Browse Source

CssRule view datavar event propagation (#6190)

pull/6204/head
Daniel Starns 1 year ago
committed by GitHub
parent
commit
a27742efa8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      packages/core/src/css_composer/index.ts
  2. 7
      packages/core/src/css_composer/model/CssRule.ts
  3. 18
      packages/core/src/css_composer/view/CssRuleView.ts
  4. 4
      packages/core/src/dom_components/view/ComponentView.ts
  5. 34
      packages/core/src/domain_abstract/model/StyleableModel.ts
  6. 11
      packages/core/test/specs/data_sources/model/StyleDataVariable.ts

3
packages/core/src/css_composer/index.ts

@ -111,8 +111,7 @@ export default class CssComposer extends ItemManagerModule<CssComposerConfig & {
* @private
*/
postLoad() {
const um = this.em?.get('UndoManager');
um && um.add(this.getAll());
this.em.UndoManager.add(this.getAll());
}
store() {

7
packages/core/src/css_composer/model/CssRule.ts

@ -1,11 +1,13 @@
import { isEmpty, forEach, isString, isArray } from 'underscore';
import { Model, ObjectAny } from '../../common';
import { Model, ObjectAny, View } from '../../common';
import StyleableModel from '../../domain_abstract/model/StyleableModel';
import Selectors from '../../selector_manager/model/Selectors';
import { getMediaLength } from '../../code_manager/model/CssGenerator';
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';
/** @private */
export interface CssRuleProperties {
@ -92,6 +94,8 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
config: CssRuleProperties;
em?: EditorModel;
opt: any;
views: CssRuleView[] = [];
dataVariableListeners: Record<string, DataVariableListenerManager> = {};
defaults() {
return {
@ -117,6 +121,7 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
this.em = opt.em;
this.ensureSelectors(null, null, {});
this.on('change', this.__onChange);
this.setStyle(this.get('style'));
}
__onChange(m: CssRule, opts: any) {

18
packages/core/src/css_composer/view/CssRuleView.ts

@ -1,3 +1,4 @@
import FrameView from '../../canvas/view/FrameView';
import { View } from '../../common';
import CssRule from '../model/CssRule';
@ -11,9 +12,24 @@ export default class CssRuleView extends View<CssRule> {
this.listenTo(model, 'change', this.render);
this.listenTo(model, 'destroy remove', this.remove);
this.listenTo(model.get('selectors'), 'change', this.render);
model.setView(this);
}
// @ts-ignore
get frameView(): FrameView {
return this.config.frameView;
}
remove() {
super.remove();
this.model.removeView(this);
return this;
}
updateStyles() {
this.render();
}
/** @ts-ignore */
tagName() {
return 'style';
}

4
packages/core/src/dom_components/view/ComponentView.ts

@ -304,6 +304,10 @@ TComp> {
}
}
updateStyles() {
this.updateStyle();
}
/**
* Update classe attribute
* @private

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

@ -1,5 +1,5 @@
import { isArray, isString, keys } from 'underscore';
import { Model, ObjectAny, ObjectHash, SetOptions } from '../../common';
import { Model, ObjectAny, ObjectHash, SetOptions, View } from '../../common';
import ParserHtml from '../../parser/model/ParserHtml';
import Selectors from '../../selector_manager/model/Selectors';
import { shallowDiff } from '../../utils/mixins';
@ -7,6 +7,9 @@ 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 CssRuleView from '../../css_composer/view/CssRuleView';
import ComponentView from '../../dom_components/view/ComponentView';
import Frame from '../../canvas/model/Frame';
export type StyleProps = Record<
string,
@ -26,6 +29,8 @@ export type UpdateStyleOptions = SetOptions & {
noEvent?: boolean;
};
export type StyleableView = ComponentView | CssRuleView;
const parserHtml = ParserHtml();
export const getLastStyleValue = (value: string | string[]) => {
@ -35,6 +40,12 @@ export const getLastStyleValue = (value: string | string[]) => {
export default class StyleableModel<T extends ObjectHash = any> extends Model<T> {
em?: EditorModel;
dataVariableListeners: Record<string, DataVariableListenerManager> = {};
views: StyleableView[] = [];
constructor(attributes: T, options: { em?: EditorModel } = {}) {
super(attributes, options);
this.em = options.em;
}
/**
* Parse style string to an object
@ -153,6 +164,27 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>
style[prop] = value;
this.setStyle(style, { noEvent: true });
this.trigger(`change:style:${prop}`);
this.updateView();
}
getView(frame?: Frame) {
let { views, em } = this;
const frm = frame || em?.getCurrentFrameModel();
return frm ? views.find((v) => v.frameView === frm.view) : views[0];
}
setView(view: StyleableView) {
let { views } = this;
!views.includes(view) && views.push(view);
}
removeView(view: StyleableView) {
const { views } = this;
views.splice(views.indexOf(view), 1);
}
updateView() {
this.views.forEach((view) => view.updateStyles());
}
/**

11
packages/core/test/specs/data_sources/model/StyleDataVariable.ts

@ -183,7 +183,9 @@ describe('StyleDataVariable', () => {
content: 'Hello World',
})[0];
em.getEditor().CssComposer.addCollection([
const cssComposer = em.getEditor().CssComposer;
const [rule] = cssComposer.addCollection([
{
selectors: [],
selectorsAdd: selector,
@ -198,12 +200,19 @@ describe('StyleDataVariable', () => {
},
]);
cssComposer.render();
const view = rule.getView();
expect(rule.getStyle()).toHaveProperty('color', 'red');
expect(em.getEditor().getCss()).toContain(`${selector}{color:red;}`);
expect(view?.el.innerHTML).toContain(`h1{color:red;}`);
const ds = dsm.get(dsId);
ds.getRecord(drId)?.set({ value: 'blue' });
expect(rule.getStyle()).toHaveProperty('color', 'blue');
expect(em.getEditor().getCss()).toContain(`${selector}{color:blue;}`);
expect(view?.el.innerHTML).toContain(`h1{color:blue;}`);
});
});
});

Loading…
Cancel
Save