diff --git a/tabris/README.md b/tabris/README.md
new file mode 100644
index 0000000000..23d3d1a496
--- /dev/null
+++ b/tabris/README.md
@@ -0,0 +1,8 @@
+# TypeScript definitions for Tabris.js
+
+[Tabris.js](http://tabrisjs.com) is a framework for developing mobile apps with native UIs in JavaScript.
+The JavaScript library is available on [npm](https://www.npmjs.com/package/tabris).
+
+Current supported version is 1.2.
+
+See http://definitelytyped.org/guides/contributing.html
diff --git a/tabris/tabris-tests.ts b/tabris/tabris-tests.ts
new file mode 100644
index 0000000000..28ab53cecd
--- /dev/null
+++ b/tabris/tabris-tests.ts
@@ -0,0 +1,302 @@
+///
+
+var page = tabris.create("Page", {});
+
+function test_events() {
+ var listener = () => console.log("triggered");
+ var widget = tabris.create("Composite", {});
+ widget.on("foo", listener);
+ widget.trigger("foo", "details");
+ widget.off("foo", listener);
+ widget.off("foo");
+ widget.off(null, listener);
+ widget.off();
+}
+
+function test_Action() {
+ var widget: tabris.Action = tabris.create("Action", {});
+ widget.set("foo", 23);
+ widget.set({
+ image: {src: "http://example.org"},
+ title: "foo",
+ placementPriority: "high"
+ });
+ var self: tabris.Action = widget.on("event", function(widget: tabris.Action) {});
+}
+
+function test_Button() {
+ var widget: tabris.Button = tabris.create("Button", {});
+ widget.set("foo", 23);
+ widget.set({
+ width: 200,
+ height: 400,
+ alignment: "center",
+ image: {src: "http://example.org"},
+ text: "foo"
+ });
+}
+
+function test_CheckBox() {
+ var widget: tabris.CheckBox = tabris.create("CheckBox", {});
+ widget.set("foo", 23);
+ widget.set({
+ selection: true,
+ text: "foo"
+ });
+}
+
+function test_Canvas() {
+ var widget: tabris.Canvas = tabris.create("Canvas", {});
+ widget.set("foo", 23);
+ widget.set({
+ });
+ var ctx: tabris.CanvasContext = widget.getContext("2d", 200, 300);
+}
+
+function test_Cell() {
+ var widget: tabris.Cell = tabris.create("Cell", {});
+ widget.set("foo", 23);
+ widget.set({
+ });
+}
+
+function test_CollectionView() {
+ var widget: tabris.CollectionView = tabris.create("CollectionView", {});
+ widget.set("foo", 23);
+ widget.set({
+ cellType: (item: any) => "foo",
+ initializeCell: (cell: tabris.Cell, type: string) => {},
+ itemHeight: (item: any, type: string) => 23,
+ items: ["foo", "bar", "baz"],
+ refreshEnabled: true,
+ refreshIndicator: true,
+ refreshMessage: "foo"
+ });
+ widget.insert(["item1", "item2"]);
+ widget.insert(["item1", "item2"], 3);
+ widget.refresh();
+ widget.refresh(3);
+ widget.remove(3);
+ widget.remove(3, 2);
+ widget.reveal(23);
+}
+
+function test_Composite() {
+ var widget: tabris.Composite = tabris.create("Composite", {});
+ widget.set("foo", 23);
+ widget.set({
+ });
+}
+
+function test_Drawer() {
+ var widget: tabris.Drawer = tabris.create("Drawer", {});
+ widget.set("foo", 23);
+ widget.set({
+ });
+ var same: tabris.Drawer = widget.open();
+ var same: tabris.Drawer = widget.close();
+}
+
+function test_ImageView() {
+ var widget: tabris.ImageView = tabris.create("ImageView", {});
+ widget.set("foo", 23);
+ widget.set({
+ image: {src: "http://example.com"},
+ scaleMode: "auto"
+ });
+}
+
+function test_Page() {
+ var page: tabris.Page = tabris.create("Page", {});
+ page.set("foo", 23);
+ page.set({
+ image: {src: "http://example.com"},
+ title: "foo",
+ topLevel: true
+ });
+ page.open().close();
+}
+
+function test_PageSelector() {
+ var widget: tabris.PageSelector = tabris.create("PageSelector", {});
+ widget.set("foo", 23);
+ widget.set({
+ });
+}
+
+function test_Picker() {
+ var widget: tabris.Picker = tabris.create("Picker", {});
+ widget.set("foo", 23);
+ widget.set({
+ selection: "foo",
+ selectionIndex: 23,
+ items: ["foo", "bar", "baz"]
+ });
+}
+
+function test_ProgressBar() {
+ var widget: tabris.ProgressBar = tabris.create("ProgressBar", {});
+ widget.set("foo", 23);
+ widget.set({
+ minimum: 0,
+ maximum: 100,
+ selection: 23,
+ state: "normal"
+ });
+}
+
+function test_RadioButton() {
+ var widget: tabris.RadioButton = tabris.create("RadioButton", {});
+ widget.set("foo", 23);
+ widget.set({
+ selection: true,
+ text: "foo"
+ });
+}
+
+function test_ScrollView() {
+ var widget: tabris.ScrollView = tabris.create("ScrollView", {});
+ widget.set("foo", 23);
+ widget.set({
+ direction: "horizontal"
+ });
+}
+
+function test_SearchAction() {
+ var widget: tabris.SearchAction = tabris.create("SearchAction", {});
+ widget.set("foo", 23);
+ widget.set({
+ message: "foo",
+ proposals: ["foo", "bar", "baz"],
+ text: "foo"
+ });
+}
+
+function test_Slider() {
+ var widget: tabris.Slider = tabris.create("Slider", {});
+ widget.set("foo", 23);
+ widget.set({
+ minimum: 0,
+ maximum: 100,
+ selection: 23
+ });
+}
+
+function test_Switch() {
+ var widget: tabris.Switch = tabris.create("Switch", {});
+ widget.set("foo", 23);
+ widget.set({
+ selection: true
+ });
+}
+
+function test_TextInput() {
+ var widget: tabris.TextInput = tabris.create("TextInput", {});
+ widget.set("foo", 23);
+ widget.set({
+ alignment: "center",
+ autoCapitalize: true,
+ autoCorrect: false,
+ editable: true,
+ text: "foo",
+ message: "bar",
+ type: "search",
+ keyboard: "ascii"
+ });
+}
+
+function test_Tab() {
+ var widget: tabris.Tab = tabris.create("Tab", {});
+ widget.set("foo", 23);
+ widget.set({
+ badge: "foo",
+ title: "bar",
+ image: {src: "http://example.org"}
+ });
+}
+
+function test_TabFolder() {
+ var widget: tabris.TabFolder = tabris.create("TabFolder", {});
+ widget.set("foo", 23);
+ widget.set({
+ paging: true,
+ tabBarLocation: "auto",
+ selection: tab1
+ });
+ var tab1: tabris.Tab, tab2: tabris.Tab;
+ var same: tabris.TabFolder = widget.append(tab1, tab2);
+}
+
+function test_TextView() {
+ var widget: tabris.TextView = tabris.create("TextView", {});
+ widget.set("foo", 23);
+ widget.set({
+ alignment: "center",
+ markupEnabled: true,
+ maxLines: 23,
+ text: "foo"
+ });
+}
+
+function test_ToggleButton() {
+ var widget: tabris.ToggleButton = tabris.create("ToggleButton", {});
+ widget.set("foo", 23);
+ widget.set({
+ alignment: "center",
+ image: {src: "http://example.org/"},
+ selection: true,
+ text: "foo"
+ });
+}
+
+function test_Video() {
+ var widget: tabris.Video = tabris.create("Video", {});
+ widget.set("foo", 23);
+ widget.set({
+ url: "http://example.org"
+ });
+}
+
+function test_WebView() {
+ var widget: tabris.WebView = tabris.create("WebView", {});
+ widget.set("foo", 23);
+ widget.set({
+ html: "",
+ url: "http://example.org"
+ });
+}
+
+function test_WidgetCollection() {
+ var collection: tabris.WidgetCollection = page.find();
+ var length: number = collection.length;
+ var grandParents: tabris.WidgetCollection = collection.parent().parent();
+ var grandChildren: tabris.WidgetCollection = collection.children().children();
+ var found: tabris.WidgetCollection = collection.find().find(".class");
+ collection.appendTo(page);
+ collection.dispose();
+}
+
+function test_tabris_app() {
+ tabris.app.installPatch("url", (error: Error, patch: Object) => {});
+ tabris.app.reload();
+}
+
+function test_tabris_device() {
+ var lang: string = tabris.device.get("language");
+ var model: string = tabris.device.get("model");
+ var orient: string = tabris.device.get("orientation");
+ var platform: string = tabris.device.get("platform");
+ var factor: number = tabris.device.get("scaleFactor");
+ var height: number = tabris.device.get("screenHeight");
+ var width: number = tabris.device.get("screenWidth");
+ var version: string = tabris.device.get("version");
+ var same: tabris.Device = tabris.device.on("change:orientation", () => {}).off("change:orientation");
+}
+
+function test_tabris_ui() {
+ var page: tabris.Page = tabris.ui.get("activePage");
+ var bg: string = tabris.ui.get("background");
+ var tc: string = tabris.ui.get("textColor");
+ var visible: boolean = tabris.ui.get("toolbarVisible");
+ var same: tabris.UI = tabris.ui.on("change:activePage", () => {}).off("change:activePage");
+}
diff --git a/tabris/tabris.d.ts b/tabris/tabris.d.ts
new file mode 100644
index 0000000000..9a0b4defe7
--- /dev/null
+++ b/tabris/tabris.d.ts
@@ -0,0 +1,1446 @@
+// Type definitions for Tabris.js v1.2
+// Project: http://tabrisjs.com
+// Definitions by: Tabris.js team
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module tabris {
+
+ // Types
+
+ interface Bounds {
+
+ /**
+ * the horizontal offset from the parent's left edge in dip
+ */
+ left: number;
+
+ /**
+ * the vertical offset from the parent's top edge in dip
+ */
+ top: number;
+
+ /**
+ * the width of the widget in dip
+ */
+ width: number;
+
+ /**
+ * the height of the widget in dip
+ */
+ height: number;
+
+ }
+
+ interface Transformation {
+
+ /**
+ * Clock-wise rotation in radians. Defaults to `0`.
+ */
+ rotation: number;
+
+ /**
+ * Horizontal scale factor. Defaults to `1`.
+ */
+ scaleX: number;
+
+ /*
+ * Vertical scale factor. Defaults to `1`.
+ */
+ scaleY: number;
+
+ /**
+ * Horizontal translation (shift) in dip. Defaults to `0`.
+ */
+ translationX: number;
+
+ /**
+ * Vertical translation (shift) in dip. Defaults to `0`.
+ */
+ translationY: number;
+
+ }
+
+ // TODO A plain string can be used as a shorthand, e.g. `"image.jpg"` equals `{src: "image.jpg"}`.
+ interface Image {
+
+ /**
+ * Image path or URL.
+ */
+ src?: string;
+
+ /**
+ * Image width, extracted from the image file when missing.
+ */
+ width?: number;
+
+ /**
+ * Image height, extracted from the image file when missing.
+ */
+ height?: number;
+
+ /**
+ * Image scale factor - the image will be scaled down by this factor.
+ * Ignored when width or height are set.
+ */
+ scale?: number;
+
+ }
+
+ interface CanvasContext {
+ // TODO
+ }
+
+ // Events
+
+ /**
+ * Event handling API supported by widgets and various other objects.
+ */
+ interface EventSupport {
+
+ /**
+ * Adds the *listener* to the list of functions to be notified when *event* is fired.
+ * In the listener function, `this` will point to the object itself. Supports chaining.
+ *
+ * @param event the name of the event to listen on
+ * @param listener the listener function
+ */
+ on (event: string, listener: (target: T, ...args: any[]) => any): T;
+
+ /**
+ * Same as `on`, but removes the listener after it has been invoked by an event.
+ * Supports chaining.
+ *
+ * @param event the name of the event to listen on
+ * @param listener the listener function
+ */
+ once (event: string, listener: (target: T, ...args: any[]) => any): T;
+
+ /**
+ * Removes all listeners for all events from this widget. Supports chaining.
+ */
+ off (): T;
+
+ /**
+ * Removes all listeners for *event* from this widget. Supports chaining.
+ *
+ * @param event the event name to remove listeners for
+ */
+ off (event: string): T;
+
+ /**
+ * Removes all occurrences of *listener* that are bound to *event* from this widget.
+ * Supports chaining.
+ *
+ * @param event the event to remove the listener from
+ * @param listener the listener function to remove
+ */
+ off (event: string, listener: (target: T, ...args: any[]) => any): T;
+
+ /**
+ * Triggers an event on this object. Supports chaining.
+ *
+ * @param event the name of the event to trigger
+ * @param args the arguments to pass to the listener functions
+ */
+ trigger (event: string, ...args: any[]): T;
+
+ }
+
+ interface AnimationOptions {
+
+ /**
+ * The time until the animation starts in ms, defaults to `0`.
+ */
+ delay?: number;
+
+ /**
+ * The duration in ms.
+ */
+ duration: number;
+
+ /**
+ * One of `linear`, `ease-in`, `ease-out`, `ease-in-out`.
+ */
+ easing: string;
+
+ /**
+ * The number of times to repeat the animation, defaults to `0`.
+ */
+ repeat: number;
+
+ /**
+ * `true` to alternate the direction of the animation on every repeat.
+ */
+ reverse: boolean;
+
+ /**
+ * No effect, but will be given in animation events.
+ */
+ name: string;
+
+ }
+
+ // Widget
+
+ function create (type: string, properties: WidgetProperties): Widget;
+
+ /**
+ * API supported by all widgets.
+ */
+ interface Widget extends EventSupport {
+
+ // Property Support
+
+ /**
+ * Gets the current value of the given *property*.
+ *
+ * @param property
+ */
+ get (property: string): any;
+
+ /**
+ * Sets the given property. Supports chaining.
+ *
+ * @param property the name of the property to set
+ * @param value the value to set the property to
+ * @param options passed to the change event resulting from this method call
+ */
+ set (property: string, value: any, options?: Object): T;
+
+ /**
+ * Sets all key-value pairs in the properties object as widget properties. Supports chaining.
+ *
+ * @param properties the properties to set
+ * @param options passed to the change event resulting from this method call
+ */
+ set (properties: WidgetProperties, options?: Object): T;
+
+ /**
+ * Starts an animation that transforms the given properties from their current values to the given ones.
+ * Supported properties are *transform* and *opacity*.
+ *
+ * @param properties The properties and target values to animate.
+ * @param options Configures the animation itself.
+ */
+ animate (properties: WidgetProperties, options: AnimationOptions): void;
+
+ /**
+ * Appends this widget to the given parent.
+ * The parent widget must support children (extending *Composite*).
+ *
+ * @param parent the parent widget to append this one to
+ */
+ appendTo (parent: Composite): T;
+
+ /**
+ * Applies the given properties to all descendants that match the associated selector(s).
+ *
+ * @param properties an object in the format
+ * `{selector: {property: value, property: value, ... }, selector: ...}`
+ */
+ apply (properties: Object): T;
+
+ /**
+ * Returns a (possibly empty) collection of all children of this widget.
+ */
+ children (): WidgetCollection;
+
+ /**
+ * Returns a (possibly empty) collection of all children of this widget that match the selector.
+ *
+ * @param selector a selector string to filter children
+ */
+ children (selector: string): WidgetCollection;
+
+ /**
+ * Removes this widget from its parent and destroys it. Also disposes of all its children.
+ * Triggers a `remove` event on the parent and a `dispose` event on itself.
+ * The widget can no longer be used.
+ */
+ dispose (): void;
+
+ /**
+ * Returns a (possibly empty) collection of all descendants of this widget.
+ */
+ find (): WidgetCollection
+
+ /**
+ * Returns a (possibly empty) collection of all descendants of this widget that match the selector.
+ * @param selector
+ */
+ find (selector: string): WidgetCollection
+
+ /**
+ * Returns `true` if the widget has been disposed, otherwise `false`.
+ */
+ isDisposed (): boolean
+
+ /**
+ * Returns the parent of this widget.
+ */
+ parent (): T;
+
+ /**
+ * An application-wide unique identifier automatically assigned to all widgets on creation.
+ * Do not change it.
+ */
+ cid: string;
+
+ /**
+ * Direct access to the value of the property of the same name.
+ * May be used instead of `widget.get("id");`.
+ * Do not use this field to change the value, instead use `widget.set("id", id);`.
+ */
+ id: string;
+
+ /**
+ * The exact string that was used to create this widget using the `tabris.create` method.
+ */
+ type: string;
+
+ }
+
+ interface WidgetProperties {
+
+ /**
+ * The background color of the widget.
+ */
+ background?: string;
+
+ /**
+ * An image to be displayed on the widget's background.
+ * If the image is smaller than the widget, it will be tiled.
+ */
+ backgroundImage?: Image;
+
+ /**
+ * The vertical position of the widget's baseline relative to a sibling widget.
+ */
+ baseline?: any;
+
+ /**
+ * The position of the widget's bottom edge relative to the parent or a sibling widget.
+ */
+ bottom?: any;
+
+ /**
+ * The actual location and size of the widget, relative to its parent. This property is read-only.
+ */
+ bounds?: Bounds;
+
+ /**
+ * The horizontal position of the widget's center relative to the parent's center.
+ */
+ centerX?: number;
+
+ /**
+ * The vertical position of the widget's center relative to the parent's center.
+ */
+ centerY?: number;
+
+ /**
+ * Whether the widget can be operated.
+ */
+ enabled?: boolean;
+
+ /**
+ * The font used for the widget.
+ */
+ font?: string;
+
+ /**
+ * The height of the widget.
+ */
+ height?: number;
+
+ /**
+ * Whether the entire widget should be highlighted while touched.
+ */
+ highlightOnTouch?: boolean;
+
+ /**
+ * A string to identify the widget by using selectors. Id's are optional.
+ * It is strongly recommended that they are unique within a page.
+ */
+ id?: string;
+
+ /**
+ * Shorthand for all layout properties. See [Layout](../layout.md).
+ */
+ layoutData?: Object;
+
+ /**
+ * The position of the widget's left edge relative to the parent or a sibling widget.
+ */
+ left?: any;
+
+ /**
+ * Opacity of the entire widget. Can be used for fade animations.
+ */
+ opacity?: number;
+
+ /**
+ * The position of the widget's right edge relative to the parent or a sibling widget.
+ */
+ right?: any;
+
+ /**
+ * Text color of the widget.
+ */
+ textColor?: string;
+
+ /**
+ * The position of the widget's top edge relative to the parent or a sibling widget.
+ */
+ top?: any;
+
+ /**
+ * Modifications to the widget's shape, size, or position. Can be used for animations.
+ * **Note:** In Android, the *transform* property does not affect the *bounds* property,
+ * while it does so in iOS.
+ */
+ transform?: Transformation;
+
+ /**
+ * Whether the widget is visible.
+ */
+ visible?: boolean;
+
+ /**
+ * The width of the widget.
+ */
+ width?: number;
+
+ }
+
+ // Action
+
+ function create (type: "Action", properties: ActionProperties): Action;
+
+ /**
+ * An executable item that is integrated in the application's navigation menu.
+ * Add a listener on *select* to implement the action.
+ */
+ interface Action extends Widget {
+
+ set (property: string, value: any, options?: Object): Action;
+ set (properties: ActionProperties, options?: Object): Action;
+
+ }
+
+ interface ActionProperties extends WidgetProperties {
+
+ /**
+ * Icon image for the action.
+ */
+ image?: Image;
+
+ /**
+ * Actions with higher placement priority will be placed at a more significant position in the UI,
+ * e.g. low priority actions could go into a menu instead of being included in a toolbar.
+ * Any of `low`, `high`, `normal`.
+ */
+ placementPriority?: string;
+
+ /**
+ * The text to be displayed for the action.
+ */
+ title?: string;
+
+ }
+
+ // Button
+
+ function create (type: "Button", properties: ButtonProperties): Button;
+
+ /**
+ * A push button. Can contain a text or an image.
+ */
+ interface Button extends Widget