Browse Source

Add CssRule mount event

add-css-mount-events
Artur Arseniev 8 months 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) {
const block = rule.getDeclaration({ body: 1 });
const block = rule.getDeclaration();
block && (opts.json ? (result = rule) : (result += block));
} else {
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 { ObjectAny, PrevToNewIdMap } from '../common';
import { UpdateStyleOptions } from '../domain_abstract/model/StyleableModel';
import { CssEvents } from './types';
import CssRuleView from './view/CssRuleView';
/** @private */
interface RuleOptions {
@ -72,8 +74,15 @@ export interface GetSetRuleOptions extends UpdateStyleOptions {
type CssRuleStyle = Required<CssRuleProperties>['style'];
export default class CssComposer extends ItemManagerModule<CssComposerConfig & { pStylePrefix?: string }> {
classes = {
CssRule,
CssRules,
CssRuleView,
CssRulesView,
};
rules: CssRules;
rulesView?: CssRulesView;
events = CssEvents;
Selectors = Selectors;

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

@ -1,6 +1,6 @@
import { isEmpty, forEach, isString, isArray } from 'underscore';
import { Model, ObjectAny, View } from '../../common';
import StyleableModel from '../../domain_abstract/model/StyleableModel';
import { Model, ObjectAny } from '../../common';
import StyleableModel, { StyleProps } 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';
@ -8,6 +8,13 @@ import Selector, { SelectorProps } from '../../selector_manager/model/Selector';
import EditorModel from '../../editor/model/Editor';
import CssRuleView from '../view/CssRuleView';
export interface ToCssOptions {
important?: boolean | string[];
allowEmpty?: boolean;
style?: StyleProps;
inline?: boolean;
}
/** @private */
export interface CssRuleProperties {
/**
@ -214,7 +221,7 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
* });
* cssRule.getDeclaration() // ".class1{color:red;}"
*/
getDeclaration(opts: ObjectAny = {}) {
getDeclaration(opts: ToCssOptions = {}) {
let result = '';
const { important } = this.attributes;
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;}}"
*/
toCSS(opts: ObjectAny = {}) {
toCSS(opts: ToCssOptions = {}) {
let result = '';
const atRule = this.getAtRule();
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 { View } from '../../common';
import CssRule from '../model/CssRule';
import { CssEvents } from '../types';
export default class CssRuleView extends View<CssRule> {
config: any;
@ -19,6 +20,10 @@ export default class CssRuleView extends View<CssRule> {
return this.config.frameView;
}
get em() {
return this.model.em!;
}
remove() {
super.remove();
this.model.removeView(this);
@ -35,9 +40,13 @@ export default class CssRuleView extends View<CssRule> {
}
render() {
const { model, el } = this;
const { model, el, em } = this;
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;
}
}

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

@ -69,6 +69,13 @@ export enum ComponentsEvents {
select = 'component:select',
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.
* @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 Components from '../model/Components';
import { ResetComponentsOptions } from '../model/types';
import { ComponentsEvents } from '../types';
export default class ComponentsView extends View {
opts!: any;
@ -119,7 +120,7 @@ export default class ComponentsView extends View {
}
if (!model.opt.temporary) {
em?.trigger('component:mount', model);
em?.trigger(ComponentsEvents.mount, model);
}
return rendered;

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

@ -17,6 +17,7 @@ import {
isDataResolverProps,
} from '../../data_sources/utils';
import { DataResolver } from '../../data_sources/types';
import { ToCssOptions } from '../../css_composer/model/CssRule';
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
* @return {String}
*/
styleToString(opts: ObjectAny = {}) {
styleToString(opts: ToCssOptions = {}) {
const result: string[] = [];
const style = this.getStyle(opts);
const style = opts.style || this.getStyle(opts);
const imp = opts.important;
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)!;
expect(rule.selectorsToString()).toEqual(`#${name}`);
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;');
});

Loading…
Cancel
Save