Improve Binding class (#2038)

Remove options parameter
This commit is contained in:
Hristo Hristov
2016-04-27 16:43:45 +03:00
parent 264fe170a9
commit b2c182fd7a
47 changed files with 325 additions and 654 deletions

View File

@@ -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 () {

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -33,7 +33,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
// >> 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() {

View File

@@ -21,7 +21,9 @@ function _createSegmentedBar(): segmentedBarModule.SegmentedBar {
function _createItems(count: number): Array<segmentedBarModule.SegmentedBarItem> {
var items = new Array<segmentedBarModule.SegmentedBarItem>();
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;
}

View File

@@ -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<viewModule.View>) {
var page = <pageModule.Page>views[1];

View File

@@ -21,10 +21,9 @@ function _createItems(count: number): Array<TabViewItem> {
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);
}

View File

@@ -25,10 +25,9 @@ export class TabViewTest extends testModule.UITest<tabViewModule.TabView> {
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<tabViewModule.TabView> {
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<tabViewModule.TabView> {
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<tabViewModule.TabView> {
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.");
}

View File

@@ -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.

View File

@@ -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;
}
}

View File

@@ -77,4 +77,4 @@ declare module "ui/button" {
_setFormattedTextPropertyToNative(value: any): void;
//@endprivate
}
}
}

View File

@@ -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 = <Bindable>data.object;
function onBindingContextChanged(data: DependencyPropertyChangeData) {
let bindable = <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<string, Binding>();
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<Object>;
target: WeakRef<Bindable>;
let emptyArray = [];
function getProperties(property: string): Array<string> {
let result: Array<string> = 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<any>; property: any };
private targetOptions: { instance: WeakRef<any>; property: any };
export class Binding {
private source: WeakRef<Object>;
public target: WeakRef<Bindable>;
private sourcePropertiesArray: Array<string>;
private sourceOptions: { instance: WeakRef<any>; property: string };
private targetOptions: { instance: WeakRef<any>; property: string };
private sourcesAndProperties: Array<{ instance: Object; property: string }>;
private propertyChangeListeners: Map<string, Observable> = new Map<string, Observable>();
private sourceProperties: Array<string>;
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<string> {
if (!this.sourcePropertiesArray) {
this.sourcePropertiesArray = Binding.getProperties(this.options.sourceProperty);
}
return this.sourcePropertiesArray;
}
private static getProperties(property: string): Array<string> {
var result: Array<string>;
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<string>) {
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<string>): 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<Object>, sourceProperty: Array<string>, 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((<Error>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((<Error>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((<Error>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((<Error>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<any>, properties: Array<string>): { instance: any; property: any } {
var objectsAndProperties = this.resolveObjectsAndProperties(obj.get(), properties);
private resolveOptions(obj: Object, properties: Array<string>): { instance: WeakRef<Object>; 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<any>; property: any }, value: any) {
var optionsInstance;
private updateOptions(options: { instance: WeakRef<any>; 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;
}
}
}

View File

@@ -263,7 +263,7 @@ export class PropertyEntry implements definition.PropertyEntry {
var defaultValueForPropertyPerType: Map<string, any> = new Map<string, any>();
export class DependencyObservable extends Observable {
export class DependencyObservable extends Observable implements definition.DependencyObservable {
private _propertyEntries = {};
public set(name: string, value: any) {

View File

@@ -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++;

View File

@@ -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");

64
ui/core/view.d.ts vendored
View File

@@ -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----------
/**

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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() {
(<UIResponder>this.ios).resignFirstResponder();
}

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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);
}

22
ui/image/image.d.ts vendored
View File

@@ -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;
}
}
}

View File

@@ -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();

View File

@@ -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);
}

20
ui/label/label.d.ts vendored
View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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;
}

31
ui/page/page.d.ts vendored
View File

@@ -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;
}
}
}

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
// TSLint error if empty.
}

View File

@@ -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 */;
}
}
}

View File

@@ -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);
}

View File

@@ -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
}
}
}

View File

@@ -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);
}