Releases: eclipsesource/tabris-js
3.0.0-beta2
UI
StackLayout and StackComposite
The new StackComposite
widget arranges all of its children automatically in one vertical stack, starting from the top. Children may be aligned to the left, right, horizontal center, or stretched. The layoutData
on the children is currently ignored, but will be supported in the final 3.0 release.
Example:
contentView.append(
<StackComposite layoutData='fill' spacing={24} >
<TextView background='red'>lorem</TextView>
<TextView background='green'>ipsum dolor</TextView>
<TextView background='blue'>sit amet</TextView>
</StackComposite>
);
This behavior can be added to most widget that inherit from Composite
(e.g. Page
, ScrollView
) by setting the new layout
property to a StackLayout
instance.
Example:
contentView.append(
<ScrollView layoutData='fill' layout={new StackLayout({alignment: 'stretchX'})} >
<TextView background='red'>lorem</TextView>
<TextView background='green'>ipsum dolor</TextView>
<TextView background='blue'>sit amet</TextView>
</ScrollView>
);
LayoutData Shorthands
In practice widgets often are made to fill their parent completely, or centered on both axes. That behavior can now be achieved with less code by setting layoutData
to 'fill'
or 'center'
instead of an LayoutData
object.
Button Styling
The look-and-feel of the Button
widget can now be adjusted by setting the style
property to "default"
, "elevate"
, "flat"
, "outline"
or "text"
. The default
style will create a platform specific appearance.
Logging
Better Stack Traces
Stack traces have been improved in a number of ways:
- Clean platform-independent format
- Framework internals are filtered out
- Source map support, i.e. corrent line numbers when using TypeScript/JSX. (*)
- cross timer/promise traces - works great in combination with
async
/await
(*) Requires the tabris-cli
version matching this release, install with npm i [email protected] -g
.
The improved stack traces are printed when calling console.trace()
or error.toString()
.
Better warnings
Warnings printed by the framework do now generally include the source objects type and id, and also the file/line number in the application that caused the warning. The phrasing of many warnings has also been revised to be clearer and contain more relevant information.
Improved console.dirxml()
The dirxml
method was already introduced in beta 1 as a convenient way to print the applications widget tree (or parts of it), but it only displayed the widget type and id. Now it also prints essential information like widget bounds, selection status, text value, etc.
In addition, dirxml
can now also be called with localStorage
to inspects its content.
localStorage
The localStorage
now also implements key
and length
as specified in the W3C standard. This allows programmatically inspecting its content without knowing the keys associated with the contained items.
JSX and TypeScript improvements
New object literals for property types
Various properties in Tabris.js used to accept only CSS-like strings, which are short but error-prone. Since the IDE and TypeScript compiler can not know what format a string is supposed to have, no auto-complete could be provided. As a result typos would not become obvious until the code was executed.
The new object literals for font, color and gradient types have full auto-completion and TypeScript support while staying 100% compatible with the old string formats. While layoutData
was already an object literal, it now allows objects to express the constraint values, e.g. left
and top
.
Each type also has a matching JavaScript class that is used as the default format by the framework. For example:
widget.background = {red: 255, green: 0, blue: 0};
// or
widget.background = '#ff0000';
// are normalized to a `Color` instance, i.e.
console.log(widget.background instance Color); // true
console.log(widget.background.toString()); // #ff0000
console.log(widget.background.red); //255
JSX support for AlertDialog
As with ActionSheet
in beta 1, AlertDialog
can now be written as JSX. That allows for more readable code when a the dialog contains TextInput
elements:
const dialog = AlertDialog.open(
<AlertDialog title='Sign-in required' buttons={{ok: 'Sign-in', cancel: 'Cancel'}}>
Provide sign-in credentials to access your personalized content.
<TextInput message='Username' />
<TextInput type='password' message='Password' />
</AlertDialog>
);
const {texts, button} = await dialog.onClose.promise();
The new static open
method that serves as a convenient shorthand to create a very simple message dialog:
await AlertDialog.open('Comment saved').onClose.promise();
textView.text = 'Dialog closed';
Documentation
API documentation has been tweaked to improve readability and provide a short, informative overview for each class, method and property at first glance.
Breaking changes
Object 'ui' removed
The 'ui' object used to be a pseudo-widget that contained the main ContentView
, the Drawer
instance and various pseudo-widgets like StatusBar
. This proved to be confusing and sometimes inconvenient, so all objects held by ui
are now available as direct imports from the tabris
module:
Old:
import {ui, TextView} from 'tabris';
ui.contentView.append(new TextView());
New:
import {contentView, TextView} from 'tabris';
contentView.append(new TextView());
Removed 'installPatch' method
The method app.installPatch
allowed to patch a Tabris.js application on the fly without installing a complete new version. This API was always marked as experimental and is now removed again. It encouraged a risky practice (bypassing store policies) and was never widely used.
As a replacement the app.reload
method now takes an URL parameter, allowing to execute any local or remote JavaScript in place of the packaged code. This, combined with fetch
and the fs
file system API would theoretically allow implementing this feature in-app, if desired.
Property 'backgroundImage' merged in to background
The property background
was already supporting both colors and gradients, so it was an obvious move to make it accept images as well, eliminating the need for a separate backgroundImage
property.
Version 2.7.0
Validate SSL connections against custom certificates
The new property trustedCertificates
on the App
objects allows to add a set of certificates to validated SSL connections against. The certificates are applied in addition to the system wide default certificates.
The ArrayBuffer
entries of the trustedCertificates
array consist of the bytes of the certificate files. On Android the certificate file has to be a *.pem (Privacy Enhanced Mail) file whereas on iOS it has to be *.der (Distinguished Encoding Rules) file.
Version 1.11.0
This is intended to be the final 1.x Tabris.js release.
Development continues on master for the upcoming 3.x release.
Maintenance continues for 2.x.
iOS platform update
The iOS platform corresponding to this release was updated to allow build artifacts to be published to Apple's app store. Apps built using Tabris.js versions before 1.11.0
are not accepted by Apple anymore.
Otherwise this release does not contain any significant changes compared to v1.10.0.
Version 2.6.2
This release addresses bug fixes in the client platforms.
Android
Fix TextView linkTap bug
With the added support for linkTap
the TextView
would consume touch events when markupEnabled
would be set to true.
Send error on invalid url in XHR requests
Using an url like ":8080" would crash the app.
iOS
Fix intrinsic size of the multiline checkbox
Widget was not growing properly when text in the label was wrapped to more than one line.
Fix possible crash in getImageData
It was possible to perform read operation out of bounds of the array.
Fix Switch being unable to disable
enabled
property on delegating switch was not set when setting enabled
on JS side.
3.0.0-beta1
Workers
You can now run code in parallel. Not only can that give you a performance boost for CPU intensive tasks, it prevents the UI from becoming unresponsive. The Worker API follows the w3c worker API so it should be very familiar.
const worker = new Worker('worker-add-numbers.js');
worker.onmessage = (event) => {
console.log(`result: ${event.data}`);
worker.terminate();
};
worker.onerror = (error) => {
console.log(`onerror: ${JSON.stringify(error)}`);
worker.terminate();
};
worker.postMessage([number1, number2]);
New Event API
For Tabris 3.0 we ported the enhanced event API introduced in the tabris-decorators project to the core module. It does not replace the old API, but offers a more convenient, higher level interface especially useful for TypeScript projects and asynchronous programming via async/await.
(async function() {
textView.onTextChanged(handleTextChanged);
textView.text = 'Tap here!';
await textView.onTap.resolve();
textView.text = 'Thank you!';
}());
JSX and TypeScript improvements
For Beta 1 we revised many internals to help with future JSX and TypeScript enhancements. A number of APIs have been tweaked for convenience and consistency. Most notably, JSX elements now always need to be imported.
Also, ActionSheet popups can now be created via JSX:
ActionSheet.open(
<ActionSheet title='Actions' onSelect={onSelect} onClose={onClose}>
Select any of the actions below to proceed.
<ActionSheetItem title='Search' image='resources/[email protected]' />
<ActionSheetItem title='Share' image='resources/[email protected]' />
<ActionSheetItem title='Settings' image='resources/[email protected]' />
<ActionSheetItem title='Delete' style='destructive' image='resources/[email protected]' />
<ActionSheetItem title='Cancel' style='cancel' image='resources/[email protected]' />
</ActionSheet>
);
Image scale by convention
Providing images for high density displays does not require you to give a scale factor explicitly if it can be determined by the file name:
<ActionSheetItem image={{src: 'resources/[email protected]', scale: 3}} />
Can be replaced by this:
<ActionSheetItem image='resources/[email protected]' />
New property scrollbarVisible on ScrollView
The ScrollView
received a new property to scrollbarVisible
which allows to hide the scrollbars.
2.6.1
2.6.0
Add support for "selection" on TextInput
A new selection
property allows to get and set the text cursor position and selection. The selection
is a two element number array representing the text selections start and end position. The native platform usually shows selection handles so that the selection can be changed by the user. A selection
array where both numbers are the same represent a single cursor at the given position. The selection can be observed via the selectionChanged
event as usual.
Add "tapLink" event on TextView
The new tapLink
event on TextView
fires when the user clicks on a link in an html text. It requires to set markupEnabled
to true and to provide a text containing an anchor (<a>
) with an href
attribute. Eg. textView.text = 'Website: <a href=\"http://example.com>example.com</a>'
. The event object contains a property url
which provides the anchors href
url.
Add textInputs property on AlertDialog
An AlertDialog
can now contain TextInput
widgets to gather user input. The inputs are displayed alongside the title
and message
. The text values inserted by the user can be read in the dialogs close
event from the respective TextInputs
. Eg.: dialog.on('close', (e) => e.target.textInputs[0].text)
.
2.5.1
2.5.0
New Popover dialog
A new Popover
popup has been introduced. It allows to cover the app UI in a modal fashion with a custom UI. On large screen devices the Popover
will be shown in a window style appearance while on small devices it covers the entire screen.
let popover = new Popover();
popover.contentView.append(new TextView({text: 'Hello Popover'}));
popover.open();
New navigationAction property on NavigationView
The navigationAction
can be used to replace the menu action on the NavigtationView
. This can be useful to e.g. create a custom "close" action.
Support for linear gradients
The background
property on a Widget
now supports linear gradients. The gradient syntax follows the same notation as the W3C linear-gradient
specification.
new Composite({
left: 0, right: 0, top: 0, bottom: 0,
background: 'linear-gradient(to right top, red, green 50%, aqua 150%)',
}).appendTo(tabris.ui.contentView);
Child selectors
All methods that accept selector a string can now also handle child selectors in the CSS-like syntax of 'selectorA > selectorB
. For example:
widget.apply({'.columnLayout > *': {left: 0, top: 'prev() 10', right: 0});
This will apply the given properties to all widgets who's parent has columnLayout
in its class attribute.
:host selector
The widget find
and apply
methods now also support the selector :host
, inspired by the Web Component API. It always refers to the widget instance of the method that is called. Used with the apply
method it allows a widget to refer to itself or descendants of a specific relationship to itself. Example:
widget.apply({
':host': {left: 0, top: 0, right: 0, bottom: 0},
':host > Composite': {left: 0, top: 'prev() 10', right: 0}
});
Previously this would have required either assigning specific id/class attributes to the targets or separate children
/set
calls.
New tap event on StatusBar
The StatusBar
supports a new tap
event on iOS. It can be used to e.g. trigger a "scroll-to-top" when the main content of the app consists of a scrolling container.
New name property on Device
The new name
property on Device
returns the user provided name of a device, e.g. "Joe's iPhone". The property is supported on iOS only.
Added support for printing images
The printing capabilities have been extended to print images. An images will be printed fullscreen in the center of the page. To support this new output type a property contentType
has been added to the print options. It has to be either image/<format>
or application/pdf
.
printer.print(data, {jobName: 'image.jpg', contentType: 'image/jpg'}))
.then(event => console.log('Printing finished', event))
.catch(err => console.error(err));