diff --git a/packages/core/src/css_composer/model/CssRule.ts b/packages/core/src/css_composer/model/CssRule.ts index 2516e5b9df..d90a0d3f13 100644 --- a/packages/core/src/css_composer/model/CssRule.ts +++ b/packages/core/src/css_composer/model/CssRule.ts @@ -7,7 +7,7 @@ import { isEmptyObj, hasWin } from '../../utils/mixins'; import Selector, { SelectorProps } from '../../selector_manager/model/Selector'; import EditorModel from '../../editor/model/Editor'; import CssRuleView from '../view/CssRuleView'; -import DataVariableListenerManager from '../../data_sources/model/DataVariableListenerManager'; +import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager'; /** @private */ export interface CssRuleProperties { @@ -95,7 +95,7 @@ export default class CssRule extends StyleableModel { em?: EditorModel; opt: any; views: CssRuleView[] = []; - dataVariableListeners: Record = {}; + dynamicVariableListeners: Record = {}; defaults() { return { diff --git a/packages/core/src/data_sources/model/DataVariableListenerManager.ts b/packages/core/src/data_sources/model/DataVariableListenerManager.ts index 5e0ee8c4ab..e2941b523b 100644 --- a/packages/core/src/data_sources/model/DataVariableListenerManager.ts +++ b/packages/core/src/data_sources/model/DataVariableListenerManager.ts @@ -2,47 +2,59 @@ import { DataSourcesEvents, DataVariableListener } from '../types'; import { stringToPath } from '../../utils/mixins'; import { Model } from '../../common'; import EditorModel from '../../editor/model/Editor'; -import DataVariable from './DataVariable'; +import DataVariable, { DataVariableType } from './DataVariable'; import ComponentView from '../../dom_components/view/ComponentView'; import ComponentDataVariable from './ComponentDataVariable'; -export interface DataVariableListenerManagerOptions { +export interface DynamicVariableListenerManagerOptions { model: Model | ComponentView; em: EditorModel; dataVariable: DataVariable | ComponentDataVariable; updateValueFromDataVariable: (value: any) => void; } -export default class DataVariableListenerManager { +export default class DynamicVariableListenerManager { private dataListeners: DataVariableListener[] = []; private em: EditorModel; private model: Model | ComponentView; - private dataVariable: DataVariable | ComponentDataVariable; - private updateValueFromDataVariable: (value: any) => void; + private dynamicVariable: DataVariable | ComponentDataVariable; + private updateValueFromDynamicVariable: (value: any) => void; - constructor(options: DataVariableListenerManagerOptions) { + constructor(options: DynamicVariableListenerManagerOptions) { this.em = options.em; this.model = options.model; - this.dataVariable = options.dataVariable; - this.updateValueFromDataVariable = options.updateValueFromDataVariable; + this.dynamicVariable = options.dataVariable; + this.updateValueFromDynamicVariable = options.updateValueFromDataVariable; - this.listenToDataVariable(); + this.listenToDynamicVariable(); } private onChange = () => { - const value = this.dataVariable.getDataValue(); - this.updateValueFromDataVariable(value); + const value = this.dynamicVariable.getDataValue(); + this.updateValueFromDynamicVariable(value); }; - listenToDataVariable() { - const { em, dataVariable, model } = this; - const { path } = dataVariable.attributes; - const normPath = stringToPath(path || '').join('.'); - const [ds, dr] = this.em.DataSources.fromPath(path); - + listenToDynamicVariable() { + const { em, dynamicVariable, model } = this; this.removeListeners(); + const type = dynamicVariable.get('type'); + let dataListeners: DataVariableListener[] = []; + switch (type) { + case DataVariableType: + dataListeners = this.listenToDataVariable(dynamicVariable, em); + break; + } + dataListeners.forEach((ls) => model.listenTo(ls.obj, ls.event, this.onChange)); + + this.dataListeners = dataListeners; + } + + private listenToDataVariable(dataVariable: DataVariable | ComponentDataVariable, em: EditorModel) { const dataListeners: DataVariableListener[] = []; + const { path } = dataVariable.attributes; + const normPath = stringToPath(path || '').join('.'); + const [ds, dr] = this.em.DataSources.fromPath(path); ds && dataListeners.push({ obj: ds.records, event: 'add remove reset' }); dr && dataListeners.push({ obj: dr, event: 'change' }); dataListeners.push( @@ -51,9 +63,7 @@ export default class DataVariableListenerManager { { obj: em, event: `${DataSourcesEvents.path}:${normPath}` }, ); - dataListeners.forEach((ls) => model.listenTo(ls.obj, ls.event, this.onChange)); - - this.dataListeners = dataListeners; + return dataListeners; } private removeListeners() { diff --git a/packages/core/src/data_sources/view/ComponentDataVariableView.ts b/packages/core/src/data_sources/view/ComponentDataVariableView.ts index 385b6ed8fd..f1bba37083 100644 --- a/packages/core/src/data_sources/view/ComponentDataVariableView.ts +++ b/packages/core/src/data_sources/view/ComponentDataVariableView.ts @@ -1,13 +1,13 @@ import ComponentView from '../../dom_components/view/ComponentView'; import ComponentDataVariable from '../model/ComponentDataVariable'; -import DataVariableListenerManager from '../model/DataVariableListenerManager'; +import DynamicVariableListenerManager from '../model/DataVariableListenerManager'; export default class ComponentDataVariableView extends ComponentView { - dataVariableListener?: DataVariableListenerManager; + dynamicVariableListener?: DynamicVariableListenerManager; initialize(opt = {}) { super.initialize(opt); - this.dataVariableListener = new DataVariableListenerManager({ + this.dynamicVariableListener = new DynamicVariableListenerManager({ model: this, em: this.em!, dataVariable: this.model, diff --git a/packages/core/src/dom_components/model/Component.ts b/packages/core/src/dom_components/model/Component.ts index b31864721e..7abb1af35b 100644 --- a/packages/core/src/dom_components/model/Component.ts +++ b/packages/core/src/dom_components/model/Component.ts @@ -927,8 +927,8 @@ export default class Component extends StyleableModel { if (name && value) attrs[name] = value; } - if (trait.dataVariable) { - traitDataVariableAttr[name] = trait.dataVariable; + if (trait.dynamicVariable) { + traitDataVariableAttr[name] = trait.dynamicVariable; } }); traits.length && this.set('attributes', attrs); diff --git a/packages/core/src/domain_abstract/model/StyleableModel.ts b/packages/core/src/domain_abstract/model/StyleableModel.ts index dd3124050a..e325d8751c 100644 --- a/packages/core/src/domain_abstract/model/StyleableModel.ts +++ b/packages/core/src/domain_abstract/model/StyleableModel.ts @@ -6,7 +6,7 @@ import { shallowDiff } from '../../utils/mixins'; import EditorModel from '../../editor/model/Editor'; import StyleDataVariable from '../../data_sources/model/StyleDataVariable'; import { DataVariableType } from '../../data_sources/model/DataVariable'; -import DataVariableListenerManager from '../../data_sources/model/DataVariableListenerManager'; +import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager'; import CssRuleView from '../../css_composer/view/CssRuleView'; import ComponentView from '../../dom_components/view/ComponentView'; import Frame from '../../canvas/model/Frame'; @@ -39,7 +39,7 @@ export const getLastStyleValue = (value: string | string[]) => { export default class StyleableModel extends Model { em?: EditorModel; - dataVariableListeners: Record = {}; + dynamicVariableListeners: Record = {}; views: StyleableView[] = []; constructor(attributes: T, options: { em?: EditorModel } = {}) { @@ -114,9 +114,17 @@ export default class StyleableModel extends Model const styleValue = newStyle[key]; if (typeof styleValue === 'object' && styleValue.type === DataVariableType) { - const styleDataVariable = new StyleDataVariable(styleValue, { em: this.em }); - newStyle[key] = styleDataVariable; - this.manageDataVariableListener(styleDataVariable, key); + const dynamicType = styleValue.type; + let styleDynamicVariable; + switch (dynamicType) { + case DataVariableType: + styleDynamicVariable = new StyleDataVariable(styleValue, { em: this.em }); + break; + default: + throw new Error(`Invalid data variable type. Expected '${DataVariableType}', but found '${dynamicType}'.`); + } + newStyle[key] = styleDynamicVariable; + this.manageDataVariableListener(styleDynamicVariable, key); } }); @@ -146,10 +154,10 @@ export default class StyleableModel extends Model * Manage DataVariableListenerManager for a style property */ manageDataVariableListener(dataVar: StyleDataVariable, styleProp: string) { - if (this.dataVariableListeners[styleProp]) { - this.dataVariableListeners[styleProp].listenToDataVariable(); + if (this.dynamicVariableListeners[styleProp]) { + this.dynamicVariableListeners[styleProp].listenToDynamicVariable(); } else { - this.dataVariableListeners[styleProp] = new DataVariableListenerManager({ + this.dynamicVariableListeners[styleProp] = new DynamicVariableListenerManager({ model: this, em: this.em!, dataVariable: dataVar, diff --git a/packages/core/src/trait_manager/model/Trait.ts b/packages/core/src/trait_manager/model/Trait.ts index a9b36e8fc4..17dd6c7732 100644 --- a/packages/core/src/trait_manager/model/Trait.ts +++ b/packages/core/src/trait_manager/model/Trait.ts @@ -7,10 +7,9 @@ import { isDef } from '../../utils/mixins'; import TraitsEvents, { TraitGetValueOptions, TraitOption, TraitProperties, TraitSetValueOptions } from '../types'; import TraitView from '../view/TraitView'; import Traits from './Traits'; -import { DataVariableListener } from '../../data_sources/types'; import TraitDataVariable from '../../data_sources/model/TraitDataVariable'; import { DataVariableType } from '../../data_sources/model/DataVariable'; -import DataVariableListenerManager from '../../data_sources/model/DataVariableListenerManager'; +import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager'; /** * @property {String} id Trait id, eg. `my-trait-id`. @@ -30,9 +29,8 @@ export default class Trait extends Model { em: EditorModel; view?: TraitView; el?: HTMLElement; - dataListeners: DataVariableListener[] = []; - dataVariable?: TraitDataVariable; - dataVariableListener?: DataVariableListenerManager; + dynamicVariable?: TraitDataVariable; + dynamicVariableListener?: DynamicVariableListenerManager; defaults() { return { @@ -59,19 +57,22 @@ export default class Trait extends Model { } this.em = em; - if ( - this.attributes.value && - typeof this.attributes.value === 'object' && - this.attributes.value.type === DataVariableType - ) { - this.dataVariable = new TraitDataVariable(this.attributes.value, { em: this.em, trait: this }); + if (this.attributes.value && typeof this.attributes.value === 'object') { + const dataType = this.attributes.value.type; + switch (dataType) { + case DataVariableType: + this.dynamicVariable = new TraitDataVariable(this.attributes.value, { em: this.em, trait: this }); + break; + default: + throw new Error(`Invalid data variable type. Expected '${DataVariableType}', but found '${dataType}'.`); + } - const dv = this.dataVariable.getDataValue(); + const dv = this.dynamicVariable.getDataValue(); this.set({ value: dv }); - this.dataVariableListener = new DataVariableListenerManager({ + this.dynamicVariableListener = new DynamicVariableListenerManager({ model: this, em: this.em, - dataVariable: this.dataVariable, + dataVariable: this.dynamicVariable, updateValueFromDataVariable: this.updateValueFromDataVariable.bind(this), }); } @@ -159,8 +160,8 @@ export default class Trait extends Model { * @returns {any} */ getValue(opts?: TraitGetValueOptions) { - if (this.dataVariable) { - const dValue = this.dataVariable.getDataValue(); + if (this.dynamicVariable) { + const dValue = this.dynamicVariable.getDataValue(); return dValue; }