diff --git a/apps/tests/app/mainPage.ts b/apps/tests/app/mainPage.ts index eb88d4e0f..7de1b21ba 100644 --- a/apps/tests/app/mainPage.ts +++ b/apps/tests/app/mainPage.ts @@ -12,7 +12,8 @@ page.id = "mainPage"; page.on(Page.navigatedToEvent, onNavigatedTo); function onNavigatedTo(args) { - let label = new Label({ text: "Running non-UI tests..." }); + let label = new Label(); + label.text = "Running non-UI tests..."; page.content = label args.object.off(Page.navigatedToEvent, onNavigatedTo); setTimeout(function () { diff --git a/apps/tests/app/pageNavigation.ts b/apps/tests/app/pageNavigation.ts index 203ae75ce..33d42c5d8 100644 --- a/apps/tests/app/pageNavigation.ts +++ b/apps/tests/app/pageNavigation.ts @@ -15,10 +15,10 @@ export function createPage() { topFrame.goBack(); }); - tab.items.push(new tabViewModule.TabViewItem({ - title: "Tab " + i, - view: button - })); + let item = new tabViewModule.TabViewItem(); + item.title = "Tab " + i; + item.view = button; + tab.items.push(item); } var page = new pages.Page(); page.content = tab; diff --git a/apps/tests/ui/animation/animation-tests.ts b/apps/tests/ui/animation/animation-tests.ts index 70122154c..6dcdb2c07 100644 --- a/apps/tests/ui/animation/animation-tests.ts +++ b/apps/tests/ui/animation/animation-tests.ts @@ -12,7 +12,9 @@ import animation = require("ui/animation"); function prepareTest(): Label { let mainPage = helper.getCurrentPage(); - let label = new Label({ text: "label" }); + let label = new Label(); + label.text = "label"; + let stackLayout = new StackLayout(); stackLayout.addChild(label); mainPage.content = stackLayout; @@ -170,9 +172,12 @@ export function test_ReusingAnimations(done) { export function test_AnimatingMultipleViews(done) { let mainPage = helper.getCurrentPage(); - let label1 = new Label({ text: "label1" }); - let label2 = new Label({ text: "label2" }); - let label3 = new Label({ text: "label3" }); + let label1 = new Label(); + label1.text = "label1"; + let label2 = new Label(); + label2.text = "label2"; + let label3 = new Label(); + label3.text = "label3"; let stackLayout = new StackLayout(); stackLayout.addChild(label1); stackLayout.addChild(label2); diff --git a/apps/tests/ui/animation/css-animation-tests.ts b/apps/tests/ui/animation/css-animation-tests.ts index a7f5fd175..a73cb68e0 100644 --- a/apps/tests/ui/animation/css-animation-tests.ts +++ b/apps/tests/ui/animation/css-animation-tests.ts @@ -247,7 +247,8 @@ export function test_LoadAnimationProgrammatically() { export function test_ExecuteCSSAnimation() { let mainPage = helper.getCurrentPage(); mainPage.css = null; - let label = new labelModule.Label({ text: "label" }); + let label = new labelModule.Label() + label.text = "label"; let stackLayout = new stackModule.StackLayout(); stackLayout.addChild(label); diff --git a/apps/tests/ui/bindable-tests.ts b/apps/tests/ui/bindable-tests.ts index 008666891..914c22bd6 100644 --- a/apps/tests/ui/bindable-tests.ts +++ b/apps/tests/ui/bindable-tests.ts @@ -179,7 +179,7 @@ export var test_bindingContext_Change_IsReflected_Properly = function () { views[0].bindingContext = undefined; model.set("testProperty", "updatedValue"); - TKUnit.assert(button.text === "testValue", "Binding not properly detached when bindingContext is cleared."); + TKUnit.assertEqual(button.text, "", "Binding not properly detached when bindingContext is cleared."); } helper.do_PageTest_WithButton(test); diff --git a/apps/tests/ui/scroll-view/scroll-view-tests.ts b/apps/tests/ui/scroll-view/scroll-view-tests.ts index 75cc3fa90..d8cea51d3 100644 --- a/apps/tests/ui/scroll-view/scroll-view-tests.ts +++ b/apps/tests/ui/scroll-view/scroll-view-tests.ts @@ -33,7 +33,7 @@ class ScrollLayoutTest extends testModule.UITest { // >> article-creating-scrollview var scrollView = new scrollViewModule.ScrollView(); // << article-creating-scrollview - console.dump(scrollView); + TKUnit.assertTrue(scrollView !== null, "ScrollView should be created."); } public test_default_TNS_values() { diff --git a/apps/tests/ui/segmented-bar/segmented-bar-tests.ts b/apps/tests/ui/segmented-bar/segmented-bar-tests.ts index 0dab24831..72997ba28 100644 --- a/apps/tests/ui/segmented-bar/segmented-bar-tests.ts +++ b/apps/tests/ui/segmented-bar/segmented-bar-tests.ts @@ -21,7 +21,9 @@ function _createSegmentedBar(): segmentedBarModule.SegmentedBar { function _createItems(count: number): Array { var items = new Array(); for (var i = 0; i < count; i++) { - items.push(new segmentedBarModule.SegmentedBarItem({ title: i + "" })); + let bar = new segmentedBarModule.SegmentedBarItem(); + bar.title = i + ""; + items.push(bar); } return items; } diff --git a/apps/tests/ui/style/style-tests.ts b/apps/tests/ui/style/style-tests.ts index 26c5e5476..1a0d7b585 100644 --- a/apps/tests/ui/style/style-tests.ts +++ b/apps/tests/ui/style/style-tests.ts @@ -103,7 +103,10 @@ export function test_css_is_applied_inside_TabView() { var testButton = new buttonModule.Button(); testButton.text = "Test"; var tabView = new tabViewModule.TabView(); - tabView.items = [new tabViewModule.TabViewItem({ title: "First tab", view: testButton })]; + let item = new tabViewModule.TabViewItem(); + item.title = "First tab"; + item.view = testButton; + tabView.items = [item]; helper.buildUIAndRunTest(tabView, function (views: Array) { var page = views[1]; diff --git a/apps/tests/ui/tab-view/tab-view-navigation-tests.ts b/apps/tests/ui/tab-view/tab-view-navigation-tests.ts index 28b6ad7ab..526e4eeef 100644 --- a/apps/tests/ui/tab-view/tab-view-navigation-tests.ts +++ b/apps/tests/ui/tab-view/tab-view-navigation-tests.ts @@ -21,10 +21,9 @@ function _createItems(count: number): Array { for (var i = 0; i < count; i++) { var label = new Label(); label.text = "Tab " + i; - var tabEntry = new TabViewItem({ - title: "Tab " + i, - view: label - }); + var tabEntry = new TabViewItem(); + tabEntry.title = "Tab " + i; + tabEntry.view = label; tabEntry["index"] = i; items.push(tabEntry); } diff --git a/apps/tests/ui/tab-view/tab-view-tests.ts b/apps/tests/ui/tab-view/tab-view-tests.ts index a8dcdb48a..ed87f529d 100644 --- a/apps/tests/ui/tab-view/tab-view-tests.ts +++ b/apps/tests/ui/tab-view/tab-view-tests.ts @@ -25,10 +25,9 @@ export class TabViewTest extends testModule.UITest { for (var i = 0; i < count; i++) { var label = new labelModule.Label(); label.text = "Tab " + i; - var tabEntry = new tabViewModule.TabViewItem({ - title: "Tab " + i, - view: label - }); + var tabEntry = new tabViewModule.TabViewItem(); + tabEntry.title = "Tab " + i; + tabEntry.view = label; items.push(tabEntry); } return items; @@ -48,7 +47,7 @@ export class TabViewTest extends testModule.UITest { let expectedValue = this.testView.items.length; let actualValue = tabViewTestsNative.getNativeTabCount(this.testView); - + TKUnit.assertEqual(actualValue, expectedValue, "NativeItems not equal to JS items."); } @@ -181,7 +180,11 @@ export class TabViewTest extends testModule.UITest { this.waitUntilTestElementIsLoaded(); TKUnit.assertThrows(function () { - tabView.items = [new tabViewModule.TabViewItem({ title: "Tab 0", view: undefined })]; + let item = new tabViewModule.TabViewItem(); + item.title = "Tab 0"; + item.view = undefined; + tabView.items = [item]; + }, "Binding TabView to a TabViewItem with undefined view should throw."); } @@ -190,7 +193,11 @@ export class TabViewTest extends testModule.UITest { this.waitUntilTestElementIsLoaded(); TKUnit.assertThrows(function () { - tabView.items = [new tabViewModule.TabViewItem({ title: "Tab 0", view: null })]; + let item = new tabViewModule.TabViewItem(); + item.title = "Tab 0"; + item.view = null; + tabView.items = [item]; + }, "Binding TabView to a TabViewItem with null view should throw."); } diff --git a/ui/activity-indicator/activity-indicator.d.ts b/ui/activity-indicator/activity-indicator.d.ts index 9a584f446..206702a06 100644 --- a/ui/activity-indicator/activity-indicator.d.ts +++ b/ui/activity-indicator/activity-indicator.d.ts @@ -2,17 +2,17 @@ * Contains the ActivityIndicator class, which represents a widget for showing that something is currently busy. */ declare module "ui/activity-indicator" { - import view = require("ui/core/view"); - import dependencyObservable = require("ui/core/dependency-observable"); + import {View} from "ui/core/view"; + import {Property} from "ui/core/dependency-observable"; /** * Represents a UI widget which displays a progress indicator hinting the user for some background operation running. */ - export class ActivityIndicator extends view.View { + export class ActivityIndicator extends View { /** * Represents the busy property of the ActivityIndicator class. */ - public static busyProperty: dependencyObservable.Property; + public static busyProperty: Property; /** * Gets the native [android widget](http://developer.android.com/reference/android/widget/ProgressBar.html) that represents the user interface for this component. Valid only when running on Android OS. diff --git a/ui/border/border.d.ts b/ui/border/border.d.ts index ade662932..b72ae065e 100644 --- a/ui/border/border.d.ts +++ b/ui/border/border.d.ts @@ -2,13 +2,13 @@ * Contains the Border class, which represents a UI border component. */ declare module "ui/border" { - import contentView = require("ui/content-view"); - import color = require("color"); + import {ContentView} from "ui/content-view"; + import {Color} from "color"; /** * Represents a UI border component. */ - export class Border extends contentView.ContentView { + export class Border extends ContentView { /** * Gets or sets the corner radius of the border component. */ @@ -22,6 +22,6 @@ declare module "ui/border" { /** * Gets or sets the border color of the border component. */ - borderColor: color.Color; + borderColor: Color; } } \ No newline at end of file diff --git a/ui/button/button.d.ts b/ui/button/button.d.ts index 6c2db175e..cbb22a80d 100644 --- a/ui/button/button.d.ts +++ b/ui/button/button.d.ts @@ -77,4 +77,4 @@ declare module "ui/button" { _setFormattedTextPropertyToNative(value: any): void; //@endprivate } -} +} \ No newline at end of file diff --git a/ui/core/bindable.ts b/ui/core/bindable.ts index a83bb3c93..a646fa7ad 100644 --- a/ui/core/bindable.ts +++ b/ui/core/bindable.ts @@ -1,70 +1,42 @@ -import observable = require("data/observable"); -import definition = require("ui/core/bindable"); -import dependencyObservable = require("ui/core/dependency-observable"); +import definition = require("ui/core/bindable"); +import {Observable, PropertyChangeData} from "data/observable"; +import {DependencyObservable, Property, PropertyMetadata, PropertyMetadataSettings, PropertyChangeData as DependencyPropertyChangeData} from "ui/core/dependency-observable"; import weakEvents = require("ui/core/weak-event-listener"); import types = require("utils/types"); import trace = require("trace"); import bindingBuilder = require("../builder/binding-builder"); import viewModule = require("ui/core/view"); -import * as applicationModule from "application"; -import * as polymerExpressionsModule from "js-libs/polymer-expressions"; -import * as specialPropertiesModule from "ui/builder/special-properties"; +import * as application from "application"; +import * as polymerExpressions from "js-libs/polymer-expressions"; +import * as specialProperties from "ui/builder/special-properties"; import * as utils from "utils/utils"; -//late import -var application: typeof applicationModule; -function ensureApplication() { - if (!application) { - application = require("application"); - } -} - -var expressions: typeof polymerExpressionsModule; -function ensureExpressions() { - if (!expressions) { - expressions = require("js-libs/polymer-expressions"); - } -} - -var specialProperties: typeof specialPropertiesModule; -function ensureSpecialProperties() { - if (!specialProperties) { - specialProperties = require("ui/builder/special-properties"); - } -} - -var bindingContextProperty = new dependencyObservable.Property( +let bindingContextProperty = new Property( "bindingContext", "Bindable", - new dependencyObservable.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.Inheritable, onBindingContextChanged) + new PropertyMetadata(undefined, PropertyMetadataSettings.Inheritable, onBindingContextChanged) ); -function onBindingContextChanged(data: dependencyObservable.PropertyChangeData) { - var bindable = data.object; +function onBindingContextChanged(data: DependencyPropertyChangeData) { + let bindable = data.object; bindable._onBindingContextChanged(data.oldValue, data.newValue); } -var contextKey = "context"; +let contextKey = "context"; // this regex is used to get parameters inside [] for example: // from $parents['ListView'] will return 'ListView' // from $parents[1] will return 1 -var paramsRegex = /\[\s*(['"])*(\w*)\1\s*\]/; +let paramsRegex = /\[\s*(['"])*(\w*)\1\s*\]/; -var bc = bindingBuilder.bindingConstants; +let bc = bindingBuilder.bindingConstants; -export class Bindable extends dependencyObservable.DependencyObservable implements definition.Bindable { +let defaultBindingSource = {}; + +export class Bindable extends DependencyObservable implements definition.Bindable { public static bindingContextProperty = bindingContextProperty; - // TODO: Implement with WeakRef to prevent memory leaks. - private _bindings: Object; - - private get bindings(): Object { - if (!this._bindings) { - this._bindings = {}; - } - return this._bindings; - } + private bindings = new Map(); get bindingContext(): Object { return this._getValue(Bindable.bindingContextProperty); @@ -73,47 +45,47 @@ export class Bindable extends dependencyObservable.DependencyObservable implemen this._setValue(Bindable.bindingContextProperty, value); } - public bind(options: definition.BindingOptions, source?: Object) { - var binding: Binding = this.bindings[options.targetProperty]; + public bind(options: definition.BindingOptions, source: Object = defaultBindingSource) { + let binding: Binding = this.bindings.get(options.targetProperty); if (binding) { binding.unbind(); } binding = new Binding(this, options); - this.bindings[options.targetProperty] = binding; + this.bindings.set(options.targetProperty, binding); - var bindingSource = source; - if (!bindingSource) { + let bindingSource = source; + if (bindingSource === defaultBindingSource) { bindingSource = this.bindingContext; binding.sourceIsBindingContext = true; } + if (!types.isNullOrUndefined(bindingSource)) { binding.bind(bindingSource); } } public unbind(property: string) { - var binding: Binding = this.bindings[property]; + let binding: Binding = this.bindings.get(property); if (binding) { binding.unbind(); - delete this.bindings[property]; + this.bindings.delete(property); } } public _updateTwoWayBinding(propertyName: string, value: any) { - var binding: Binding = this.bindings[propertyName]; - + let binding: Binding = this.bindings.get(propertyName); if (binding) { binding.updateTwoWay(value); } } - public _setCore(data: observable.PropertyChangeData) { + public _setCore(data: PropertyChangeData) { super._setCore(data); this._updateTwoWayBinding(data.propertyName, data.value); } - public _onPropertyChanged(property: dependencyObservable.Property, oldValue: any, newValue: any) { + public _onPropertyChanged(property: Property, oldValue: any, newValue: any) { trace.write(`${this}._onPropertyChanged(${property.name}, ${oldValue}, ${newValue})`, trace.categories.Binding); super._onPropertyChanged(property, oldValue, newValue); if (this instanceof viewModule.View) { @@ -121,7 +93,8 @@ export class Bindable extends dependencyObservable.DependencyObservable implemen return; } } - var binding = this.bindings[property.name]; + + let binding = this.bindings.get(property.name); if (binding && !binding.updating) { if (binding.options.twoWay) { trace.write(`${this}._updateTwoWayBinding(${property.name}, ${newValue});` + property.name, trace.categories.Binding); @@ -135,168 +108,175 @@ export class Bindable extends dependencyObservable.DependencyObservable implemen } public _onBindingContextChanged(oldValue: any, newValue: any) { - var binding: Binding; - for (var p in this.bindings) { - binding = this.bindings[p]; - - if (binding.updating || !binding.sourceIsBindingContext) { - continue; - } - - trace.write(`Binding ${binding.target.get()}.${binding.options.targetProperty} to new context ${newValue}`, trace.categories.Binding); - binding.unbind(); - if (!types.isNullOrUndefined(newValue)) { + this.bindings.forEach((binding, index, bindings) => { + if (!binding.updating && binding.sourceIsBindingContext) { + trace.write(`Binding ${binding.target.get()}.${binding.options.targetProperty} to new context ${newValue}`, trace.categories.Binding); binding.bind(newValue); } - } + }); } } -export class Binding { - options: definition.BindingOptions; - updating = false; - sourceIsBindingContext: boolean; - source: WeakRef; - target: WeakRef; +let emptyArray = []; +function getProperties(property: string): Array { + let result: Array = emptyArray; + if (property) { + // first replace all '$parents[..]' with a safe string + // second removes all ] since they are not important for property access and not needed + // then split properties either on '.' or '[' + let parentsMatches = property.match(bindingBuilder.parentsRegex); + result = property.replace(bindingBuilder.parentsRegex, "parentsMatch") + .replace(/\]/g, "") + .split(/\.|\[/); - public loadedHandlerVisualTreeBinding(args) { - var targetInstance = args.object; - targetInstance.off(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this); - this.unbind(); - if (!types.isNullOrUndefined(targetInstance.bindingContext)) { - this.bind(targetInstance.bindingContext); + let parentsMatchesCounter = 0; + for (let i = 0, resultLength = result.length; i < resultLength; i++) { + if (result[i] === "parentsMatch") { + result[i] = parentsMatches[parentsMatchesCounter++]; + } } - }; + } - private propertyChangeListeners = {}; + return result; +} - private sourceOptions: { instance: WeakRef; property: any }; - private targetOptions: { instance: WeakRef; property: any }; +export class Binding { + private source: WeakRef; + public target: WeakRef; - private sourcePropertiesArray: Array; + private sourceOptions: { instance: WeakRef; property: string }; + private targetOptions: { instance: WeakRef; property: string }; + + private sourcesAndProperties: Array<{ instance: Object; property: string }>; + + private propertyChangeListeners: Map = new Map(); + private sourceProperties: Array; + + public updating: boolean; + public options: definition.BindingOptions; + public sourceIsBindingContext: boolean; constructor(target: Bindable, options: definition.BindingOptions) { this.target = new WeakRef(target); this.options = options; + this.sourceProperties = getProperties(options.sourceProperty); + this.targetOptions = this.resolveOptions(target, getProperties(options.targetProperty)); } - public bind(obj: Object) { - if (types.isNullOrUndefined(obj)) { - throw new Error("Expected valid object reference as a source in the Binding.bind method."); + public loadedHandlerVisualTreeBinding(args) { + let target = args.object; + target.off(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this); + if (!types.isNullOrUndefined(target.bindingContext)) { + this.bind(target.bindingContext); } + }; + + public clearSource(): void { + this.propertyChangeListeners.forEach((observable, index, map) => { + weakEvents.removeWeakEventListener( + observable, + Observable.propertyChangeEvent, + this.onSourcePropertyChanged, + this); + }); + + this.propertyChangeListeners.clear(); + this.sourcesAndProperties = null; + + if (this.source) { + this.source.clear(); + } + + if (this.sourceOptions) { + this.sourceOptions.instance.clear(); + this.sourceOptions = undefined; + } + } + + public bind(source: Object): void { + this.clearSource(); /* tslint:disable */ - if (typeof (obj) === "number") { - obj = new Number(obj); + let objectType = typeof source; + if (objectType === "number") { + source = new Number(source); } - - if (typeof (obj) === "boolean") { - obj = new Boolean(obj); + else if (objectType === "boolean") { + source = new Boolean(source); } - - if (typeof (obj) === "string") { - obj = new String(obj); + else if (objectType === "string") { + source = new String(source); } /* tslint:enable */ - this.source = new WeakRef(obj); - this.updateTarget(this.getSourcePropertyValue()); - if (!this.sourceOptions) { - this.sourceOptions = this.resolveOptions(this.source, this.getSourceProperties()); - } + if (!types.isNullOrUndefined(source)) { + this.source = new WeakRef(source); + this.sourceOptions = this.resolveOptions(source, this.sourceProperties); - this.addPropertyChangeListeners(this.source, this.getSourceProperties()); - } - - private getSourceProperties(): Array { - if (!this.sourcePropertiesArray) { - this.sourcePropertiesArray = Binding.getProperties(this.options.sourceProperty); - } - return this.sourcePropertiesArray; - } - - private static getProperties(property: string): Array { - var result: Array; - if (property) { - // first replace all '$parents[..]' with a safe string - // second removes all ] since they are not important for property access and not needed - // then split properties either on '.' or '[' - var parentsMatches = property.match(bindingBuilder.parentsRegex); - result = property.replace(bindingBuilder.parentsRegex, "parentsMatch") - .replace(/\]/g, "") - .split(/\.|\[/); - - var i; - var resultLength = result.length; - var parentsMatchesCounter = 0; - for (i = 0; i < resultLength; i++) { - if (result[i] === "parentsMatch") { - result[i] = parentsMatches[parentsMatchesCounter]; - parentsMatchesCounter++; - } - } - - return result; + let sourceValue = this.getSourcePropertyValue(); + this.updateTarget(sourceValue); + this.addPropertyChangeListeners(this.source, this.sourceProperties); } else { - return []; + this.updateTarget(source); } } - private resolveObjectsAndProperties(source: Object, propsArray: Array) { - var result = []; - var i; - var propsArrayLength = propsArray.length; - var currentObject = source; - var objProp = ""; - var currentObjectChanged = false; - for (i = 0; i < propsArrayLength; i++) { - objProp = propsArray[i]; - if (objProp === bc.bindingValueKey) { + // Consider returning single {} instead of array for performance. + private resolveObjectsAndProperties(source: Object, properties: Array): Array<{ instance: Object; property: string }> { + let result = []; + let currentObject = source; + let currentObjectChanged = false; + for (let i = 0, propsArrayLength = properties.length; i < propsArrayLength; i++) { + let property = properties[i]; + if (property === bc.bindingValueKey) { currentObjectChanged = true; } - if (objProp === bc.parentValueKey || objProp.indexOf(bc.parentsValueKey) === 0) { - var parentView = this.getParentView(this.target.get(), objProp).view; + + if (property === bc.parentValueKey || property.indexOf(bc.parentsValueKey) === 0) { + let parentView = this.getParentView(this.target.get(), property).view; if (parentView) { currentObject = parentView.bindingContext; } else { - var targetInstance = this.target.get(); + let targetInstance = this.target.get(); targetInstance.off(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this); targetInstance.on(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this); } + currentObjectChanged = true; } + if (currentObject) { - result.push({ instance: currentObject, property: objProp }); + result.push({ instance: currentObject, property: property }); } else { break; } + // do not need to dive into last object property getter on binding stage will handle it if (!currentObjectChanged && (i < propsArrayLength - 1)) { - currentObject = currentObject ? currentObject[propsArray[i]] : null; + currentObject = currentObject ? currentObject[properties[i]] : null; } + currentObjectChanged = false; } + return result; } private addPropertyChangeListeners(source: WeakRef, sourceProperty: Array, parentProperies?: string) { - var objectsAndProperties = this.resolveObjectsAndProperties(source.get(), sourceProperty) - var objectsAndPropertiesLength = objectsAndProperties.length; - if (objectsAndPropertiesLength > 0) { - var i; - var prop = parentProperies || ""; - for (i = 0; i < objectsAndPropertiesLength; i++) { - prop += "$" + objectsAndProperties[i].property; - var currentObject = objectsAndProperties[i].instance; - if (!this.propertyChangeListeners[prop] && currentObject instanceof observable.Observable) { - weakEvents.addWeakEventListener( - currentObject, - observable.Observable.propertyChangeEvent, - this.onSourcePropertyChanged, - this); - this.propertyChangeListeners[prop] = currentObject; - } + let objectsAndProperties = this.resolveObjectsAndProperties(source.get(), sourceProperty) + let prop = parentProperies || ""; + + for (let i = 0, length = objectsAndProperties.length; i < length; i++) { + prop += "$" + objectsAndProperties[i].property; + let currentObject = objectsAndProperties[i].instance; + if (!this.propertyChangeListeners.has(prop) && currentObject instanceof Observable) { + weakEvents.addWeakEventListener( + currentObject, + Observable.propertyChangeEvent, + this.onSourcePropertyChanged, + this); + this.propertyChangeListeners.set(prop, currentObject); } } } @@ -306,28 +286,12 @@ export class Binding { return; } - var i; - var propertyChangeListenersKeys = Object.keys(this.propertyChangeListeners); - for (i = 0; i < propertyChangeListenersKeys.length; i++) { - weakEvents.removeWeakEventListener( - this.propertyChangeListeners[propertyChangeListenersKeys[i]], - observable.Observable.propertyChangeEvent, - this.onSourcePropertyChanged, - this); - delete this.propertyChangeListeners[propertyChangeListenersKeys[i]]; - } + this.clearSource(); - if (this.source) { - this.source.clear(); - } - if (this.sourceOptions) { - this.sourceOptions.instance.clear(); - this.sourceOptions = undefined; - } if (this.targetOptions) { this.targetOptions = undefined; } - this.sourcePropertiesArray = undefined; + this.sourceProperties = undefined; } private prepareExpressionForUpdate(): string { @@ -337,142 +301,140 @@ export class Binding { // text="{{ sourceProperty = $parents['ListView'].test, expression = $parents['ListView'].test + 2}}" // update expression will be '$newPropertyValue + 2' // then on expression execution the new value will be taken and target property will be updated with the value of the expression. - var escapedSourceProperty = utils.escapeRegexSymbols(this.options.sourceProperty); - var expRegex = new RegExp(escapedSourceProperty, 'g'); - var resultExp = this.options.expression.replace(expRegex, bc.newPropertyValueKey); + let escapedSourceProperty = utils.escapeRegexSymbols(this.options.sourceProperty); + let expRegex = new RegExp(escapedSourceProperty, 'g'); + let resultExp = this.options.expression.replace(expRegex, bc.newPropertyValueKey); return resultExp; } public updateTwoWay(value: any) { - if (this.updating) { + if (this.updating || !this.options.twoWay) { return; } - if (this.options.twoWay) { - if (this.options.expression) { - var changedModel = {}; - changedModel[bc.bindingValueKey] = value; - changedModel[bc.newPropertyValueKey] = value; - var sourcePropertyName = ""; - if (this.sourceOptions) { - sourcePropertyName = this.sourceOptions.property; - } - else if (typeof this.options.sourceProperty === "string" && this.options.sourceProperty.indexOf(".") === -1) { - sourcePropertyName = this.options.sourceProperty; - } - if (sourcePropertyName !== "") { - changedModel[sourcePropertyName] = value; - } - var updateExpression = this.prepareExpressionForUpdate(); - this.prepareContextForExpression(changedModel, updateExpression); - var expressionValue = this._getExpressionValue(updateExpression, true, changedModel); - if (expressionValue instanceof Error) { - trace.write((expressionValue).message, trace.categories.Binding, trace.messageType.error); - } - else { - this.updateSource(expressionValue); - } + + let newValue = value; + if (this.options.expression) { + let changedModel = {}; + changedModel[bc.bindingValueKey] = value; + changedModel[bc.newPropertyValueKey] = value; + let sourcePropertyName = ""; + if (this.sourceOptions) { + sourcePropertyName = this.sourceOptions.property; } - else { - this.updateSource(value); + else if (typeof this.options.sourceProperty === "string" && this.options.sourceProperty.indexOf(".") === -1) { + sourcePropertyName = this.options.sourceProperty; } + + if (sourcePropertyName !== "") { + changedModel[sourcePropertyName] = value; + } + + let updateExpression = this.prepareExpressionForUpdate(); + this.prepareContextForExpression(changedModel, updateExpression); + + let expressionValue = this._getExpressionValue(updateExpression, true, changedModel); + if (expressionValue instanceof Error) { + trace.write((expressionValue).message, trace.categories.Binding, trace.messageType.error); + } + + newValue = expressionValue; } + + this.updateSource(newValue); } private _getExpressionValue(expression: string, isBackConvert: boolean, changedModel: any): any { try { - ensureExpressions(); - - var exp = expressions.PolymerExpressions.getExpression(expression); + let exp = polymerExpressions.PolymerExpressions.getExpression(expression); if (exp) { - var context = this.source && this.source.get && this.source.get() || global; - var model = {}; - var addedProps = []; - ensureApplication(); - for (var prop in application.resources) { + let context = this.source && this.source.get && this.source.get() || global; + let model = {}; + let addedProps = []; + for (let prop in application.resources) { if (application.resources.hasOwnProperty(prop) && !context.hasOwnProperty(prop)) { context[prop] = application.resources[prop]; addedProps.push(prop); } } - + this.prepareContextForExpression(context, expression); model[contextKey] = context; let result = exp.getValue(model, isBackConvert, changedModel ? changedModel : model); // clear added props let addedPropsLength = addedProps.length; - for(let i = 0; i < addedPropsLength; i++) { + for (let i = 0; i < addedPropsLength; i++) { delete context[addedProps[i]]; } addedProps.length = 0; - + return result; } return new Error(expression + " is not a valid expression."); } catch (e) { - var errorMessage = "Run-time error occured in file: " + e.sourceURL + " at line: " + e.line + " and column: " + e.column; + let errorMessage = "Run-time error occured in file: " + e.sourceURL + " at line: " + e.line + " and column: " + e.column; return new Error(errorMessage); } } - public onSourcePropertyChanged(data: observable.PropertyChangeData) { - var sourceProps = Binding.getProperties(this.options.sourceProperty); - var sourcePropsLength = sourceProps.length; - var changedPropertyIndex = sourceProps.indexOf(data.propertyName); - var parentProps = ""; + public onSourcePropertyChanged(data: PropertyChangeData) { + let sourceProps = this.sourceProperties; + let sourcePropsLength = sourceProps.length; + let changedPropertyIndex = sourceProps.indexOf(data.propertyName); + let parentProps = ""; if (changedPropertyIndex > -1) { parentProps = "$" + sourceProps.slice(0, changedPropertyIndex + 1).join("$"); - while (this.propertyChangeListeners[parentProps] !== data.object) { + while (this.propertyChangeListeners.get(parentProps) !== data.object) { changedPropertyIndex += sourceProps.slice(changedPropertyIndex + 1).indexOf(data.propertyName) + 1; parentProps = "$" + sourceProps.slice(0, changedPropertyIndex + 1).join("$"); } } - + if (this.options.expression) { - var expressionValue = this._getExpressionValue(this.options.expression, false, undefined); + let expressionValue = this._getExpressionValue(this.options.expression, false, undefined); if (expressionValue instanceof Error) { trace.write((expressionValue).message, trace.categories.Binding, trace.messageType.error); - } - else { + } else { this.updateTarget(expressionValue); } } else { if (changedPropertyIndex > -1) { - var props = sourceProps.slice(changedPropertyIndex + 1); - var propsLength = props.length; + let props = sourceProps.slice(changedPropertyIndex + 1); + let propsLength = props.length; if (propsLength > 0) { - var value = data.value; + let value = data.value; for (let i = 0; i < propsLength; i++) { value = value[props[i]]; } + this.updateTarget(value); - } - else if (data.propertyName === this.sourceOptions.property) { + } else if (data.propertyName === this.sourceOptions.property) { this.updateTarget(data.value); } } } if (changedPropertyIndex > -1) { - var probablyChangedObject = this.propertyChangeListeners[parentProps]; + let probablyChangedObject = this.propertyChangeListeners.get(parentProps); if (probablyChangedObject && probablyChangedObject !== data.object[sourceProps[changedPropertyIndex]]) { // remove all weakevent listeners after change, because changed object replaces object that is hooked for // propertyChange event for (let i = sourcePropsLength - 1; i > changedPropertyIndex; i--) { - var prop = "$" + sourceProps.slice(0, i + 1).join("$"); - if (this.propertyChangeListeners[prop]) { + let prop = "$" + sourceProps.slice(0, i + 1).join("$"); + if (this.propertyChangeListeners.has(prop)) { weakEvents.removeWeakEventListener( - this.propertyChangeListeners[prop], - observable.Observable.propertyChangeEvent, + this.propertyChangeListeners.get(prop), + Observable.propertyChangeEvent, this.onSourcePropertyChanged, this); - delete this.propertyChangeListeners[prop]; + this.propertyChangeListeners.delete(prop); } } - var newProps = sourceProps.slice(changedPropertyIndex + 1); + + let newProps = sourceProps.slice(changedPropertyIndex + 1); // add new weakevent listeners - var newObject = data.object[sourceProps[changedPropertyIndex]] + let newObject = data.object[sourceProps[changedPropertyIndex]] if (typeof newObject === 'object') { this.addPropertyChangeListeners(new WeakRef(data.object[sourceProps[changedPropertyIndex]]), newProps, parentProps); } @@ -480,12 +442,13 @@ export class Binding { } } - private prepareContextForExpression(model, expression) { - var parentViewAndIndex; - var parentView; + private prepareContextForExpression(model: Object, expression: string) { + let parentViewAndIndex: { view: viewModule.View, index: number }; + let parentView; if (expression.indexOf(bc.bindingValueKey) > -1) { model[bc.bindingValueKey] = model; } + if (expression.indexOf(bc.parentValueKey) > -1) { parentView = this.getParentView(this.target.get(), bc.parentValueKey).view; if (parentView) { @@ -493,10 +456,9 @@ export class Binding { } } - var parentsArray = expression.match(bindingBuilder.parentsRegex); + let parentsArray = expression.match(bindingBuilder.parentsRegex); if (parentsArray) { - var i; - for (i = 0; i < parentsArray.length; i++) { + for (let i = 0; i < parentsArray.length; i++) { parentViewAndIndex = this.getParentView(this.target.get(), parentsArray[i]); if (parentViewAndIndex.view) { model[bc.parentsValueKey] = model[bc.parentsValueKey] || {}; @@ -508,9 +470,9 @@ export class Binding { private getSourcePropertyValue() { if (this.options.expression) { - var changedModel = {}; + let changedModel = {}; changedModel[bc.bindingValueKey] = this.source.get(); - var expressionValue = this._getExpressionValue(this.options.expression, false, changedModel); + let expressionValue = this._getExpressionValue(this.options.expression, false, changedModel); if (expressionValue instanceof Error) { trace.write((expressionValue).message, trace.categories.Binding, trace.messageType.error); } @@ -519,72 +481,59 @@ export class Binding { } } - if (!this.sourceOptions) { - this.sourceOptions = this.resolveOptions(this.source, this.getSourceProperties()); - } - - var value; - if (this.sourceOptions) { - var sourceOptionsInstance = this.sourceOptions.instance.get(); + let sourceOptionsInstance = this.sourceOptions.instance.get(); if (this.sourceOptions.property === bc.bindingValueKey) { - value = sourceOptionsInstance; - } else if ((sourceOptionsInstance instanceof observable.Observable) && (this.sourceOptions.property && this.sourceOptions.property !== "")) { - value = sourceOptionsInstance.get(this.sourceOptions.property); + return sourceOptionsInstance; + } else if ((sourceOptionsInstance instanceof Observable) && (this.sourceOptions.property && this.sourceOptions.property !== "")) { + return sourceOptionsInstance.get(this.sourceOptions.property); } else if (sourceOptionsInstance && this.sourceOptions.property && this.sourceOptions.property !== "" && this.sourceOptions.property in sourceOptionsInstance) { - value = sourceOptionsInstance[this.sourceOptions.property]; + return sourceOptionsInstance[this.sourceOptions.property]; } else { trace.write("Property: '" + this.sourceOptions.property + "' is invalid or does not exist. SourceProperty: '" + this.options.sourceProperty + "'", trace.categories.Binding, trace.messageType.error); } } - return value; + + return null; } private updateTarget(value: any) { - if (this.updating || (!this.target || !this.target.get())) { + if (this.updating) { return; } - if (!this.targetOptions) { - this.targetOptions = this.resolveOptions(this.target, Binding.getProperties(this.options.targetProperty)); - } - this.updateOptions(this.targetOptions, value); } private updateSource(value: any) { - if (this.updating || (!this.source || !this.source.get())) { + if (this.updating || !this.source || !this.source.get()) { return; } - if (!this.sourceOptions) { - this.sourceOptions = this.resolveOptions(this.source, this.getSourceProperties()); - } - this.updateOptions(this.sourceOptions, value); } - private getParentView(target, property) { + private getParentView(target: any, property: string): { view: viewModule.View, index: number } { if (!target || !(target instanceof viewModule.View)) { return { view: null, index: null }; } - var result; + let result: viewModule.View; if (property === bc.parentValueKey) { result = target.parent; } + let index = null; if (property.indexOf(bc.parentsValueKey) === 0) { result = target.parent; - var indexParams = paramsRegex.exec(property); - var index; + let indexParams = paramsRegex.exec(property); if (indexParams && indexParams.length > 1) { index = indexParams[2]; } if (!isNaN(index)) { - var indexAsInt = parseInt(index); + let indexAsInt = parseInt(index); while (indexAsInt > 0) { result = result.parent; indexAsInt--; @@ -599,24 +548,25 @@ export class Binding { return { view: result, index: index }; } - private resolveOptions(obj: WeakRef, properties: Array): { instance: any; property: any } { - var objectsAndProperties = this.resolveObjectsAndProperties(obj.get(), properties); + private resolveOptions(obj: Object, properties: Array): { instance: WeakRef; property: any } { + let objectsAndProperties = this.resolveObjectsAndProperties(obj, properties); if (objectsAndProperties.length > 0) { - var resolvedObj = objectsAndProperties[objectsAndProperties.length - 1].instance; - var prop = objectsAndProperties[objectsAndProperties.length - 1].property; - return { - instance: new WeakRef(resolvedObj), - property: prop + let resolvedObj = objectsAndProperties[objectsAndProperties.length - 1].instance; + let prop = objectsAndProperties[objectsAndProperties.length - 1].property; + return { + instance: new WeakRef(resolvedObj), + property: prop } } return null; } - private updateOptions(options: { instance: WeakRef; property: any }, value: any) { - var optionsInstance; + private updateOptions(options: { instance: WeakRef; property: string }, value: any) { + let optionsInstance; if (options && options.instance) { optionsInstance = options.instance.get(); } + if (!optionsInstance) { return; } @@ -631,13 +581,11 @@ export class Binding { optionsInstance.off(options.property, null, optionsInstance.bindingContext); optionsInstance.on(options.property, value, optionsInstance.bindingContext); } else { - ensureSpecialProperties(); - let specialSetter = specialProperties.getSpecialPropertySetter(options.property); if (specialSetter) { specialSetter(optionsInstance, value); } else { - if (optionsInstance instanceof observable.Observable) { + if (optionsInstance instanceof Observable) { optionsInstance.set(options.property, value); } else { optionsInstance[options.property] = value; @@ -653,4 +601,4 @@ export class Binding { this.updating = false; } -} +} \ No newline at end of file diff --git a/ui/core/dependency-observable.ts b/ui/core/dependency-observable.ts index 7716b2348..18190b77c 100644 --- a/ui/core/dependency-observable.ts +++ b/ui/core/dependency-observable.ts @@ -263,7 +263,7 @@ export class PropertyEntry implements definition.PropertyEntry { var defaultValueForPropertyPerType: Map = new Map(); -export class DependencyObservable extends Observable { +export class DependencyObservable extends Observable implements definition.DependencyObservable { private _propertyEntries = {}; public set(name: string, value: any) { diff --git a/ui/core/view-common.ts b/ui/core/view-common.ts index 2c5ed6573..b91a57872 100644 --- a/ui/core/view-common.ts +++ b/ui/core/view-common.ts @@ -190,12 +190,8 @@ export class View extends ProxyObject implements definition.View { private _updatingInheritedProperties: boolean; - public _options: definition.Options; - - constructor(options?: definition.Options) { - super(); - - this._options = options; + constructor() { + super({}); this._style = new style.Style(this); this._domId = viewIdCounter++; diff --git a/ui/core/view.android.ts b/ui/core/view.android.ts index c27b09f5f..0bd4a7431 100644 --- a/ui/core/view.android.ts +++ b/ui/core/view.android.ts @@ -268,9 +268,6 @@ export class View extends viewCommon.View { this._nativeView.setLayoutParams(new org.nativescript.widgets.CommonLayoutParams()); } - utils.copyFrom(this._options, this); - delete this._options; - // copy all the locally cached values to the native android widget this._syncNativeProperties(); trace.notifyEvent(this, "_onContextChanged"); diff --git a/ui/core/view.d.ts b/ui/core/view.d.ts index d2c4a886c..42c1e876c 100644 --- a/ui/core/view.d.ts +++ b/ui/core/view.d.ts @@ -64,68 +64,6 @@ declare module "ui/core/view" { */ height: number; } - - /** - * Defines interface for an optional parameter used to create a view. - */ - export interface Options { - /** - * Gets or sets the desired width of the view. - */ - width?: number; - /** - * Gets or sets the desired height of the view. - */ - height?: number; - /** - * Gets or sets the minimum width the view may grow to. - */ - minWidth?: number; - /** - * Gets or sets the minimum height the view may grow to. - */ - minHeight?: number; - /** - * Gets or sets the alignment of this view within its parent along the Horizontal axis. - */ - horizontalAlignment?: string; - /** - * Gets or sets the alignment of this view within its parent along the Vertical axis. - */ - verticalAlignment?: string; - /** - * Specifies extra space on the left side of this view. - */ - marginLeft?: number; - /** - * Specifies extra space on the top side of this view. - */ - marginTop?: number; - /** - * Specifies extra space on the right side of this view. - */ - marginRight?: number; - /** - * Specifies extra space on the bottom side of this view. - */ - marginBottom?: number; - /** - * Gets or sets the visibility of this view. - */ - visibility?: string; - /** - * [Deprecated. Please use className instead] Gets or sets the CSS class of this view. - */ - cssClass?: string; - /** - * Gets or sets the CSS class name of this view. - */ - className?: string; - /** - * Gets or sets the id of this view. - */ - id?: string; - } /** * This class is the base class for all UI components. @@ -192,8 +130,6 @@ declare module "ui/core/view" { */ public static isUserInteractionEnabledProperty: dependencyObservable.Property; - constructor(options?: Options); - //----------Style property shortcuts---------- /** diff --git a/ui/core/view.ios.ts b/ui/core/view.ios.ts index cb3808c1b..948f57eb6 100644 --- a/ui/core/view.ios.ts +++ b/ui/core/view.ios.ts @@ -90,20 +90,6 @@ export class View extends viewCommon.View { this.requestLayout(); } - public onLoaded() { - super.onLoaded(); - - // TODO: It is very late to work with options here in the onLoaded method. - // We should not do anything that affects UI AFTER the widget has been loaded. - utils.copyFrom(this._options, this); - delete this._options; - - // We do not need to call this in iOS, since the native instance is created immediately - // and any props that you set on our instance are immediately synced onto the native one. - // _syncNativeProperties makes sense for Android only, where widgets are created later. - // this._syncNativeProperties(); - } - get _nativeView(): UIView { return this.ios; } diff --git a/ui/editable-text-base/editable-text-base-common.ts b/ui/editable-text-base/editable-text-base-common.ts index 3d31c9b29..bed4af28a 100644 --- a/ui/editable-text-base/editable-text-base-common.ts +++ b/ui/editable-text-base/editable-text-base-common.ts @@ -104,10 +104,6 @@ export class EditableTextBase extends textBase.TextBase implements definition.Ed public static hintProperty = hintProperty; - constructor(options?: definition.Options) { - super(options); - } - get keyboardType(): string { return this._getValue(EditableTextBase.keyboardTypeProperty); } diff --git a/ui/editable-text-base/editable-text-base.android.ts b/ui/editable-text-base/editable-text-base.android.ts index de260100e..a4a28231c 100644 --- a/ui/editable-text-base/editable-text-base.android.ts +++ b/ui/editable-text-base/editable-text-base.android.ts @@ -1,5 +1,4 @@ import common = require("./editable-text-base-common"); -import textBase = require("ui/text-base"); import dependencyObservable = require("ui/core/dependency-observable"); import enums = require("ui/enums"); import utils = require("utils/utils"); @@ -13,10 +12,6 @@ export class EditableTextBase extends common.EditableTextBase { private _dirtyTextAccumulator: string; /* tslint:enable */ - constructor(options?: textBase.Options) { - super(options); - } - get android(): android.widget.EditText { return this._android; } diff --git a/ui/editable-text-base/editable-text-base.d.ts b/ui/editable-text-base/editable-text-base.d.ts index b79da4e2e..a40a5f7cf 100644 --- a/ui/editable-text-base/editable-text-base.d.ts +++ b/ui/editable-text-base/editable-text-base.d.ts @@ -13,8 +13,6 @@ public static autocapitalizationTypeProperty: dependencyObservable.Property; public static autocorrectProperty: dependencyObservable.Property; - constructor(options?: Options); - /** * Gets or sets the soft keyboard type. Possible values are contained in the [KeyboardType enumeration](../enums/KeyboardType/README.md). */ @@ -35,12 +33,12 @@ * Possible values are contained in the [UpdateTextTrigger enumeration](../enums/UpdateTextTrigger/README.md). */ updateTextTrigger: string; - + /** * Gets or sets the autocapitalization type. Possible values are contained in the [AutocapitalizationType enumeration](../enums/AutocapitalizationType/README.md). */ autocapitalizationType: string; - + /** * Enables or disables autocorrection. */ @@ -56,44 +54,4 @@ */ dismissSoftInput(): void; } - - /** - * An interface for common options used to create an editable text component. - */ - export interface Options extends textBase.Options { - /** - * Gets or sets the soft keyboard type. - */ - keyboardType?: string; - - /** - * Gets or sets the soft keyboard return key flavor. - */ - returnKeyType?: string; - - /** - * Gets or sets whether the instance is editable. - */ - editable?: boolean; - - /** - * Gets or sets a value indicating when the text property will be updated. - */ - updateTextTrigger?: string; - - /** - * Gets or sets the autocapitalization type. - */ - autocapitalizationType?: string; - - /** - * Gets or sets the placeholder text. - */ - hint?: string; - - /** - * Enables or disables autocorrection. - */ - autocorrect?: boolean; - } } \ No newline at end of file diff --git a/ui/editable-text-base/editable-text-base.ios.ts b/ui/editable-text-base/editable-text-base.ios.ts index 507ecea2f..73b2f8432 100644 --- a/ui/editable-text-base/editable-text-base.ios.ts +++ b/ui/editable-text-base/editable-text-base.ios.ts @@ -1,13 +1,8 @@ import common = require("./editable-text-base-common"); -import textBase = require("ui/text-base"); import dependencyObservable = require("ui/core/dependency-observable"); import enums = require("ui/enums"); export class EditableTextBase extends common.EditableTextBase { - constructor(options?: textBase.Options) { - super(options); - } - public dismissSoftInput() { (this.ios).resignFirstResponder(); } diff --git a/ui/html-view/html-view-common.ts b/ui/html-view/html-view-common.ts index d6ad1a000..44253daba 100644 --- a/ui/html-view/html-view-common.ts +++ b/ui/html-view/html-view-common.ts @@ -10,10 +10,6 @@ export class HtmlView extends view.View implements definition.HtmlView { new proxy.PropertyMetadata(false, dependencyObservable.PropertyMetadataSettings.AffectsLayout) ); - constructor(options?: definition.Options) { - super(options); - } - get html(): string { return this._getValue(HtmlView.htmlProperty); } diff --git a/ui/html-view/html-view.d.ts b/ui/html-view/html-view.d.ts index a188724f7..a132b0b2f 100644 --- a/ui/html-view/html-view.d.ts +++ b/ui/html-view/html-view.d.ts @@ -17,8 +17,6 @@ declare module "ui/html-view" { */ public static htmlProperty: dependencyObservable.Property; - constructor(options?: Options); - /** * Gets the native [android widget](http://developer.android.com/reference/android/widget/TextView.html) that represents the user interface for this component. Valid only when running on Android OS. */ @@ -34,14 +32,4 @@ declare module "ui/html-view" { */ html: string; } - - /** - * Provides a set of most common options for creating a HtmlView. - */ - export interface Options extends view.Options { - /** - * Gets or sets the html content of a HtmlView. - */ - html?: string; - } -} +} \ No newline at end of file diff --git a/ui/html-view/html-view.ios.ts b/ui/html-view/html-view.ios.ts index 9ecc020f9..4f6bcf94e 100644 --- a/ui/html-view/html-view.ios.ts +++ b/ui/html-view/html-view.ios.ts @@ -1,5 +1,4 @@ import common = require("./html-view-common"); -import definition = require("ui/html-view"); import dependencyObservable = require("ui/core/dependency-observable"); import proxy = require("ui/core/proxy"); import * as utils from "utils/utils"; @@ -30,8 +29,8 @@ global.moduleMerge(common, exports); export class HtmlView extends common.HtmlView { private _ios: UITextView; - constructor(options?: definition.Options) { - super(options); + constructor() { + super(); this._ios = UITextView.new(); this._ios.scrollEnabled = false; diff --git a/ui/image/image-common.ts b/ui/image/image-common.ts index 9bb5a57df..cc03af900 100644 --- a/ui/image/image-common.ts +++ b/ui/image/image-common.ts @@ -73,10 +73,6 @@ export class Image extends view.View implements definition.Image { public static stretchProperty = new dependencyObservable.Property(STRETCH, IMAGE, new proxy.PropertyMetadata(enums.Stretch.aspectFit, AffectsLayout)); - constructor(options?: definition.Options) { - super(options); - } - get imageSource(): imageSource.ImageSource { return this._getValue(Image.imageSourceProperty); } diff --git a/ui/image/image.d.ts b/ui/image/image.d.ts index 7c699bdb6..e3748c86d 100644 --- a/ui/image/image.d.ts +++ b/ui/image/image.d.ts @@ -45,24 +45,4 @@ declare module "ui/image" { */ stretch: string; } - - /** - * Provides common options for creating an image. - */ - export interface Options extends view.Options { - /** - * Gets or sets the image source of the image. - */ - imageSource: imageSource.ImageSource; - - /** - * Gets or sets the URL of the image. - */ - src: string; - - /** - * Gets or sets the image stretch mode. Possible values are contained in the [Stretch enumeration](../enums/Stretch/README.md). - */ - stretch: string; - } -} +} \ No newline at end of file diff --git a/ui/image/image.ios.ts b/ui/image/image.ios.ts index 6d6eada2d..3b43ebf4a 100644 --- a/ui/image/image.ios.ts +++ b/ui/image/image.ios.ts @@ -1,7 +1,6 @@ import imageCommon = require("./image-common"); import dependencyObservable = require("ui/core/dependency-observable"); import proxy = require("ui/core/proxy"); -import definition = require("ui/image"); import enums = require("ui/enums"); global.moduleMerge(imageCommon, exports); @@ -38,8 +37,8 @@ function onImageSourcePropertyChanged(data: dependencyObservable.PropertyChangeD export class Image extends imageCommon.Image { private _ios: UIImageView; - constructor(options?: definition.Options) { - super(options); + constructor() { + super(); //TODO: Think of unified way of setting all the default values. this._ios = new UIImageView(); diff --git a/ui/label/label-common.ts b/ui/label/label-common.ts index f6a117d7a..56a8f338d 100644 --- a/ui/label/label-common.ts +++ b/ui/label/label-common.ts @@ -19,10 +19,6 @@ export class Label extends textBase.TextBase implements definition.Label { new proxy.PropertyMetadata(false, dependencyObservable.PropertyMetadataSettings.AffectsLayout) ); - constructor(options?: definition.Options) { - super(options); - } - get textWrap(): boolean { return this._getValue(Label.textWrapProperty); } diff --git a/ui/label/label.d.ts b/ui/label/label.d.ts index eab7dae1f..2d3b20d5b 100644 --- a/ui/label/label.d.ts +++ b/ui/label/label.d.ts @@ -2,7 +2,6 @@ * Contains the Label class, which represents a standard label widget. */ declare module "ui/label" { - import view = require("ui/core/view"); import dependencyObservable = require("ui/core/dependency-observable"); import textBase = require("ui/text-base"); @@ -16,8 +15,6 @@ declare module "ui/label" { */ public static textWrapProperty: dependencyObservable.Property; - constructor(options?: Options); - /** * Gets the native [android widget](http://developer.android.com/reference/android/widget/TextView.html) that represents the user interface for this component. Valid only when running on Android OS. */ @@ -33,19 +30,4 @@ declare module "ui/label" { */ textWrap: boolean; } - - /** - * Provides a set of most common options for creating a label. - */ - export interface Options extends view.Options { - /** - * Gets or sets the text content of a Label. - */ - text?: string; - - /** - * Gets or sets whether the Label wraps text or not. - */ - textWrap?: boolean; - } -} +} \ No newline at end of file diff --git a/ui/label/label.ios.ts b/ui/label/label.ios.ts index 57dae2b10..a1afc6747 100644 --- a/ui/label/label.ios.ts +++ b/ui/label/label.ios.ts @@ -1,5 +1,4 @@ import common = require("./label-common"); -import definition = require("ui/label"); import * as enums from "ui/enums"; import * as utils from "utils/utils"; import * as backgroundModule from "ui/styling/background"; @@ -61,8 +60,8 @@ class UILabelImpl extends UILabel { export class Label extends common.Label { private _ios: UILabel; - constructor(options?: definition.Options) { - super(options); + constructor() { + super(); this._ios = UILabelImpl.initWithOwner(new WeakRef(this)); this._ios.userInteractionEnabled = true; diff --git a/ui/list-picker/list-picker-common.ts b/ui/list-picker/list-picker-common.ts index 96e6ada3c..3992da47c 100644 --- a/ui/list-picker/list-picker-common.ts +++ b/ui/list-picker/list-picker-common.ts @@ -11,10 +11,6 @@ export class ListPicker extends view.View implements definition.ListPicker { public static selectedIndexProperty = new dependencyObservable.Property("selectedIndex", "ListPicker", new proxy.PropertyMetadata(undefined)); public static itemsProperty = new dependencyObservable.Property("items", "ListPicker", new proxy.PropertyMetadata(undefined)); - constructor() { - super(); - } - get selectedIndex(): number { return this._getValue(ListPicker.selectedIndexProperty); } diff --git a/ui/list-picker/list-picker.android.ts b/ui/list-picker/list-picker.android.ts index 496129e95..93e514aeb 100644 --- a/ui/list-picker/list-picker.android.ts +++ b/ui/list-picker/list-picker.android.ts @@ -15,10 +15,6 @@ export class ListPicker extends common.ListPicker { return this._android; } - constructor() { - super(); - } - public _createUI() { this._android = new android.widget.NumberPicker(this._context); this._android.setDescendantFocusability(android.widget.NumberPicker.FOCUS_BLOCK_DESCENDANTS); diff --git a/ui/page/page-common.ts b/ui/page/page-common.ts index 190774f7a..2a5c6cf5c 100644 --- a/ui/page/page-common.ts +++ b/ui/page/page-common.ts @@ -61,8 +61,8 @@ export class Page extends ContentView implements dts.Page { public _modal: Page; - constructor(options?: dts.Options) { - super(options); + constructor() { + super(); this.actionBar = new ActionBar(); } diff --git a/ui/page/page.android.ts b/ui/page/page.android.ts index 0216c1314..68fdb5c58 100644 --- a/ui/page/page.android.ts +++ b/ui/page/page.android.ts @@ -1,5 +1,4 @@ import pageCommon = require("./page-common"); -import definition = require("ui/page"); import view = require("ui/core/view"); import enums = require("ui/enums"); import * as actionBar from "ui/action-bar"; @@ -98,13 +97,8 @@ function ensureDialogFragmentClass() { export class Page extends pageCommon.Page { private _isBackNavigation = false; - private _grid: org.nativescript.widgets.GridLayout; - constructor(options?: definition.Options) { - super(options); - } - get android(): android.view.ViewGroup { return this._grid; } diff --git a/ui/page/page.d.ts b/ui/page/page.d.ts index 29ac2e6eb..a21c4569b 100644 --- a/ui/page/page.d.ts +++ b/ui/page/page.d.ts @@ -3,7 +3,6 @@ */ declare module "ui/page" { import observable = require("data/observable"); - import view = require("ui/core/view"); import contentView = require("ui/content-view"); import frame = require("ui/frame"); import actionBar = require("ui/action-bar"); @@ -37,7 +36,7 @@ declare module "ui/page" { * The context (optional, may be undefined) passed to the page when shown modally. */ context: any; - + /** * A callback to call when you want to close the modally shown page. Pass in any kind of arguments and you will receive when the callback parameter of Page.showModal is executed. */ @@ -92,8 +91,6 @@ declare module "ui/page" { */ public static navigatedFromEvent: string; - constructor(options?: Options) - /** * Gets or sets whether page background spans under status bar. */ @@ -174,7 +171,7 @@ declare module "ui/page" { * Raised when navigation from the page has finished. */ on(event: "navigatedFrom", callback: (args: NavigatedData) => void, thisArg?: any): void; - + /** * Raised before the page is shown as a modal dialog. */ @@ -217,7 +214,7 @@ declare module "ui/page" { * Returns the current modal view that this page is showing (is parent of), if any. */ modal: Page; - + //@private /** @@ -248,24 +245,4 @@ declare module "ui/page" { _getStyleScope(): styleScope.StyleScope; //@endprivate } - - /** - * Provides a set with most common option used to create a page instance. - */ - export interface Options extends view.Options { - /** - * Gets or sets the page module. - */ - module?: any; - - /** - * Gets or sets the page module file name. - */ - filename?: string; - - /** - * Gets or sets the page module exports. - */ - exports?: any; - } -} +} \ No newline at end of file diff --git a/ui/page/page.ios.ts b/ui/page/page.ios.ts index 35ae089fd..597d0df2b 100644 --- a/ui/page/page.ios.ts +++ b/ui/page/page.ios.ts @@ -1,5 +1,4 @@ import pageCommon = require("./page-common"); -import definition = require("ui/page"); import {View} from "ui/core/view"; import trace = require("trace"); import uiUtils = require("ui/utils"); @@ -256,17 +255,12 @@ class UIViewControllerImpl extends UIViewController { } export class Page extends pageCommon.Page { - private _ios: UIViewController; + private _ios: UIViewController = UIViewControllerImpl.initWithOwner(new WeakRef(this)); public _enableLoadedEvents: boolean; public _modalParent: Page; public _UIModalPresentationFormSheet: boolean; public _viewWillDisappear: boolean; - constructor(options?: definition.Options) { - super(options); - this._ios = UIViewControllerImpl.initWithOwner(new WeakRef(this)); - } - public requestLayout(): void { super.requestLayout(); if (!this.parent && this.ios && this._nativeView) { diff --git a/ui/text-base/text-base-common.ts b/ui/text-base/text-base-common.ts index 437ad603c..70e1feff4 100644 --- a/ui/text-base/text-base-common.ts +++ b/ui/text-base/text-base-common.ts @@ -48,10 +48,6 @@ export class TextBase extends view.View implements definition.TextBase, formatte public static textProperty = textProperty; public static formattedTextProperty = formattedTextProperty; - constructor(options?: definition.Options) { - super(options); - } - public _onBindingContextChanged(oldValue: any, newValue: any) { super._onBindingContextChanged(oldValue, newValue); if (this.formattedText) { diff --git a/ui/text-base/text-base.d.ts b/ui/text-base/text-base.d.ts index 4ca2ff6fc..c5bdf6fb9 100644 --- a/ui/text-base/text-base.d.ts +++ b/ui/text-base/text-base.d.ts @@ -18,8 +18,6 @@ */ public static formattedTextProperty: dependencyObservable.Property; - constructor(options?: Options); - /** * Gets or sets the text. */ @@ -53,14 +51,4 @@ _setFormattedTextPropertyToNative(value: any): void; //@endprivate } - - /** - * Defines interface for an optional parameter used to create a text-base component. - */ - export interface Options extends view.Options { - /** - * Gets or sets the text. - */ - text?: string; - } } \ No newline at end of file diff --git a/ui/text-field/text-field-common.ts b/ui/text-field/text-field-common.ts index c7606ae5c..fcd0e2dc1 100644 --- a/ui/text-field/text-field-common.ts +++ b/ui/text-field/text-field-common.ts @@ -15,10 +15,6 @@ global.moduleMerge(textBase, exports); export class TextField extends editableTextBase.EditableTextBase implements definition.TextField { public static returnPressEvent = "returnPress"; - constructor(options?: definition.Options) { - super(options); - } - get secure(): boolean { return this._getValue(secureProperty); } diff --git a/ui/text-field/text-field.d.ts b/ui/text-field/text-field.d.ts index 707f12a61..bbcc2cf33 100644 --- a/ui/text-field/text-field.d.ts +++ b/ui/text-field/text-field.d.ts @@ -10,8 +10,6 @@ declare module "ui/text-field" { export class TextField extends editableTextBase.EditableTextBase { public static returnPressEvent: string; - constructor(options?: editableTextBase.Options); - /** * Gets the native [android widget](http://developer.android.com/reference/android/widget/EditText.html) that represents the user interface for this component. Valid only when running on Android OS. */ @@ -27,14 +25,4 @@ declare module "ui/text-field" { */ secure: boolean; } - - /** - * Defines interface for an optional parameter used to create a editable-text-base component. - */ - export interface Options extends editableTextBase.Options { - /** - * Gets or sets if a text field is for password entry. - */ - secure?: boolean; - } -} +} \ No newline at end of file diff --git a/ui/text-view/text-view-common.ts b/ui/text-view/text-view-common.ts index 4e6567f95..4a8efd45e 100644 --- a/ui/text-view/text-view-common.ts +++ b/ui/text-view/text-view-common.ts @@ -5,7 +5,5 @@ import editableTextBase = require("ui/editable-text-base"); global.moduleMerge(textBase, exports); export class TextView extends editableTextBase.EditableTextBase implements definition.TextView { - constructor(options?: editableTextBase.Options) { - super(options); - } -} \ No newline at end of file + // TSLint error if empty. +} \ No newline at end of file diff --git a/ui/text-view/text-view.d.ts b/ui/text-view/text-view.d.ts index ab4e7f405..26130f622 100644 --- a/ui/text-view/text-view.d.ts +++ b/ui/text-view/text-view.d.ts @@ -2,14 +2,12 @@ * Contains the TextView class, which represents an editable multi-line line box. */ declare module "ui/text-view" { - import editableTextBase = require("ui/editable-text-base"); + import {EditableTextBase} from "ui/editable-text-base"; /** * Represents an editable multiline text view. */ - export class TextView extends editableTextBase.EditableTextBase { - constructor(options?: editableTextBase.Options); - + export class TextView extends EditableTextBase { /** * Gets the native [android widget](http://developer.android.com/reference/android/widget/EditText.html) that represents the user interface for this component. Valid only when running on Android OS. */ @@ -20,4 +18,4 @@ declare module "ui/text-view" { */ ios: any /* UITextView */; } -} +} \ No newline at end of file diff --git a/ui/time-picker/time-picker-common.ts b/ui/time-picker/time-picker-common.ts index a25338136..fcc1e2c3a 100644 --- a/ui/time-picker/time-picker-common.ts +++ b/ui/time-picker/time-picker-common.ts @@ -196,10 +196,6 @@ export class TimePicker extends view.View implements definition.TimePicker { public static timeProperty = new dependencyObservable.Property("time", "TimePicker", new proxy.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.None, onTimePropertyChanged, isValidTime)); - constructor() { - super(); - } - get hour(): number { return this._getValue(TimePicker.hourProperty); } diff --git a/ui/time-picker/time-picker.d.ts b/ui/time-picker/time-picker.d.ts index 52283b27f..ba9b079df 100644 --- a/ui/time-picker/time-picker.d.ts +++ b/ui/time-picker/time-picker.d.ts @@ -13,8 +13,6 @@ declare module "ui/time-picker" { public static minuteProperty: dependencyObservable.Property; public static timeProperty: dependencyObservable.Property; - constructor(); - /** * Gets the native [android.widget.TimePicker](http://developer.android.com/reference/android/widget/TimePicker.html) that represents the user interface for this component. Valid only when running on Android OS. */ @@ -72,4 +70,4 @@ declare module "ui/time-picker" { _setNativeMinuteIntervalTime(): void; //@endprivate } -} +} \ No newline at end of file diff --git a/ui/web-view/web-view-common.ts b/ui/web-view/web-view-common.ts index 064fd29fb..0106a176a 100644 --- a/ui/web-view/web-view-common.ts +++ b/ui/web-view/web-view-common.ts @@ -90,10 +90,6 @@ export abstract class WebView extends view.View implements definition.WebView { public _suspendLoading: boolean; - constructor() { - super(); - } - get url(): string { return this._getValue(WebView.urlProperty); }