From 510f88d6d23d2d9da7ec4b6cfe41bcf166b9c34c Mon Sep 17 00:00:00 2001 From: LastLeaf Date: Fri, 8 Sep 2023 16:14:10 +0800 Subject: [PATCH 1/4] feat: add warning when `value` and `default` are both given in one property (#66) --- glass-easel/src/behavior.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/glass-easel/src/behavior.ts b/glass-easel/src/behavior.ts index 2274d1f..5a8a0e9 100644 --- a/glass-easel/src/behavior.ts +++ b/glass-easel/src/behavior.ts @@ -1467,6 +1467,10 @@ export class Behavior< else if (type === NormalizedPropertyType.Boolean) value = false else if (type === NormalizedPropertyType.Array) value = [] else value = null + } else if (propDef.default !== undefined) { + triggerWarning( + `the initial value of property "${name}" is not used when its default is provided (when preparing behavior "${is}").`, + ) } let observer: ((newValue: any, oldValue: any) => void) | null if (typeof propDef.observer === 'function') { From 1c42811e9a1878865bb5dd1bc7f2b8fb8b2f9b7a Mon Sep 17 00:00:00 2001 From: LastLeaf Date: Fri, 8 Sep 2023 16:37:19 +0800 Subject: [PATCH 2/4] feat: add warning when `value` and `default` are both given in one property (#66) --- glass-easel/tests/core/behavior.test.ts | 1 - glass-easel/tests/legacy/component.test.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/glass-easel/tests/core/behavior.test.ts b/glass-easel/tests/core/behavior.test.ts index b178f76..25bef99 100644 --- a/glass-easel/tests/core/behavior.test.ts +++ b/glass-easel/tests/core/behavior.test.ts @@ -223,7 +223,6 @@ describe('chaining-form interface', () => { .define() .property('propA', { type: Number, - value: 123, default: () => 456, }) .observer('propA', () => { diff --git a/glass-easel/tests/legacy/component.test.js b/glass-easel/tests/legacy/component.test.js index fc7d52c..caaab74 100644 --- a/glass-easel/tests/legacy/component.test.js +++ b/glass-easel/tests/legacy/component.test.js @@ -235,14 +235,12 @@ describe('Component', function () { properties: { a: { type: String, - value: 'abc', default: function () { return 'def' }, }, b: { type: Number, - value: 123, default: function () { return 456 }, From dfca865358f0ba26e04151e65a61ef10409b143a Mon Sep 17 00:00:00 2001 From: LastLeaf Date: Fri, 8 Sep 2023 17:58:58 +0800 Subject: [PATCH 3/4] test: add function call cases --- glass-easel/tests/tmpl/expression.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/glass-easel/tests/tmpl/expression.test.ts b/glass-easel/tests/tmpl/expression.test.ts index 77bd870..98fc6d8 100644 --- a/glass-easel/tests/tmpl/expression.test.ts +++ b/glass-easel/tests/tmpl/expression.test.ts @@ -438,4 +438,21 @@ describe('binding expression', () => { elem.setData({ c: 0 }) expect(eA.dataset.a).toEqual(100) }) + + test('function call', () => { + const def = glassEasel.registerElement({ + template: tmpl(` +
+ `), + data: { + a: 2, + f: (a: number, b: number) => a + b, + }, + }) + const elem = glassEasel.createElement('root', def.general()) + const n1 = elem.getShadowRoot()!.getElementById('n1')! + expect(n1.dataset.a).toEqual(3) + elem.setData({ a: 10 }) + expect(n1.dataset.a).toEqual(11) + }) }) From 64ca32697c352b2b9eb7d285cf315d214414db62 Mon Sep 17 00:00:00 2001 From: LastLeaf Date: Fri, 8 Sep 2023 18:53:55 +0800 Subject: [PATCH 4/4] feat: better property comparer (#57) --- glass-easel/src/data_proxy.ts | 15 ++++++++++++--- glass-easel/tests/core/data_update.test.ts | 12 ++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/glass-easel/src/data_proxy.ts b/glass-easel/src/data_proxy.ts index 77c01a8..6cc8860 100644 --- a/glass-easel/src/data_proxy.ts +++ b/glass-easel/src/data_proxy.ts @@ -346,7 +346,6 @@ export class DataGroup< data = simpleDeepCopy(newData) } } - if (prop.comparer && !prop.comparer(data, this.data[propName])) return false this._$pendingChanges.push([[propName], data, undefined, undefined]) return true } @@ -418,6 +417,7 @@ export class DataGroup< const propName = String(path[0]) const excluded = pureDataPattern ? pureDataPattern.test(propName) : false const prop: PropertyDefinition | undefined = propFields[propName] + let changed = true if (prop && path.length === 1) { // do update for 1-level fields const oldData: unknown = this.data[propName] @@ -489,7 +489,16 @@ export class DataGroup< } } } - if (!excluded && oldData !== filteredData) { + changed = prop.comparer + ? !!safeCallback( + 'Property Comparer', + prop.comparer, + comp!, + [newData, oldData], + comp?.general(), + ) + : oldData !== filteredData + if (!excluded && changed) { propChanges.push({ propName, prop, @@ -605,7 +614,7 @@ export class DataGroup< } } markTriggerBitOnPath(this._$observerTree, this._$observerStatus, path) - if (!excluded) { + if (!excluded && changed) { combinedChanges.push(change) } if (this._$doingUpdates) { diff --git a/glass-easel/tests/core/data_update.test.ts b/glass-easel/tests/core/data_update.test.ts index 620cc7d..39c49b3 100644 --- a/glass-easel/tests/core/data_update.test.ts +++ b/glass-easel/tests/core/data_update.test.ts @@ -536,6 +536,7 @@ describe('partial update', () => { comparer(newValue, oldValue) { execArr.push('A') if (newValue === 'abc') return false + if (newValue === 'ghi') return true return newValue !== oldValue }, observer() { @@ -561,19 +562,22 @@ describe('partial update', () => { })) .registerComponent() const comp = glassEasel.Component.createWithContext('root', compDef, domBackend) - expect(execArr).toStrictEqual(['A']) + expect(execArr).toStrictEqual(['A', 'B']) execArr = [] glassEasel.Element.pretendAttached(comp) comp.setData({ p: '' }) expect(execArr).toStrictEqual(['A', 'B', 'C']) execArr = [] comp.setData({ p: 'abc' }) - expect(execArr).toStrictEqual(['A']) + expect(execArr).toStrictEqual(['A', 'B']) execArr = [] comp.setData({ p: '' }) - expect(execArr).toStrictEqual(['A']) + expect(execArr).toStrictEqual(['A', 'B', 'C']) + execArr = [] + comp.setData({ p: 'ghi' }) + expect(execArr).toStrictEqual(['A', 'B', 'C']) execArr = [] - comp.setData({ p: 'def' }) + comp.setData({ p: 'ghi' }) expect(execArr).toStrictEqual(['A', 'B', 'C']) })