@@ -2,6 +2,7 @@ import { unsetValue } from "ui/core/dependency-observable";
22import { WrappedValue } from "data/observable" ;
33import { ViewBase } from "./view-base" ;
44import { Style } from "ui/styling/style" ;
5+ import * as definitions from "ui/core/view-base" ;
56
67export { unsetValue , Style } ;
78
@@ -31,44 +32,21 @@ const enum ValueSource {
3132 Local = 3
3233}
3334
34- export interface PropertyOptions < T , U > {
35- name : string ;
36- defaultValue ?: U ;
37- affectsLayout ?: boolean ;
38- equalityComparer ?( this : void , x : U , y : U ) : boolean ;
39- valueChanged ?( this : void , target : T , oldValue : U , newValue : U ) : void ;
40- valueConverter ?( this : void , value : string ) : U ;
41- }
42-
43- export interface CoerciblePropertyOptions < T , U > extends PropertyOptions < T , U > {
44- readonly coerceValue : ( t : T , u : U ) => U ;
45- }
46-
47- export interface ShorthandPropertyOptions < P > {
48- name : string ;
49- cssName : string ;
50- converter ( this : void , value : string | P ) : [ CssProperty < any , any > , any ] [ ] ;
51- getter ( this : Style ) : string | P ;
52- }
53-
54- export interface CssPropertyOptions < T extends Style , U > extends PropertyOptions < T , U > {
55- cssName : string ;
56- }
57-
58- export class Property < T extends ViewBase , U > implements PropertyDescriptor {
35+ export class Property < T extends ViewBase , U > implements PropertyDescriptor , definitions . Property < T , U > {
5936 private registered : boolean ;
6037 private readonly name : string ;
6138 public readonly key : symbol ;
6239 public readonly native : symbol ;
6340 public readonly defaultValueKey : symbol ;
6441 public readonly defaultValue : U ;
42+ public readonly nativeValueChange : ( owner : T , value : U ) => void ;
6543
6644 public get : ( ) => U ;
6745 public set : ( value : U ) => void ;
6846 public enumerable : boolean = true ;
6947 public configurable : boolean = true ;
7048
71- constructor ( options : PropertyOptions < T , U > ) {
49+ constructor ( options : definitions . PropertyOptions < T , U > ) {
7250 const name = options . name ;
7351 this . name = name ;
7452
@@ -85,12 +63,12 @@ export class Property<T extends ViewBase, U> implements PropertyDescriptor {
8563 this . defaultValue = defaultValue ;
8664
8765 const eventName = name + "Change" ;
88- const affectsLayout : boolean = options . affectsLayout ;
8966 const equalityComparer = options . equalityComparer ;
67+ const affectsLayout : boolean = options . affectsLayout ;
9068 const valueChanged = options . valueChanged ;
9169 const valueConverter = options . valueConverter ;
9270
93- this . set = function ( this : T , value : any ) : void {
71+ this . set = function ( this : T , value : U ) : void {
9472 const reset = value === unsetValue ;
9573 let unboxedValue : U ;
9674 let wrapped : boolean ;
@@ -146,10 +124,34 @@ export class Property<T extends ViewBase, U> implements PropertyDescriptor {
146124 }
147125 }
148126
149- this . get = function ( ) : U {
127+ this . get = function ( this : T ) : U {
150128 return key in this ? this [ key ] : defaultValue ;
151129 }
152130
131+ this . nativeValueChange = function ( owner : T , value : U ) : void {
132+ const currentValue = key in owner ? owner [ key ] : defaultValue ;
133+ const changed = equalityComparer ? ! equalityComparer ( currentValue , value ) : currentValue !== value ;
134+ if ( changed ) {
135+ owner [ key ] = value ;
136+ if ( valueChanged ) {
137+ valueChanged ( owner , currentValue , value ) ;
138+ }
139+
140+ if ( owner . hasListeners ( eventName ) ) {
141+ owner . notify ( {
142+ eventName : eventName ,
143+ propertyName : name ,
144+ object : owner ,
145+ value : value
146+ } ) ;
147+ }
148+
149+ if ( affectsLayout ) {
150+ owner . requestLayout ( ) ;
151+ }
152+ }
153+ }
154+
153155 symbolPropertyMap [ key ] = this ;
154156 }
155157
@@ -162,13 +164,14 @@ export class Property<T extends ViewBase, U> implements PropertyDescriptor {
162164 }
163165}
164166
165- export class CoercibleProperty < T extends ViewBase , U > implements PropertyDescriptor {
167+ export class CoercibleProperty < T extends ViewBase , U > implements PropertyDescriptor , definitions . CoercibleProperty < T , U > {
166168 private registered : boolean ;
167169 private readonly name : string ;
168170 public readonly key : symbol ;
169171 public readonly native : symbol ;
170172 public readonly defaultValueKey : symbol ;
171173 public readonly defaultValue : U ;
174+ public readonly nativeValueChange : ( owner : T , value : U ) => void ;
172175
173176 public readonly get : ( ) => U ;
174177 public readonly set : ( value : U ) => void ;
@@ -177,7 +180,7 @@ export class CoercibleProperty<T extends ViewBase, U> implements PropertyDescrip
177180
178181 public readonly coerce : ( target : T ) => void ;
179182
180- constructor ( options : CoerciblePropertyOptions < T , U > ) {
183+ constructor ( options : definitions . CoerciblePropertyOptions < T , U > ) {
181184 const name = options . name ;
182185 this . name = name ;
183186
@@ -272,6 +275,31 @@ export class CoercibleProperty<T extends ViewBase, U> implements PropertyDescrip
272275 return key in this ? this [ key ] : defaultValue ;
273276 }
274277
278+ this . nativeValueChange = function ( owner : T , value : U ) : void {
279+ const currentValue = key in owner ? owner [ key ] : defaultValue ;
280+ const changed = equalityComparer ? ! equalityComparer ( currentValue , value ) : currentValue !== value ;
281+ if ( changed ) {
282+ owner [ key ] = value ;
283+ owner [ coerceKey ] = value ;
284+ if ( valueChanged ) {
285+ valueChanged ( owner , currentValue , value ) ;
286+ }
287+
288+ if ( owner . hasListeners ( eventName ) ) {
289+ owner . notify ( {
290+ eventName : eventName ,
291+ propertyName : name ,
292+ object : owner ,
293+ value : value
294+ } ) ;
295+ }
296+
297+ if ( affectsLayout ) {
298+ owner . requestLayout ( ) ;
299+ }
300+ }
301+ }
302+
275303 symbolPropertyMap [ key ] = this ;
276304 }
277305
@@ -284,11 +312,11 @@ export class CoercibleProperty<T extends ViewBase, U> implements PropertyDescrip
284312 }
285313}
286314
287- export class InheritedProperty < T extends ViewBase , U > extends Property < T , U > {
315+ export class InheritedProperty < T extends ViewBase , U > extends Property < T , U > implements definitions . InheritedProperty < T , U > {
288316 public readonly sourceKey : symbol ;
289317 public readonly setInheritedValue : ( value : U ) => void ;
290318
291- constructor ( options : PropertyOptions < T , U > ) {
319+ constructor ( options : definitions . PropertyOptions < T , U > ) {
292320 super ( options ) ;
293321 const name = options . name ;
294322 const key = this . key ;
@@ -369,7 +397,7 @@ export class InheritedProperty<T extends ViewBase, U> extends Property<T, U> {
369397 }
370398}
371399
372- export class CssProperty < T extends Style , U > {
400+ export class CssProperty < T extends Style , U > implements definitions . CssProperty < T , U > {
373401 private registered : boolean ;
374402
375403 public readonly name : string ;
@@ -384,7 +412,7 @@ export class CssProperty<T extends Style, U> {
384412 public readonly defaultValueKey : symbol ;
385413 public readonly defaultValue : U ;
386414
387- constructor ( options : CssPropertyOptions < T , U > ) {
415+ constructor ( options : definitions . CssPropertyOptions < T , U > ) {
388416 const name = options . name ;
389417 this . name = name ;
390418
@@ -559,10 +587,10 @@ export class CssProperty<T extends Style, U> {
559587 }
560588}
561589
562- export class InheritedCssProperty < T extends Style , U > extends CssProperty < T , U > {
590+ export class InheritedCssProperty < T extends Style , U > extends CssProperty < T , U > implements definitions . InheritedCssProperty < T , U > {
563591 public setInheritedValue : ( value : U ) => void ;
564592
565- constructor ( options : CssPropertyOptions < T , U > ) {
593+ constructor ( options : definitions . CssPropertyOptions < T , U > ) {
566594 super ( options ) ;
567595 const name = options . name ;
568596
@@ -684,7 +712,7 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
684712 }
685713}
686714
687- export class ShorthandProperty < T extends Style , P > {
715+ export class ShorthandProperty < T extends Style , P > implements definitions . ShorthandProperty < T , P > {
688716 private registered : boolean ;
689717
690718 public readonly key : symbol ;
@@ -697,7 +725,7 @@ export class ShorthandProperty<T extends Style, P> {
697725 public readonly native : symbol ;
698726 public readonly sourceKey : symbol ;
699727
700- constructor ( options : ShorthandPropertyOptions < P > ) {
728+ constructor ( options : definitions . ShorthandPropertyOptions < P > ) {
701729 const name = options . name ;
702730 this . name = name ;
703731
@@ -712,7 +740,7 @@ export class ShorthandProperty<T extends Style, P> {
712740
713741 const converter = options . converter ;
714742
715- function setLocalValue ( this : T , value : string | P ) : void {
743+ function setLocalValue ( this : T , value : string | P ) : void {
716744 this [ sourceKey ] = ValueSource . Local ;
717745 if ( this [ key ] !== value ) {
718746 this [ key ] = value ;
0 commit comments