Skip to content

Commit

Permalink
Refactor data variable listeners to a generic dynamic variable (#6229)
Browse files Browse the repository at this point in the history
Co-authored-by: Artur Arseniev <[email protected]>
  • Loading branch information
mohamedsalem401 and artf authored Oct 21, 2024
1 parent 8b4a48a commit 45da189
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 51 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/css_composer/model/CssRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -95,7 +95,7 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
em?: EditorModel;
opt: any;
views: CssRuleView[] = [];
dataVariableListeners: Record<string, DataVariableListenerManager> = {};
dynamicVariableListeners: Record<string, DynamicVariableListenerManager> = {};

defaults() {
return {
Expand Down
50 changes: 30 additions & 20 deletions packages/core/src/data_sources/model/DataVariableListenerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<ComponentDataVariable> {
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,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/dom_components/model/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -927,8 +927,8 @@ export default class Component extends StyleableModel<ComponentProperties> {
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);
Expand Down
24 changes: 16 additions & 8 deletions packages/core/src/domain_abstract/model/StyleableModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -39,7 +39,7 @@ export const getLastStyleValue = (value: string | string[]) => {

export default class StyleableModel<T extends ObjectHash = any> extends Model<T> {
em?: EditorModel;
dataVariableListeners: Record<string, DataVariableListenerManager> = {};
dynamicVariableListeners: Record<string, DynamicVariableListenerManager> = {};
views: StyleableView[] = [];

constructor(attributes: T, options: { em?: EditorModel } = {}) {
Expand Down Expand Up @@ -114,9 +114,17 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>

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);
}
});

Expand Down Expand Up @@ -146,10 +154,10 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>
* 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,
Expand Down
33 changes: 17 additions & 16 deletions packages/core/src/trait_manager/model/Trait.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -30,9 +29,8 @@ export default class Trait extends Model<TraitProperties> {
em: EditorModel;
view?: TraitView;
el?: HTMLElement;
dataListeners: DataVariableListener[] = [];
dataVariable?: TraitDataVariable;
dataVariableListener?: DataVariableListenerManager;
dynamicVariable?: TraitDataVariable;
dynamicVariableListener?: DynamicVariableListenerManager;

defaults() {
return {
Expand All @@ -59,19 +57,22 @@ export default class Trait extends Model<TraitProperties> {
}
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),
});
}
Expand Down Expand Up @@ -159,8 +160,8 @@ export default class Trait extends Model<TraitProperties> {
* @returns {any}
*/
getValue(opts?: TraitGetValueOptions) {
if (this.dataVariable) {
const dValue = this.dataVariable.getDataValue();
if (this.dynamicVariable) {
const dValue = this.dynamicVariable.getDataValue();

return dValue;
}
Expand Down

0 comments on commit 45da189

Please sign in to comment.