Browse Source

Add CssRule mount event

pull/6540/head
Artur Arseniev 1 year ago
parent
commit
ca2a2b1c32
  1. 2
      packages/core/src/code_manager/model/CssGenerator.ts
  2. 9
      packages/core/src/css_composer/index.ts
  3. 15
      packages/core/src/css_composer/model/CssRule.ts
  4. 9
      packages/core/src/css_composer/types.ts
  5. 13
      packages/core/src/css_composer/view/CssRuleView.ts
  6. 7
      packages/core/src/dom_components/types.ts
  7. 3
      packages/core/src/dom_components/view/ComponentsView.ts
  8. 5
      packages/core/src/domain_abstract/model/StyleableModel.ts
  9. 2
      packages/core/test/specs/css_composer/index.ts

2
packages/core/src/code_manager/model/CssGenerator.ts

@ -172,7 +172,7 @@ export default class CssGenerator extends Model {
}); });
if ((selectorStrNoAdd && found) || selectorsAdd || singleAtRule || !model) { if ((selectorStrNoAdd && found) || selectorsAdd || singleAtRule || !model) {
const block = rule.getDeclaration({ body: 1 }); const block = rule.getDeclaration();
block && (opts.json ? (result = rule) : (result += block)); block && (opts.json ? (result = rule) : (result += block));
} else { } else {
dump.push(rule); dump.push(rule);

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

@ -40,6 +40,8 @@ import EditorModel from '../editor/model/Editor';
import Component from '../dom_components/model/Component'; import Component from '../dom_components/model/Component';
import { ObjectAny, PrevToNewIdMap } from '../common'; import { ObjectAny, PrevToNewIdMap } from '../common';
import { UpdateStyleOptions } from '../domain_abstract/model/StyleableModel'; import { UpdateStyleOptions } from '../domain_abstract/model/StyleableModel';
import { CssEvents } from './types';
import CssRuleView from './view/CssRuleView';
/** @private */ /** @private */
interface RuleOptions { interface RuleOptions {
@ -72,8 +74,15 @@ export interface GetSetRuleOptions extends UpdateStyleOptions {
type CssRuleStyle = Required<CssRuleProperties>['style']; type CssRuleStyle = Required<CssRuleProperties>['style'];
export default class CssComposer extends ItemManagerModule<CssComposerConfig & { pStylePrefix?: string }> { export default class CssComposer extends ItemManagerModule<CssComposerConfig & { pStylePrefix?: string }> {
classes = {
CssRule,
CssRules,
CssRuleView,
CssRulesView,
};
rules: CssRules; rules: CssRules;
rulesView?: CssRulesView; rulesView?: CssRulesView;
events = CssEvents;
Selectors = Selectors; Selectors = Selectors;

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

@ -1,6 +1,6 @@
import { isEmpty, forEach, isString, isArray } from 'underscore'; import { isEmpty, forEach, isString, isArray } from 'underscore';
import { Model, ObjectAny, View } from '../../common'; import { Model, ObjectAny } from '../../common';
import StyleableModel from '../../domain_abstract/model/StyleableModel'; import StyleableModel, { StyleProps } from '../../domain_abstract/model/StyleableModel';
import Selectors from '../../selector_manager/model/Selectors'; import Selectors from '../../selector_manager/model/Selectors';
import { getMediaLength } from '../../code_manager/model/CssGenerator'; import { getMediaLength } from '../../code_manager/model/CssGenerator';
import { isEmptyObj, hasWin } from '../../utils/mixins'; import { isEmptyObj, hasWin } from '../../utils/mixins';
@ -8,6 +8,13 @@ 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';
export interface ToCssOptions {
important?: boolean | string[];
allowEmpty?: boolean;
style?: StyleProps;
inline?: boolean;
}
/** @private */ /** @private */
export interface CssRuleProperties { export interface CssRuleProperties {
/** /**
@ -214,7 +221,7 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
* }); * });
* cssRule.getDeclaration() // ".class1{color:red;}" * cssRule.getDeclaration() // ".class1{color:red;}"
*/ */
getDeclaration(opts: ObjectAny = {}) { getDeclaration(opts: ToCssOptions = {}) {
let result = ''; let result = '';
const { important } = this.attributes; const { important } = this.attributes;
const selectors = this.selectorsToString(opts); const selectors = this.selectorsToString(opts);
@ -285,7 +292,7 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
* }); * });
* cssRule.toCSS() // "@media (min-width: 500px){.class1{color:red;}}" * cssRule.toCSS() // "@media (min-width: 500px){.class1{color:red;}}"
*/ */
toCSS(opts: ObjectAny = {}) { toCSS(opts: ToCssOptions = {}) {
let result = ''; let result = '';
const atRule = this.getAtRule(); const atRule = this.getAtRule();
const block = this.getDeclaration(opts); const block = this.getDeclaration(opts);

9
packages/core/src/css_composer/types.ts

@ -0,0 +1,9 @@
export enum CssEvents {
/**
* @event `css:mount` CSS rule is mounted in the canvas.
* @example
* editor.on('css:mount', ({ rule }) => { ... });
*/
mount = 'css:mount',
mountBefore = 'css:mount:before',
}

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

@ -1,6 +1,7 @@
import FrameView from '../../canvas/view/FrameView'; import FrameView from '../../canvas/view/FrameView';
import { View } from '../../common'; import { View } from '../../common';
import CssRule from '../model/CssRule'; import CssRule from '../model/CssRule';
import { CssEvents } from '../types';
export default class CssRuleView extends View<CssRule> { export default class CssRuleView extends View<CssRule> {
config: any; config: any;
@ -19,6 +20,10 @@ export default class CssRuleView extends View<CssRule> {
return this.config.frameView; return this.config.frameView;
} }
get em() {
return this.model.em!;
}
remove() { remove() {
super.remove(); super.remove();
this.model.removeView(this); this.model.removeView(this);
@ -35,9 +40,13 @@ export default class CssRuleView extends View<CssRule> {
} }
render() { render() {
const { model, el } = this; const { model, el, em } = this;
const important = model.get('important'); const important = model.get('important');
el.innerHTML = model.toCSS({ important }); const css = model.toCSS({ important });
const mountProps = { rule: model, ruleView: this, css };
em?.trigger(CssEvents.mountBefore, mountProps);
el.innerHTML = mountProps.css;
em?.trigger(CssEvents.mount, mountProps);
return this; return this;
} }
} }

7
packages/core/src/dom_components/types.ts

@ -69,6 +69,13 @@ export enum ComponentsEvents {
select = 'component:select', select = 'component:select',
selectBefore = 'component:select:before', selectBefore = 'component:select:before',
/**
* @event `component:mount` Component is mounted in the canvas.
* @example
* editor.on('component:mount', (component) => { ... });
*/
mount = 'component:mount',
/** /**
* @event `component:script:mount` Component with script is mounted. * @event `component:script:mount` Component with script is mounted.
* @example * @example

3
packages/core/src/dom_components/view/ComponentsView.ts

@ -8,6 +8,7 @@ import ComponentView from './ComponentView';
import FrameView from '../../canvas/view/FrameView'; import FrameView from '../../canvas/view/FrameView';
import Components from '../model/Components'; import Components from '../model/Components';
import { ResetComponentsOptions } from '../model/types'; import { ResetComponentsOptions } from '../model/types';
import { ComponentsEvents } from '../types';
export default class ComponentsView extends View { export default class ComponentsView extends View {
opts!: any; opts!: any;
@ -119,7 +120,7 @@ export default class ComponentsView extends View {
} }
if (!model.opt.temporary) { if (!model.opt.temporary) {
em?.trigger('component:mount', model); em?.trigger(ComponentsEvents.mount, model);
} }
return rendered; return rendered;

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

@ -17,6 +17,7 @@ import {
isDataResolverProps, isDataResolverProps,
} from '../../data_sources/utils'; } from '../../data_sources/utils';
import { DataResolver } from '../../data_sources/types'; import { DataResolver } from '../../data_sources/types';
import { ToCssOptions } from '../../css_composer/model/CssRule';
export type StyleProps = Record<string, string | string[] | DataVariableProps | DataConditionProps>; export type StyleProps = Record<string, string | string[] | DataVariableProps | DataConditionProps>;
@ -241,9 +242,9 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>
* @param {Object} [opts={}] Options * @param {Object} [opts={}] Options
* @return {String} * @return {String}
*/ */
styleToString(opts: ObjectAny = {}) { styleToString(opts: ToCssOptions = {}) {
const result: string[] = []; const result: string[] = [];
const style = this.getStyle(opts); const style = opts.style || this.getStyle(opts);
const imp = opts.important; const imp = opts.important;
for (let prop in style) { for (let prop in style) {

2
packages/core/test/specs/css_composer/index.ts

@ -162,7 +162,7 @@ describe('Css Composer', () => {
const rule = obj.getIdRule(name)!; const rule = obj.getIdRule(name)!;
expect(rule.selectorsToString()).toEqual(`#${name}`); expect(rule.selectorsToString()).toEqual(`#${name}`);
expect(rule.styleToString()).toEqual('color:red;'); expect(rule.styleToString()).toEqual('color:red;');
expect(rule.styleToString({ important: 1 })).toEqual('color:red !important;'); expect(rule.styleToString({ important: true })).toEqual('color:red !important;');
expect(rule.styleToString({ important: ['color'] })).toEqual('color:red !important;'); expect(rule.styleToString({ important: ['color'] })).toEqual('color:red !important;');
}); });

Loading…
Cancel
Save