feat(core): allow property overrides at runtime (#9241)

This commit is contained in:
Nathanael Anderson
2021-02-26 18:23:18 -06:00
committed by GitHub
parent 11ef943495
commit c04e1b59e5

View File

@ -3,7 +3,7 @@ import * as reduceCSSCalc from 'reduce-css-calc';
import { ViewBase } from '../view-base'; import { ViewBase } from '../view-base';
// Types. // Types.
import { WrappedValue, PropertyChangeData } from '../../../data/observable'; import { PropertyChangeData, WrappedValue } from '../../../data/observable';
import { Trace } from '../../../trace'; import { Trace } from '../../../trace';
import { Style } from '../../styling/style'; import { Style } from '../../styling/style';
@ -11,7 +11,7 @@ import { Style } from '../../styling/style';
import { profile } from '../../../profiling'; import { profile } from '../../../profiling';
/** /**
* Value specifing that Property should be set to its initial value. * Value specifying that Property should be set to its initial value.
*/ */
export const unsetValue: any = new Object(); export const unsetValue: any = new Object();
@ -183,6 +183,7 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
public get: () => U; public get: () => U;
public set: (value: U) => void; public set: (value: U) => void;
public overrideHandlers: (options: PropertyOptions<T, U>) => void;
public enumerable = true; public enumerable = true;
public configurable = true; public configurable = true;
@ -206,10 +207,26 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
const eventName = propertyName + 'Change'; const eventName = propertyName + 'Change';
const equalityComparer = options.equalityComparer;
const affectsLayout: boolean = options.affectsLayout; let equalityComparer = options.equalityComparer;
const valueChanged = options.valueChanged; let affectsLayout: boolean = options.affectsLayout;
const valueConverter = options.valueConverter; let valueChanged = options.valueChanged;
let valueConverter = options.valueConverter;
this.overrideHandlers = function (options: PropertyOptions<T, U>) {
if (typeof options.equalityComparer !== 'undefined') {
equalityComparer = options.equalityComparer;
}
if (typeof options.affectsLayout !== 'undefined') {
affectsLayout = options.affectsLayout;
}
if (typeof options.valueChanged !== 'undefined') {
valueChanged = options.valueChanged;
}
if (typeof options.valueConverter !== 'undefined') {
valueConverter = options.valueConverter;
}
};
const property = this; const property = this;
@ -364,14 +381,32 @@ export class CoercibleProperty<T extends ViewBase, U> extends Property<T, U> imp
const coerceKey = Symbol(propertyName + ':coerceKey'); const coerceKey = Symbol(propertyName + ':coerceKey');
const eventName = propertyName + 'Change'; const eventName = propertyName + 'Change';
const affectsLayout: boolean = options.affectsLayout; let affectsLayout: boolean = options.affectsLayout;
const equalityComparer = options.equalityComparer; let equalityComparer = options.equalityComparer;
const valueChanged = options.valueChanged; let valueChanged = options.valueChanged;
const valueConverter = options.valueConverter; let valueConverter = options.valueConverter;
const coerceCallback = options.coerceValue; let coerceCallback = options.coerceValue;
const property = this; const property = this;
this.overrideHandlers = function (options: CoerciblePropertyOptions<T, U>) {
if (typeof options.equalityComparer !== 'undefined') {
equalityComparer = options.equalityComparer;
}
if (typeof options.affectsLayout !== 'undefined') {
affectsLayout = options.affectsLayout;
}
if (typeof options.valueChanged !== 'undefined') {
valueChanged = options.valueChanged;
}
if (typeof options.valueConverter !== 'undefined') {
valueConverter = options.valueConverter;
}
if (typeof options.coerceValue !== 'undefined') {
coerceCallback = options.coerceValue;
}
};
this.coerce = function (target: T): void { this.coerce = function (target: T): void {
const originalValue: U = coerceKey in target ? target[coerceKey] : defaultValue; const originalValue: U = coerceKey in target ? target[coerceKey] : defaultValue;
// need that to make coercing but also fire change events // need that to make coercing but also fire change events
@ -559,6 +594,8 @@ export class CssProperty<T extends Style, U> implements CssProperty<T, U> {
public readonly defaultValueKey: symbol; public readonly defaultValueKey: symbol;
public readonly defaultValue: U; public readonly defaultValue: U;
public overrideHandlers: (options: CssPropertyOptions<T, U>) => void;
constructor(options: CssPropertyOptions<T, U>) { constructor(options: CssPropertyOptions<T, U>) {
const propertyName = options.name; const propertyName = options.name;
this.name = propertyName; this.name = propertyName;
@ -587,10 +624,25 @@ export class CssProperty<T extends Style, U> implements CssProperty<T, U> {
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
const eventName = propertyName + 'Change'; const eventName = propertyName + 'Change';
const affectsLayout: boolean = options.affectsLayout; let affectsLayout: boolean = options.affectsLayout;
const equalityComparer = options.equalityComparer; let equalityComparer = options.equalityComparer;
const valueChanged = options.valueChanged; let valueChanged = options.valueChanged;
const valueConverter = options.valueConverter; let valueConverter = options.valueConverter;
this.overrideHandlers = function (options: CssPropertyOptions<T, U>) {
if (typeof options.equalityComparer !== 'undefined') {
equalityComparer = options.equalityComparer;
}
if (typeof options.affectsLayout !== 'undefined') {
affectsLayout = options.affectsLayout;
}
if (typeof options.valueChanged !== 'undefined') {
valueChanged = options.valueChanged;
}
if (typeof options.valueConverter !== 'undefined') {
valueConverter = options.valueConverter;
}
};
const property = this; const property = this;
@ -1015,6 +1067,7 @@ CssAnimationProperty.prototype.isStyleProperty = true;
export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U> implements InheritedCssProperty<T, U> { export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U> implements InheritedCssProperty<T, U> {
public setInheritedValue: (value: U) => void; public setInheritedValue: (value: U) => void;
public overrideHandlers: (options: CssPropertyOptions<T, U>) => void;
constructor(options: CssPropertyOptions<T, U>) { constructor(options: CssPropertyOptions<T, U>) {
super(options); super(options);
@ -1027,14 +1080,29 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
const defaultValueKey = this.defaultValueKey; const defaultValueKey = this.defaultValueKey;
const eventName = propertyName + 'Change'; const eventName = propertyName + 'Change';
const defaultValue: U = options.defaultValue; let defaultValue: U = options.defaultValue;
const affectsLayout: boolean = options.affectsLayout; let affectsLayout: boolean = options.affectsLayout;
const equalityComparer = options.equalityComparer; let equalityComparer = options.equalityComparer;
const valueChanged = options.valueChanged; let valueChanged = options.valueChanged;
const valueConverter = options.valueConverter; let valueConverter = options.valueConverter;
const property = this; const property = this;
this.overrideHandlers = function (options: CssPropertyOptions<T, U>) {
if (typeof options.equalityComparer !== 'undefined') {
equalityComparer = options.equalityComparer;
}
if (typeof options.affectsLayout !== 'undefined') {
affectsLayout = options.affectsLayout;
}
if (typeof options.valueChanged !== 'undefined') {
valueChanged = options.valueChanged;
}
if (typeof options.valueConverter !== 'undefined') {
valueConverter = options.valueConverter;
}
};
const setFunc = (valueSource: ValueSource) => const setFunc = (valueSource: ValueSource) =>
function (this: T, boxedValue: any): void { function (this: T, boxedValue: any): void {
const view = this.viewRef.get(); const view = this.viewRef.get();