From d371b256c9c94d06475ca4f93a44f5e5bb0f5532 Mon Sep 17 00:00:00 2001 From: danstarns Date: Sun, 4 Aug 2024 12:20:11 -0700 Subject: [PATCH] feat: data watchers --- src/data_sources/index.ts | 2 ++ src/domain_abstract/model/StyleableModel.ts | 36 +++++++++++++------- src/style_manager/model/PropertyComposite.ts | 6 ++-- test/specs/data_sources/index.ts | 9 +++-- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/data_sources/index.ts b/src/data_sources/index.ts index e248c46ea..0fbf8c503 100644 --- a/src/data_sources/index.ts +++ b/src/data_sources/index.ts @@ -6,6 +6,7 @@ import DataRecord from './model/DataRecord'; import DataSource from './model/DataSource'; import DataSources from './model/DataSources'; import { DataSourceProps, DataSourcesEvents } from './types'; +import { Events } from 'backbone'; export default class DataSourceManager extends ItemManagerModule { storageKey = ''; @@ -14,6 +15,7 @@ export default class DataSourceManager extends ItemManagerModule { export default class StyleableModel extends Model { em?: EditorModel; + dataListeners: DataVariableListener[] = []; /** * Forward style string to `parseStyle` to be parse to an object @@ -123,7 +125,7 @@ export default class StyleableModel extends Model keys(style).forEach(key => { const styleValue = style[key]; // @ts-ignore - if (typeof styleValue === 'object' && styleValue.type === 'data-variable') { + if (typeof styleValue === 'object' && styleValue.type === 'data-variable-css') { // @ts-ignore style[key] = new StyleDataVariable(styleValue, { em: this.em }); } @@ -133,26 +135,37 @@ export default class StyleableModel extends Model processDataVariableStyles(style: StyleProps) { keys(style).forEach(key => { const styleValue = style[key]; - // @ts-ignore if (styleValue instanceof StyleDataVariable) { - // @ts-ignore this.listenToDataVariable(styleValue, key); } }); } listenToDataVariable(dataVar: StyleDataVariable, styleProp: string) { - this.listenTo(dataVar, 'change:value', (model: any) => { - const newValue = model.get('value'); - this.updateStyleProp(styleProp, newValue); - }); + const { em } = this; + const { path } = dataVar.attributes; + const normPath = stringToPath(path || '').join('.'); + const dataListeners: DataVariableListener[] = []; + const prevListeners = this.dataListeners || []; + + prevListeners.forEach(ls => this.stopListening(ls.obj, ls.event, this.updateStyleProp)); + + dataListeners.push({ obj: dataVar, event: 'change:value' }); + dataListeners.push({ obj: em, event: `${DataSourcesEvents.path}:${normPath}` }); + + dataListeners.forEach(ls => + this.listenTo(ls.obj, ls.event, () => { + const newValue = em?.DataSources.getValue(normPath, dataVar.get('value')); + this.updateStyleProp(styleProp, newValue); + }) + ); + this.dataListeners = dataListeners; } updateStyleProp(prop: string, value: string) { const style = this.getStyle(); style[prop] = value; - // @ts-ignore - this.set('style', style, { noEvent: true }); + this.setStyle(style, { noEvent: true }); this.trigger(`change:style:${prop}`); } @@ -160,11 +173,8 @@ export default class StyleableModel extends Model const resolvedStyle = { ...style }; keys(resolvedStyle).forEach(key => { const styleValue = resolvedStyle[key]; - // @ts-ignore if (styleValue instanceof StyleDataVariable) { - // @ts-ignore const resolvedValue = this.em?.DataSources.getValue(styleValue.get('path'), styleValue.get('value')); - // @ts-ignore resolvedStyle[key] = resolvedValue || styleValue.get('value'); } }); diff --git a/src/style_manager/model/PropertyComposite.ts b/src/style_manager/model/PropertyComposite.ts index a9d5a0852..eea40c5ba 100644 --- a/src/style_manager/model/PropertyComposite.ts +++ b/src/style_manager/model/PropertyComposite.ts @@ -277,7 +277,7 @@ export default class PropertyComposite = PropertyC const result = this.getStyleFromProps()[this.getName()] || ''; if (result && typeof result !== 'string' && 'type' in result) { - if (result.type === 'data-variable') { + if (result.type === 'data-variable-css') { console.log('Datasources __getFullValue'); } } @@ -309,7 +309,7 @@ export default class PropertyComposite = PropertyC const value = style[name]; if (value && typeof value !== 'string' && 'type' in value) { - if (value.type === 'data-variable') { + if (value.type === 'data-variable-css') { console.log('Datasources __splitStyleName'); } } @@ -357,7 +357,7 @@ export default class PropertyComposite = PropertyC const value = style[name]; if (value && typeof value !== 'string' && 'type' in value) { - if (value.type === 'data-variable') { + if (value.type === 'data-variable-css') { console.log('Datasources __getPropsFromStyle'); } } diff --git a/test/specs/data_sources/index.ts b/test/specs/data_sources/index.ts index fbd4a2f25..55de7dfa0 100644 --- a/test/specs/data_sources/index.ts +++ b/test/specs/data_sources/index.ts @@ -53,11 +53,12 @@ describe('DataSourceManager', () => { fixtures.appendChild(wrapperEl.el); }); - test('todo', () => { + test('component initializes with data-variable style', () => { const styleDataSource: DataSourceProps = { id: 'colors-data', records: [{ id: 'id1', color: 'red' }], }; + dsm.add(styleDataSource); const cmp = cmpRoot.append({ tagName: 'h1', @@ -66,11 +67,15 @@ describe('DataSourceManager', () => { style: { color: { type: 'data-variable', - default: 'black', + value: 'black', path: 'colors-data.id1.color', }, }, })[0]; + + const el = cmp.getEl(); + console.log('el', el?.style); + expect(el?.style.color).toBe('red'); }); });