From fc0048c4a10f5cb9b536a8c9999c34f5ff6a393c Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Mon, 15 Aug 2016 15:14:03 +0300 Subject: [PATCH] dependency-observable changes (#2584) * Improved es6.d.ts Small perf improvement in resetValues * Fix tslint errors * Removed all comments from es6.d.ts (TSLint hell) --- tns-core-modules/es6.d.ts | 13 ++- .../ui/core/dependency-observable.d.ts | 1 + .../ui/core/dependency-observable.ts | 103 ++++++++---------- tns-core-modules/ui/core/view-common.ts | 10 +- tns-core-modules/ui/styling/style.ts | 23 +--- 5 files changed, 68 insertions(+), 82 deletions(-) diff --git a/tns-core-modules/es6.d.ts b/tns-core-modules/es6.d.ts index 0c7324ccf..6ddafcc38 100644 --- a/tns-core-modules/es6.d.ts +++ b/tns-core-modules/es6.d.ts @@ -1,9 +1,20 @@ -declare var Symbol: any; +interface Symbol { + toString(): string; + valueOf(): Object; +} + +interface SymbolConstructor { + prototype: Symbol; + (description?: string | number): symbol; +} + +declare var Symbol: SymbolConstructor; interface ObjectConstructor { assign(target: any, ...sources: any[]): any; is(value1: any, value2: any): boolean; setPrototypeOf(o: any, proto: any): any; + getOwnPropertySymbols(o: any): symbol[]; } declare var Object: ObjectConstructor; \ No newline at end of file diff --git a/tns-core-modules/ui/core/dependency-observable.d.ts b/tns-core-modules/ui/core/dependency-observable.d.ts index 9d23b976c..130b4acff 100644 --- a/tns-core-modules/ui/core/dependency-observable.d.ts +++ b/tns-core-modules/ui/core/dependency-observable.d.ts @@ -243,6 +243,7 @@ declare module "ui/core/dependency-observable" { /** * Iterates all the properties which have a PropertyEntry registered for this instance. */ + _resetValues(valueSource: number): void; _eachSetProperty(callback: (property: Property) => boolean): void; _eachSetPropertyValue(callback: (property: Property, value: any) => void): void; //@endprivate diff --git a/tns-core-modules/ui/core/dependency-observable.ts b/tns-core-modules/ui/core/dependency-observable.ts index 0974bc004..1cf135dbc 100644 --- a/tns-core-modules/ui/core/dependency-observable.ts +++ b/tns-core-modules/ui/core/dependency-observable.ts @@ -77,40 +77,23 @@ export class PropertyMetadata implements definition.PropertyMetadata { } } -// function property(property: Property): PropertyDecorator { -// function _getValue() { -// return this._getValue(property); -// } - -// function _setValue(value: any) { -// this._setValueInternal(property, value, ValueSource.Local); -// } - -// return (target: Object, propertyKey: string) => { -// Object.defineProperty(target, propertyKey, { -// get: _getValue, -// set: _setValue, -// enumerable: true, -// configurable: true -// }); -// }; -// } - export class Property implements definition.Property { public key: string; + public id: number; public defaultValue; - public onValidateValue; public equalityComparer; public inheritable; public affectsStyle; public affectsLayout; - public onValueChanged: definition.PropertyChangedCallback; public nameEvent: string; + + public onValidateValue; + public onValueChanged: definition.PropertyChangedCallback; + constructor(public name: string, public ownerType: string, public metadata: PropertyMetadata, public valueConverter?: (value: string) => any) { // register key this.key = generatePropertyKey(name, ownerType, true); - if (propertyFromKey[this.key]) { throw new Error("Property " + name + " already registered for type " + ownerType + "."); } @@ -150,7 +133,6 @@ export class PropertyEntry implements definition.PropertyEntry { public visualStateValue: any; constructor(public property: Property) { - this.property = property; } public resetValue() { @@ -159,8 +141,6 @@ export class PropertyEntry implements definition.PropertyEntry { } } -var defaultValueForPropertyPerType: Map = new Map(); - export class DependencyObservable extends Observable implements definition.DependencyObservable { private _propertyEntries = {}; @@ -206,17 +186,15 @@ export class DependencyObservable extends Observable implements definition.Depen } private _getDefaultValue(property: Property): any { - if (property.defaultValueGetter) { // we check for cached properties only for these which have 'defaultValueGetter' defined; + if (property.defaultValueGetter) { + // we check for cached properties only for these which have 'defaultValueGetter' defined; // When DependencyProperties are removed from Style - fix this check. - var view = (this)._view || this; - let key = types.getClass(view) + "." + property.id; - let defaultValue = defaultValueForPropertyPerType.get(key); - if (!defaultValueForPropertyPerType.has(key) && view._nativeView) { - let defaultValueResult = property.defaultValueGetter(this); - defaultValue = defaultValueResult.result; - if (defaultValueResult.cacheable) { - defaultValueForPropertyPerType.set(key, defaultValue); - } + let defaultValueResult = property.defaultValueGetter(this); + let defaultValue = defaultValueResult.result; + if (defaultValueResult.cacheable) { + let entry = new PropertyEntry(property); + entry.effectiveValue = defaultValue; + this._propertyEntries[property.id] = entry; } return defaultValue; @@ -225,13 +203,25 @@ export class DependencyObservable extends Observable implements definition.Depen return property.defaultValue; } - public _resetValue(property: Property, source: number = ValueSource.Local) { + public _resetValues(valueSource: number): void { + for (let i = 0, keys = Object.keys(this._propertyEntries); i < keys.length; i++) { + let key = keys[i]; + let entry: PropertyEntry = this._propertyEntries[key]; + this._resetValueInternal(entry.property, entry, valueSource); + } + } + + public _resetValue(property: Property, valueSource: number = ValueSource.Local): void { let entry: PropertyEntry = this._propertyEntries[property.id]; if (!entry) { return; } - switch (source) { + this._resetValueInternal(property, entry, valueSource); + } + + private _resetValueInternal(property: Property, entry: PropertyEntry, valueSource: number): void { + switch (valueSource) { case ValueSource.Inherited: entry.inheritedValue = undefined; break; @@ -247,7 +237,7 @@ export class DependencyObservable extends Observable implements definition.Depen } let currentValueSource = entry.valueSource; - if (currentValueSource !== source) { + if (currentValueSource !== valueSource) { // If current valueSource is larget than the one we reset - do nothing. // We are reseting property will lower priority and it won't change effectValue; // Reseting larger source means we somehow was able to set value without updating currentValueSource which is clearly a bug. @@ -255,15 +245,15 @@ export class DependencyObservable extends Observable implements definition.Depen } let currentValue = entry.effectiveValue; - let newValue = this.getEffectiveValue(currentValueSource, entry, property); + let newValue = this.getEffectiveValueAndUpdateEntry(currentValueSource, entry, property); if (!property.equalityComparer(currentValue, newValue)) { - // If we fallback to defalutValue - remove propertyEntry. - if (entry.valueSource === ValueSource.Default) { - delete this._propertyEntries[property.id]; - } - else { - entry.effectiveValue = newValue; - } + // // If we fallback to defalutValue - remove propertyEntry. + // if (entry.valueSource === ValueSource.Default) { + // delete this._propertyEntries[property.id]; + // } + // else { + entry.effectiveValue = newValue; + // } this._onPropertyChanged(property, currentValue, newValue); } @@ -314,7 +304,9 @@ export class DependencyObservable extends Observable implements definition.Depen for (let i = 0, keys = Object.keys(this._propertyEntries); i < keys.length; i++) { let key = keys[i]; let entry: PropertyEntry = this._propertyEntries[key]; - callback(entry.property, entry.effectiveValue); + if (!callback(entry.property, entry.effectiveValue)) { + break; + } } } @@ -345,28 +337,25 @@ export class DependencyObservable extends Observable implements definition.Depen let currentValue; if (!entry) { entry = new PropertyEntry(property); + entry.effectiveValue = this._getDefaultValue(property); this._propertyEntries[property.id] = entry; - currentValue = this._getDefaultValue(property); - // In rare case when we set local value equal to default value we need to update effectiveValue as well. - // Otherwise effectiveValue will stay undefined. - if (property.equalityComparer(currentValue, realValue)) { - entry.effectiveValue = realValue; - } - } - else { - currentValue = entry.effectiveValue; } + currentValue = entry.effectiveValue; + switch (source) { case ValueSource.Inherited: entry.inheritedValue = realValue; break; + case ValueSource.Css: entry.cssValue = realValue; break; + case ValueSource.Local: entry.localValue = realValue; break; + case ValueSource.VisualState: entry.visualStateValue = realValue; break; @@ -386,7 +375,7 @@ export class DependencyObservable extends Observable implements definition.Depen } } - private getEffectiveValue(currentValueSource: number, entry: PropertyEntry, property: Property): any { + private getEffectiveValueAndUpdateEntry(currentValueSource: number, entry: PropertyEntry, property: Property): any { let newValue: any; switch (currentValueSource) { case ValueSource.Inherited: diff --git a/tns-core-modules/ui/core/view-common.ts b/tns-core-modules/ui/core/view-common.ts index ec99314d9..20e31d668 100644 --- a/tns-core-modules/ui/core/view-common.ts +++ b/tns-core-modules/ui/core/view-common.ts @@ -1061,10 +1061,14 @@ export class View extends ProxyObject implements definition.View { view.onUnloaded(); } - view._setValue(ProxyObject.bindingContextProperty, undefined, ValueSource.Inherited); - view._eachSetProperty((property) => { + view.unsetInheritedProperties(); + } + + public unsetInheritedProperties(): void { + this._setValue(ProxyObject.bindingContextProperty, undefined, ValueSource.Inherited); + this._eachSetProperty((property) => { if (!(property instanceof styling.Property) && property.inheritable) { - view._resetValue(property, ValueSource.Inherited); + this._resetValue(property, ValueSource.Inherited); } return true; }); diff --git a/tns-core-modules/ui/styling/style.ts b/tns-core-modules/ui/styling/style.ts index 5a32ac9e7..06b5ad72a 100644 --- a/tns-core-modules/ui/styling/style.ts +++ b/tns-core-modules/ui/styling/style.ts @@ -891,20 +891,11 @@ export class Style extends DependencyObservable implements styling.Style { public _resetCssValues() { this._view._unregisterAllAnimations(); - - const that = this; - this._eachSetProperty(function (property: Property) { - that._resetValue(property, ValueSource.Css); - return true; - }); + this._resetValues(ValueSource.Css); } public _resetLocalValues() { - const that = this; - this._eachSetProperty(function (property: Property) { - that._resetValue(property); - return true; - }); + this._resetValues(ValueSource.Local); } public _inheritStyleProperties(parent: View) { @@ -918,16 +909,6 @@ export class Style extends DependencyObservable implements styling.Style { }); } - // public _inheritStyleProperty(property: Property, value: any) { - // // let currentParent = this._view.parent; - // // if (currentParent) { - // // let valueSource = currentParent.style._getValueSource(property); - // // if (valueSource > ValueSource.Default) { - // this._setValue(property, value, ValueSource.Inherited); - // // } - // // } - // } - public _onPropertyChanged(property: Property, oldValue: any, newValue: any) { if (trace.enabled) { trace.write(