Browse Source

Refactor data variable listeners to a generic dynamic variable (#6229)

Co-authored-by: Artur Arseniev <artur.catch@hotmail.it>
pull/6244/head
mohamed yahia 1 year ago
committed by GitHub
parent
commit
45da189c08
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      packages/core/src/css_composer/model/CssRule.ts
  2. 50
      packages/core/src/data_sources/model/DataVariableListenerManager.ts
  3. 6
      packages/core/src/data_sources/view/ComponentDataVariableView.ts
  4. 4
      packages/core/src/dom_components/model/Component.ts
  5. 24
      packages/core/src/domain_abstract/model/StyleableModel.ts
  6. 33
      packages/core/src/trait_manager/model/Trait.ts

4
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 Selector, { SelectorProps } from '../../selector_manager/model/Selector';
import EditorModel from '../../editor/model/Editor'; import EditorModel from '../../editor/model/Editor';
import CssRuleView from '../view/CssRuleView'; import CssRuleView from '../view/CssRuleView';
import DataVariableListenerManager from '../../data_sources/model/DataVariableListenerManager'; import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
/** @private */ /** @private */
export interface CssRuleProperties { export interface CssRuleProperties {
@ -95,7 +95,7 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
em?: EditorModel; em?: EditorModel;
opt: any; opt: any;
views: CssRuleView[] = []; views: CssRuleView[] = [];
dataVariableListeners: Record<string, DataVariableListenerManager> = {}; dynamicVariableListeners: Record<string, DynamicVariableListenerManager> = {};
defaults() { defaults() {
return { return {

50
packages/core/src/data_sources/model/DataVariableListenerManager.ts

@ -2,47 +2,59 @@ import { DataSourcesEvents, DataVariableListener } from '../types';
import { stringToPath } from '../../utils/mixins'; import { stringToPath } from '../../utils/mixins';
import { Model } from '../../common'; import { Model } from '../../common';
import EditorModel from '../../editor/model/Editor'; import EditorModel from '../../editor/model/Editor';
import DataVariable from './DataVariable'; import DataVariable, { DataVariableType } from './DataVariable';
import ComponentView from '../../dom_components/view/ComponentView'; import ComponentView from '../../dom_components/view/ComponentView';
import ComponentDataVariable from './ComponentDataVariable'; import ComponentDataVariable from './ComponentDataVariable';
export interface DataVariableListenerManagerOptions { export interface DynamicVariableListenerManagerOptions {
model: Model | ComponentView; model: Model | ComponentView;
em: EditorModel; em: EditorModel;
dataVariable: DataVariable | ComponentDataVariable; dataVariable: DataVariable | ComponentDataVariable;
updateValueFromDataVariable: (value: any) => void; updateValueFromDataVariable: (value: any) => void;
} }
export default class DataVariableListenerManager { export default class DynamicVariableListenerManager {
private dataListeners: DataVariableListener[] = []; private dataListeners: DataVariableListener[] = [];
private em: EditorModel; private em: EditorModel;
private model: Model | ComponentView; private model: Model | ComponentView;
private dataVariable: DataVariable | ComponentDataVariable; private dynamicVariable: DataVariable | ComponentDataVariable;
private updateValueFromDataVariable: (value: any) => void; private updateValueFromDynamicVariable: (value: any) => void;
constructor(options: DataVariableListenerManagerOptions) { constructor(options: DynamicVariableListenerManagerOptions) {
this.em = options.em; this.em = options.em;
this.model = options.model; this.model = options.model;
this.dataVariable = options.dataVariable; this.dynamicVariable = options.dataVariable;
this.updateValueFromDataVariable = options.updateValueFromDataVariable; this.updateValueFromDynamicVariable = options.updateValueFromDataVariable;
this.listenToDataVariable(); this.listenToDynamicVariable();
} }
private onChange = () => { private onChange = () => {
const value = this.dataVariable.getDataValue(); const value = this.dynamicVariable.getDataValue();
this.updateValueFromDataVariable(value); this.updateValueFromDynamicVariable(value);
}; };
listenToDataVariable() { listenToDynamicVariable() {
const { em, dataVariable, model } = this; const { em, dynamicVariable, model } = this;
const { path } = dataVariable.attributes;
const normPath = stringToPath(path || '').join('.');
const [ds, dr] = this.em.DataSources.fromPath(path);
this.removeListeners(); 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 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' }); ds && dataListeners.push({ obj: ds.records, event: 'add remove reset' });
dr && dataListeners.push({ obj: dr, event: 'change' }); dr && dataListeners.push({ obj: dr, event: 'change' });
dataListeners.push( dataListeners.push(
@ -51,9 +63,7 @@ export default class DataVariableListenerManager {
{ obj: em, event: `${DataSourcesEvents.path}:${normPath}` }, { obj: em, event: `${DataSourcesEvents.path}:${normPath}` },
); );
dataListeners.forEach((ls) => model.listenTo(ls.obj, ls.event, this.onChange)); return dataListeners;
this.dataListeners = dataListeners;
} }
private removeListeners() { private removeListeners() {

6
packages/core/src/data_sources/view/ComponentDataVariableView.ts

@ -1,13 +1,13 @@
import ComponentView from '../../dom_components/view/ComponentView'; import ComponentView from '../../dom_components/view/ComponentView';
import ComponentDataVariable from '../model/ComponentDataVariable'; import ComponentDataVariable from '../model/ComponentDataVariable';
import DataVariableListenerManager from '../model/DataVariableListenerManager'; import DynamicVariableListenerManager from '../model/DataVariableListenerManager';
export default class ComponentDataVariableView extends ComponentView<ComponentDataVariable> { export default class ComponentDataVariableView extends ComponentView<ComponentDataVariable> {
dataVariableListener?: DataVariableListenerManager; dynamicVariableListener?: DynamicVariableListenerManager;
initialize(opt = {}) { initialize(opt = {}) {
super.initialize(opt); super.initialize(opt);
this.dataVariableListener = new DataVariableListenerManager({ this.dynamicVariableListener = new DynamicVariableListenerManager({
model: this, model: this,
em: this.em!, em: this.em!,
dataVariable: this.model, dataVariable: this.model,

4
packages/core/src/dom_components/model/Component.ts

@ -927,8 +927,8 @@ export default class Component extends StyleableModel<ComponentProperties> {
if (name && value) attrs[name] = value; if (name && value) attrs[name] = value;
} }
if (trait.dataVariable) { if (trait.dynamicVariable) {
traitDataVariableAttr[name] = trait.dataVariable; traitDataVariableAttr[name] = trait.dynamicVariable;
} }
}); });
traits.length && this.set('attributes', attrs); traits.length && this.set('attributes', attrs);

24
packages/core/src/domain_abstract/model/StyleableModel.ts

@ -6,7 +6,7 @@ import { shallowDiff } from '../../utils/mixins';
import EditorModel from '../../editor/model/Editor'; import EditorModel from '../../editor/model/Editor';
import StyleDataVariable from '../../data_sources/model/StyleDataVariable'; import StyleDataVariable from '../../data_sources/model/StyleDataVariable';
import { DataVariableType } from '../../data_sources/model/DataVariable'; 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 CssRuleView from '../../css_composer/view/CssRuleView';
import ComponentView from '../../dom_components/view/ComponentView'; import ComponentView from '../../dom_components/view/ComponentView';
import Frame from '../../canvas/model/Frame'; import Frame from '../../canvas/model/Frame';
@ -39,7 +39,7 @@ export const getLastStyleValue = (value: string | string[]) => {
export default class StyleableModel<T extends ObjectHash = any> extends Model<T> { export default class StyleableModel<T extends ObjectHash = any> extends Model<T> {
em?: EditorModel; em?: EditorModel;
dataVariableListeners: Record<string, DataVariableListenerManager> = {}; dynamicVariableListeners: Record<string, DynamicVariableListenerManager> = {};
views: StyleableView[] = []; views: StyleableView[] = [];
constructor(attributes: T, options: { em?: EditorModel } = {}) { constructor(attributes: T, options: { em?: EditorModel } = {}) {
@ -114,9 +114,17 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>
const styleValue = newStyle[key]; const styleValue = newStyle[key];
if (typeof styleValue === 'object' && styleValue.type === DataVariableType) { if (typeof styleValue === 'object' && styleValue.type === DataVariableType) {
const styleDataVariable = new StyleDataVariable(styleValue, { em: this.em }); const dynamicType = styleValue.type;
newStyle[key] = styleDataVariable; let styleDynamicVariable;
this.manageDataVariableListener(styleDataVariable, key); 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<T extends ObjectHash = any> extends Model<T>
* Manage DataVariableListenerManager for a style property * Manage DataVariableListenerManager for a style property
*/ */
manageDataVariableListener(dataVar: StyleDataVariable, styleProp: string) { manageDataVariableListener(dataVar: StyleDataVariable, styleProp: string) {
if (this.dataVariableListeners[styleProp]) { if (this.dynamicVariableListeners[styleProp]) {
this.dataVariableListeners[styleProp].listenToDataVariable(); this.dynamicVariableListeners[styleProp].listenToDynamicVariable();
} else { } else {
this.dataVariableListeners[styleProp] = new DataVariableListenerManager({ this.dynamicVariableListeners[styleProp] = new DynamicVariableListenerManager({
model: this, model: this,
em: this.em!, em: this.em!,
dataVariable: dataVar, dataVariable: dataVar,

33
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 TraitsEvents, { TraitGetValueOptions, TraitOption, TraitProperties, TraitSetValueOptions } from '../types';
import TraitView from '../view/TraitView'; import TraitView from '../view/TraitView';
import Traits from './Traits'; import Traits from './Traits';
import { DataVariableListener } from '../../data_sources/types';
import TraitDataVariable from '../../data_sources/model/TraitDataVariable'; import TraitDataVariable from '../../data_sources/model/TraitDataVariable';
import { DataVariableType } from '../../data_sources/model/DataVariable'; 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`. * @property {String} id Trait id, eg. `my-trait-id`.
@ -30,9 +29,8 @@ export default class Trait extends Model<TraitProperties> {
em: EditorModel; em: EditorModel;
view?: TraitView; view?: TraitView;
el?: HTMLElement; el?: HTMLElement;
dataListeners: DataVariableListener[] = []; dynamicVariable?: TraitDataVariable;
dataVariable?: TraitDataVariable; dynamicVariableListener?: DynamicVariableListenerManager;
dataVariableListener?: DataVariableListenerManager;
defaults() { defaults() {
return { return {
@ -59,19 +57,22 @@ export default class Trait extends Model<TraitProperties> {
} }
this.em = em; this.em = em;
if ( if (this.attributes.value && typeof this.attributes.value === 'object') {
this.attributes.value && const dataType = this.attributes.value.type;
typeof this.attributes.value === 'object' && switch (dataType) {
this.attributes.value.type === DataVariableType case DataVariableType:
) { this.dynamicVariable = new TraitDataVariable(this.attributes.value, { em: this.em, trait: this });
this.dataVariable = 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.set({ value: dv });
this.dataVariableListener = new DataVariableListenerManager({ this.dynamicVariableListener = new DynamicVariableListenerManager({
model: this, model: this,
em: this.em, em: this.em,
dataVariable: this.dataVariable, dataVariable: this.dynamicVariable,
updateValueFromDataVariable: this.updateValueFromDataVariable.bind(this), updateValueFromDataVariable: this.updateValueFromDataVariable.bind(this),
}); });
} }
@ -159,8 +160,8 @@ export default class Trait extends Model<TraitProperties> {
* @returns {any} * @returns {any}
*/ */
getValue(opts?: TraitGetValueOptions) { getValue(opts?: TraitGetValueOptions) {
if (this.dataVariable) { if (this.dynamicVariable) {
const dValue = this.dataVariable.getDataValue(); const dValue = this.dynamicVariable.getDataValue();
return dValue; return dValue;
} }

Loading…
Cancel
Save