Releases: eclipsesource/tabris-js
2.0.0 Beta 1
New UI model
Tabris.js does not dictate the use of pages anymore. Widgets can be added directly to the main area of the app.
The object tabris.ui
, which represents the UI root, now has a number of children, that represent different parts of the app's user interface:
tabris.ui.statusBar
- shows the time and some system status iconstabris.ui.navigationBar
- contains the Back, Home, etc. buttons on Androidtabris.ui.contentView
- contains the app's main UItabris.ui.drawer
- can be swiped in from the left
Widgets can be appended to contentView
, and optionally to the drawer
:
new tabris.Button({
left: 16, top: 16
}).appendTo(tabris.ui.contentView);
Drawer is now a singleton
There's only a single drawer widget available as tabris.ui.drawer
. The type tabris.Drawer
cannot be instantiated anymore. The drawer is disabled by default, to use it in an application, you have to enable it:
tabris.ui.drawer.enabled = true;
New NavigationView, changes to Page
The new widget NavigationView
offers page-based navigation. By creating multiple instances of this widget, it is now possible to have multiple page stacks in an app, for example in different tabs.
Pages are now appended to and removed from a NavigationView using the standard widget methods append()
, appendTo()
, detach()
, and dispose()
, respectively. When a page is added, it becomes the topmost page on the page stack and covers any previous page. The methods open()
and close()
on Page are obsolete and have been removed.
On back navigation, the topmost page will be disposed. When a page is removed from a NavigationView, all pages on top will be disposed automatically. To prevent pages from being automatically disposed, you can set the property autoDispose
to false
. The property topLevel
has also been removed.
The header of a NavigationView can be styled using the new properties toolbarColor
, actionColor
, titleTextColor
, and actionTextColor
.
Actions and SearchActions are now also added to instances of a NavigationView.
Remove PageSelector
The helper type PageSelector
, that showed a list of pages did not fit with the new UI model that allows for multiple page stacks. It has been removed.
Widgets
New AlertDialog
The new type AlertDialog
can be used to display modal dialogs to the user. An alert dialog can contain a message text and up to three buttons with custom texts.
ScrollView scrolling
The ScrollView
properties offsetX
and offsetY
are now read-only. To scroll programmatically, use the methods scrollToX()
and scrollToY()
. You can omit the animation by adding {animate: false}
as second parameter.
TabFolder scrolling
A new property tabMode
on TabFolder
allows to enable overflow behavior on Android. It can be set to 'fixed'
(default) or 'scrollable'
. When set to 'scrollable'
, the tabs in the tab bar will overflow and can be scrolled.
A new TabFolder event scroll
is fired when paging
is enabled and a tab is scrolled. This event can be used to implement transition effects such as parallax scrolling.
TextView selectable mode
With a new property selectable
on TextView
, you can allow copying from a TextView into the clipboard. This property is currently only support on Android.
TextInput keepFocus property
A new property keepFocus
has been introduced on TextInput
. When set to true
the TextInput
will keep its focus, even when tapped outside of the widget bounds, thereby leaving the keyboard open.
New color properties on TextInput and Picker
The new properties fillColor
and borderColor
provide more fine-grained control over the look and feel of TextInput
and Picker
widgets.
Support for data URIs in image properties
Data URIs can now be used in all widget properties that accept an image.
Properties on tabris.app
The read-only properties id
, version
, and versionCode
on tabris.app
provide information on the app id and version.
HTTP
Support for binary responses in XHR
The responseType
'arraybuffer'
is now supported by the XHR implementation in Tabris.js and supports downloading binary content.
Support for certificate pinning
A new property pinnedCertificate
on tabris.app
can be used to enable certificate pinning.
The property accepts an array of pinned certificates in the form of
[
{host: <string>, hash: <string>, algorithm: <RSA2048|RSA4096|ECDSA256>},
...
]
Overall Widget API
Direct access to widget properties
You can now access all widget properties directly, without using get()
and set()
:
button.text = 'OK';
var text = button.text;
The methods get()
and set()
remain available.
Remove support for off() with zero or one argument
In Tabris 1.0, calling a widget's off()
method with zero arguments could be used to remove all listeners from a widget and off(topic)
to remove all listeners for a given event topic. As these calls could affect other modules, they were considered risky and have been removed.
New detach method to remove widgets from their parent
Tabris widgets can be created without a parent and appended to a parent later. Using appendTo()
they can be re-parented. A new method detach()
now allows to remove a widget from its current parent for later re-use.
New includes method on WidgetCollection
You can use the new method includes()
to find out whether a widget exists in a collection, e.g.
if (parent.children().includes(widget)) {
...
}
Custom widgets
The method tabris.registerWidget
that had been recommended for custom widgets has been removed. Native widgets should now extend Widget
. We recommend to use ES6 classes and transpile the code as needed.
class MyWidget extends Widget {
get foo() {}
set foo(value) {}
...
}
Android platform
Resource drawables in image objects
A new Android specific image url scheme android-drawable
allows to load bundled resource drawables, e.g. new tabris.ImageView({image: 'android-drawable://ic_icon' })
. The bundled resources have to be placed in their respective drawable folders during app build time.
Added support for splash screens
The cordova build now supports to configure a splash screen via the <splash ..>
element. To customize the theme extend one of the SplashScreen themes.
Breaking changes
- Minimum support Android version raised to API level 17 (Android 4.2)
- Base theme to extend when creating a custom theme has been renamed from
DarkActionBar
toDarkAppBar
- TabrisActivity intent extra
theme
now expects a theme resource id instead of a qualified class name
1.10.0
Support for WebSockets
The WebSockets API is now supported by Tabris.js. This allows to send messages to a server and receive event-driven responses without having to poll the server for a reply.
New InactivityTimer
A new type InactivityTimer
has been added. This timer will elapse after a given period of user inactivity.
var timer = new tabris.InactivityTimer({
delay: 2000
}).on("timeout", function() {
label.set("text", "inactive!");
});
timer.start();
Extended API for Video widget
The API of the Video
widget has been extended. You can now hide the player controls with the property controlsVisible
, start and pause a video with the methods play()
and pause()
, and set a position with seek()
.
New event on WebView for Android
When a link to a file is selected in the WebView, a download
event will now be fired. This event provides the properties url
, mimeType
, contentLength
and contentDisposition
. The event could be used to trigger a download when a link to an unsupported file type is clicked. This event is only supported on Android.
Support for images in Page header
The new Page property icon
can now be used to set an image on a page header. It is named icon
to prevent a collision with the existing property image
which is used by the PageSelector. It will be renamed in Tabris.js 2.0.
1.9.0
ImageData API
The CanvasContext object now supports the methods getImageData
, createImageData
and putImageData
.
Web messaging API on WebView
This new API allows the Tabris.js application to communicate with the HTML document loaded inside a WebView via an HTML5 compatible API. String messages can be exchanged via the postMessage
method and message
event, which are available on the WebView itself and on the window object inside the WebView.
New property "selectedImage" on Tab widget
You can now give an additional image to be displayed if the tab is currently selected.
New property "focused" on TextInput
This property can be used to bring up the virtual keyboard by setting it to true
. The user can then immediately start typing.
New events on Drawer
The Drawer widget now has the events open
and close
, which are fired after the opening/closing animation of the drawer completes.
Animation with promises
The widget method "animate" now returns a promise that is resolved when the animation completes, and rejected when the animation is aborted.
New lifecycle events
In addition to pause
and resume
there are now three new events on the tabris.app
object to react to changes in the app running state: foreground
, background
and terminate
.
Crypto object
The W3C conform global object crypto
has been added. It can be used to generate cryptographically secure random numbers.
Full access to http headers via XMLHttpRequest
In a strictly W3C/browser conform implementation of XMLHttpRequest it is not allowed to access certain headers. Tabris.js no longer implements these restrictions. All headers can now be set and read, including previously "forbidden" headers like "Cookie".
Updated permission handling on Android
Cordova plugins can now receive permission request callbacks.
The Tabris.js playground
To make it easier for everyone to play with their code, we have now made a public Playground available without signing in. Go to tabrisjs.com/playground and scan the QR code with your device using the Tabris.js Developer App. You will see your code in action right away.
1.8.0
Grid mode for CollectionView
It is now possible to align a given number of CollectionView
cells in a single row, resulting in a grid layout as is common in image galleries or file explorers. The number of columns is controlled via the columnCount
property, with the default 1
representing the traditional list layout.
Customize TextView line spacing
Control the amount of space between each line of a multi-line TextView
using the property lineSpacing
. The value 1.0
represents the font's default, 2.0
doubles the spacing, and so on.
Tint Images in a solid color
Using the new tintColor
property you can tint all opaque pixels of an image with the given color. This is useful to represent different states, or just to better align the UI with the platform look & feel.
Get event when images are done loading
Since it may take some time to download an image from a remote location, a load
event has been introduced. It fires once the image is visible on screen, or if the image could not be found. Example:
new tabris.ImageView({
image: "http://mycloudstorage/foo.png"
}).on("load", function(imageView, event) {
hidePlaceholder();
if (event.error) {
showFileNotFound();
}
});
Improved TypeScript support
Type definitions are now bundled with Tabris.js and can be used without any additional installation. The property and event APIs now provide full auto completion and type information support.
To access type definitions for the promise
and fetch
APIs provided by Tabris.js, their respective type definitions files have to be explicitly referenced in the tsconfig.json
file:
"files": [
"./node_modules/tabris/promise.d.ts",
"./node_modules/tabris/whatwg-fetch.d.ts",
...
]
Yeoman generator update
You can now use Yeoman to create more advanced Tabris.js projects, for example with EcmaScript 6 or TypeScript transpilers already set up.
Simply type:
npm install -g yo generator-tabris-js
yo tabris-js
1.7.0
Widget constructors
Widgets can now be created using their constructors. Instead of tabris.create("Button", { text: "Submit" })
, you can now write:
new tabris.Button({ text: "Submit" });
This syntax is shorter and more common. While tabris.create()
will remain available in all 1.x releases, we encourage you to use constructors from now on. We've also adjusted all our snippets and examples to the new syntax.
Access all siblings of a widget
In addition to the parent()
children()
methods, widgets now also provide a method siblings()
. This method will return a WidgetCollection
of all widgets that have the same parent, excluding the target widget itself. The method can also be called with a selector expression, which makes it easy to select all siblings of a certain type:
checkbox.on("select", function() {
checkbox.siblings("CheckBox").set("selection", false);
});
Rounded corners on widgets
The new property cornerRadius
allows you to apply a rounded clipping to the corners of a widget. See the snippet on GitHub.
This property is supported on iOS and Android 5.0+.
System bar theme
The theme used for the system status bar can now be controlled using a new property systemBarTheme
. Possible values are "light"
, "dark"
, and "default"
(which selects the platform default). This property will control the foreground text and icons on the status bar. Note that the light theme will result in a dark foreground and vice-versa. See the snippet on GitHub.
This property is supported on iOS and Android 6+.
Fetch API included
As a simpler and more flexible alternative to XmlHttpRequest
, the Fetch API is now available in Tabris.js. The npm module whatwg-fetch
is no longer required.
Promise included
Tabris.js now includes a full Promise
implementation on all platforms. There is no need to include a promise shim anymore.
1.6.0
New widget ActivityIndicator
To indicate a pending operation of indeterminate time, you can now use the widget ActivityIndicator
that displays a spinning indicator on both platforms. Have a look at the snippet.
New property displayMode to enable fullscreen
The new property displayMode
on tabris.ui
can be set to "fullscreen"
to enable fullscreen mode, i.e. to hide the system bar. The default display mode is called "normal"
.
New properties scrollX and scrollY on ScrollView
The new properties scrollX
and scrollY
can be used to get and to set the current scroll position of a ScrollView
.
backnavigation: preventDefault is now a function
In order to prevent the default effect of the back-button on Android, you can now call event.preventDefault()
as a function in your backnavigation
listener. Before you had to set a field of this name to false
. This method is still supported, but discouraged.
1.5.0
Allow for TabFolders without a tab bar
The TabFolder property tabBarLocation
now accepts the value "hidden"
. Together with paging: true
, this enables a swipe-widget like experience. There's a new snippet for this use case.
Note that the property tabBarLocation
is static, i.e. it can only be set at creation time.
Support for Tab images on Android
The image
property on Tab
is now also available on Android. You can use it with or without the text
property.
Support for elevation and z-translation on Android 5+
As of Android 5.0, widgets can have an elevation that defines their relative position on the z-axis. The elevation is visually represented by a shadow effect. Transformations now support the additional property translationZ
. While elevation
represents the base state of a widget, the translationZ
property should be altered for animations. Have a look at the new snippets for elevation and translationZ.
Both elevation
and translationZ
are only respected by Android 5.0+.
SearchAction open method
SearchActions can now be invoked programmatically using the new method open()
.
1.4.0
Support for any data type in the Picker items array
Where the Picker previously only accepted an array of strings it can now deal with any kind of item. This is especially convenient when handling an item in the select
and change:selection
events.
By default the Picker calls toString()
on the item to convert it to string, but you can also provide a custom function to do this in the new itemText
property:
tabris.create("Picker", {
items: airports,
itemText: function(airport) {
return airport.name;
}
});
Scroll event for CollectionView
Just like in ScrollView, CollectionView now has a scroll
event that lets you know when the user has scrolled. The callback contains information about the scrolling direction and distance.
New "firstVisibleIndex" and "lastVisibleIndex" properties in CollectionView
To determine which items are currently visible on screen the firstVisibleIndex
and lastVisibleIndex
properties have been added to CollectionView. These also come with matching change events, which are very well suited to implement an "endless scrolling list". Simply listen to "change:lastVisibleIndex" and start loading more items once the value exceeds a limit of your choosing.
1.3.0
iOS 9 support
The iOS client now works on iOS 9.
TypeScript support
We provide type definitions to assist you developing Tabris.js apps in TypeScript. See this blog post for details.
Insert widgets before/after others
In addition to appendTo()
, you can now use the new methods insertBefore()
and insertAfter()
to insert widgets at a given position. This is particularly useful in conjunction with the "prev()"
keyword in layout data.
Support additional colors in Switch
Switch buttons now offer fine-grained control over colors using the following new properties:
thumbOnColor
thumbOffColor
trackOnColor
trackOffColor
Access to bundled resources
A new method getResourceLocation()
on tabris.app
provides absolute locations for resources that are bundled with the app, such as images, videos, etc.
1.2.0
Layout: symbolic reference "prev()"
In all layout attributes that support referencing other widgets, "prev()"
can now be given (as a string) to refer to the preceding sibling. This is superior to parent.children().last()
or a direct reference for several reasons:
- It's less code.
- It requires no access to the parent.
- The reference is dynamically resolved - meaning if the preceding sibling is removed or replaced the layout is adjusted automatically.
Layout: Alternative notation for top/left/right/bottom
- Instead of
["20%", 10]
it's now also possible to write"20% 10"
. - Instead of
["#foo", 10]
or["prev()", 10]
, it's now also possible to write"#foo 10"
or"prev() 10"
.
Layout: Setting layoutData attributes as widget properties
All attributes of layoutData
are now also properties of Widget. So if you want to change only a single attribute of layoutData
without affecting the other, simply set the widget property:
widget.set("layoutData", {width: 100, height: 10});
//...
widget.set("left", 100); // width and height do not change
If you wish to set an entirely new layout, use layoutData
:
widget.set("layoutData", {width: 100, height: 10});
//...
widget.set("layoutData": {left: 100}); // width and height are reset
Android back button support
The back button in Android is usually used in Tabris.js to close the current page. However, with the new backnavigation
event on the app
object this behavior can now be overwritten:
tabris.app.on("backnavigation", function(app, options) {
options.preventDefault = true;
// do something else than closing the page
});
Hide navigation UI elements
To create a "fullscreen" app, simply call tabris.ui.set("toolbarVisible", false);
Note that there is currently a minor issue when using the feature on iOS, see #597.
Provisional Custom Widget API
We have been working on defining a public API that will allow application developer to create their own Tabris.js widgets using JavaScript and Java/Objective-C. The API is neither complete nor final, but already allows creating simple widgets like a Map or Date input.
View all relevant GitHub issues closed in this release here