Skip to content

Commit

Permalink
Fix and add a few events (#6397)
Browse files Browse the repository at this point in the history
* Remove unused styles

* Remove deprecated command options

* Remove deprecated Commands events

* Add `command:call` event for generic Command calls

* Add `project:get` event

* Add `parse:html:before` and `parse:css:before` events

* Avoid using toggleFramesEvents on component resize
  • Loading branch information
artf authored Feb 4, 2025
1 parent fa087df commit 13d1c23
Show file tree
Hide file tree
Showing 16 changed files with 144 additions and 74 deletions.
1 change: 1 addition & 0 deletions packages/core/src/canvas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@ export default class CanvasModule extends Module<CanvasConfig> {
}

toggleFramesEvents(on: boolean) {
// Seems like this causing a bug for iframes in Chrome: https://issues.chromium.org/issues/41336877
const { style } = this.getFramesEl();
style.pointerEvents = on ? '' : 'none';
}
Expand Down
15 changes: 4 additions & 11 deletions packages/core/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,18 +383,13 @@ export default class CommandsModule extends Module<CommandsConfig & { pStylePref
runCommand(command?: CommandObject, options: CommandOptions = {}) {
let result;

if (command && command.run) {
if (command?.run) {
const { em, config } = this;
const id = command.id as string;
const editor = em.Editor;

if (!this.isActive(id) || options.force || !config.strict) {
// @ts-ignore
result = editor && command.callRun(editor, options);

if (id && command.stop && !command.noStop && !options.abort) {
this.active[id] = result;
}
result = editor && (command as any).callRun(editor, options);
}
}

Expand All @@ -411,15 +406,13 @@ export default class CommandsModule extends Module<CommandsConfig & { pStylePref
stopCommand(command?: CommandObject, options: CommandOptions = {}) {
let result;

if (command && command.run) {
if (command?.run) {
const { em, config } = this;
const id = command.id as string;
const editor = em.Editor;

if (this.isActive(id) || options.force || !config.strict) {
if (id) delete this.active[id];
// @ts-ignore
result = command.callStop(editor, options);
result = (command as any).callStop(editor, options);
}
}

Expand Down
21 changes: 16 additions & 5 deletions packages/core/src/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ export enum CommandsEvents {
* });
*/
run = 'command:run',
_run = 'run',

/**
* @event `command:run:COMMAND-ID` Triggered on run of a specific command.
* @example
* editor.on('command:run:my-command', ({ result, options }) => { ... });
*/
runCommand = 'command:run:',
_runCommand = 'run:',

/**
* @event `command:run:before:COMMAND-ID` Triggered before the command is called.
Expand All @@ -38,7 +36,6 @@ export enum CommandsEvents {
* });
*/
abort = 'command:abort:',
_abort = 'abort:',

/**
* @event `command:stop` Triggered on stop of any command.
Expand All @@ -48,22 +45,36 @@ export enum CommandsEvents {
* });
*/
stop = 'command:stop',
_stop = 'stop',

/**
* @event `command:stop:COMMAND-ID` Triggered on stop of a specific command.
* @example
* editor.on('command:run:my-command', ({ result, options }) => { ... });
*/
stopCommand = 'command:stop:',
_stopCommand = 'stop:',

/**
* @event `command:stop:before:COMMAND-ID` Triggered before the command is called to stop.
* @example
* editor.on('command:stop:before:my-command', ({ options }) => { ... });
*/
stopBeforeCommand = 'command:stop:before:',

/**
* @event `command:call` Triggered on run or stop of a command.
* @example
* editor.on('command:call', ({ id, result, options, type }) => {
* console.log('Command id', id, 'command result', result, 'call type', type);
* });
*/
call = 'command:call',

/**
* @event `command:call:COMMAND-ID` Triggered on run or stop of a specific command.
* @example
* editor.on('command:call:my-command', ({ result, options, type }) => { ... });
*/
callCommand = 'command:call:',
}
/**{END_EVENTS}*/

Expand Down
24 changes: 14 additions & 10 deletions packages/core/src/commands/view/CommandAbstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default class CommandAbstract<O extends ObjectAny = any> extends Model {
plhClass: string;
freezClass: string;
canvas: CanvasModule;
noStop?: boolean;

constructor(o: any) {
super(0);
Expand Down Expand Up @@ -111,22 +112,26 @@ export default class CommandAbstract<O extends ObjectAny = any> extends Model {
callRun(editor: Editor, options: any = {}) {
const { id } = this;
editor.trigger(`${CommandsEvents.runBeforeCommand}${id}`, { options });
editor.trigger(`${CommandsEvents._runCommand}${id}:before`, options);

if (options.abort) {
editor.trigger(`${CommandsEvents.abort}${id}`, { options });
editor.trigger(`${CommandsEvents._abort}${id}`, options);
return;
}

const sender = options.sender || editor;
const result = this.run(editor, sender, options);
const data = { id, result, options };
const dataCall = { ...data, type: 'run' };

if (!this.noStop) {
editor.Commands.active[id] = result;
}

editor.trigger(`${CommandsEvents.runCommand}${id}`, data);
editor.trigger(`${CommandsEvents.callCommand}${id}`, dataCall);
editor.trigger(CommandsEvents.run, data);
// deprecated
editor.trigger(`${CommandsEvents._runCommand}${id}`, result, options);
editor.trigger(CommandsEvents._run, id, result, options);
editor.trigger(CommandsEvents.call, dataCall);

return result;
}

Expand All @@ -140,15 +145,14 @@ export default class CommandAbstract<O extends ObjectAny = any> extends Model {
const { id } = this;
const sender = options.sender || editor;
editor.trigger(`${CommandsEvents.stopBeforeCommand}${id}`, { options });
editor.trigger(`${CommandsEvents._stopCommand}${id}:before`, options);
const result = this.stop(editor, sender, options);
const data = { id, result, options };
const dataCall = { ...data, type: 'stop' };
delete editor.Commands.active[id];
editor.trigger(`${CommandsEvents.stopCommand}${id}`, data);
editor.trigger(`${CommandsEvents.callCommand}${id}`, dataCall);
editor.trigger(CommandsEvents.stop, data);

// deprecated
editor.trigger(`${CommandsEvents._stopCommand}${id}`, result, options);
editor.trigger(CommandsEvents._stop, id, result, options);
editor.trigger(CommandsEvents.call, dataCall);
return result;
}

Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/commands/view/SelectComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,6 @@ export default {
const { keyHeight, keyWidth, currentUnit, keepAutoHeight, keepAutoWidth } = config;
toggleBodyClass('add', ev, opts);
modelToStyle = em.Styles.getModelToStyle(model);
canvas.toggleFramesEvents(false);
const computedStyle = getComputedStyle(el);
const modelStyle = modelToStyle.getStyle();

Expand Down Expand Up @@ -477,7 +476,6 @@ export default {
onEnd(ev, opts);
toggleBodyClass('remove', ev, opts);
editor.trigger('component:resize', { ...resizeEventOpts, type: 'end' });
canvas.toggleFramesEvents(true);
showOffsets = true;
self.activeResizer = false;
},
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/editor/model/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,9 @@ export default class EditorModel extends Model {
this.storables.forEach((m) => {
result = { ...result, ...m.store(1) };
});
return JSON.parse(JSON.stringify(result));
const project = JSON.parse(JSON.stringify(result));
this.trigger(EditorEvents.projectGet, { project });
return project;
}

loadData(project: ProjectData = {}, opts: EditorLoadOptions = {}): ProjectData {
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/editor/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ export enum EditorEvents {
*/
projectLoad = 'project:load',

/**
* @event `project:get` Event triggered on request of the project data. This can be used to extend the project with custom data.
* @example
* editor.on('project:get', ({ project }) => { project.myCustomKey = 'value' });
*/
projectGet = 'project:get',

/**
* @event `log` Log message triggered.
* @example
Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/parser/model/ParserCss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ import { ParserEvents } from '../types';
const ParserCss = (em?: EditorModel, config: ParserConfig = {}) => ({
/**
* Parse CSS string to a desired model object
* @param {String} input CSS string
* @param {String} str CSS string
* @return {Array<Object>}
*/
parse(input: string, opts: { throwOnError?: boolean } = {}) {
parse(str: string, opts: { throwOnError?: boolean } = {}) {
let output: CssRuleJSON[] = [];
const { parserCss } = config;
const editor = em?.Editor;
let nodes: CssRuleJSON[] | ParsedCssRule[] = [];
let error: unknown;
const Parser = em?.Parser;
const inputOptions = { input: str };
Parser?.__emitEvent(ParserEvents.cssBefore, inputOptions);
const { input } = inputOptions;

try {
nodes = parserCss ? parserCss(input, editor!) : BrowserCssParser(input);
Expand All @@ -26,7 +30,7 @@ const ParserCss = (em?: EditorModel, config: ParserConfig = {}) => ({
}

nodes.forEach((node) => (output = output.concat(this.checkNode(node))));
em?.Parser?.__emitEvent(ParserEvents.css, { input, output, nodes, error });
Parser?.__emitEvent(ParserEvents.css, { input, output, nodes, error });

return output;
},
Expand Down
9 changes: 6 additions & 3 deletions packages/core/src/parser/model/ParserHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ const ParserHtml = (em?: EditorModel, config: ParserConfig & { returnArray?: boo
*/
parse(str: string, parserCss?: any, opts: HTMLParserOptions = {}) {
const conf = em?.get('Config') || {};
const Parser = em?.Parser;
const res: HTMLParseResult = { html: [] };
const cf = { ...config, ...opts };
const preOptions = {
Expand All @@ -325,7 +326,9 @@ const ParserHtml = (em?: EditorModel, config: ParserConfig & { returnArray?: boo
asDocument: this.__checkAsDocument(str, preOptions),
};
const { preParser, asDocument } = options;
const input = isFunction(preParser) ? preParser(str, { editor: em?.getEditor()! }) : str;
const inputOptions = { input: isFunction(preParser) ? preParser(str, { editor: em?.getEditor()! }) : str };
Parser?.__emitEvent(ParserEvents.htmlBefore, inputOptions);
const { input } = inputOptions;
const parseRes = isFunction(cf.parserHtml) ? cf.parserHtml(input, options) : BrowserParserHtml(input, options);
let root = parseRes as HTMLElement;
const docEl = parseRes as Document;
Expand Down Expand Up @@ -365,7 +368,7 @@ const ParserHtml = (em?: EditorModel, config: ParserConfig & { returnArray?: boo
if (styleStr) res.css = parserCss.parse(styleStr);
}

em?.Parser?.__emitEvent(ParserEvents.htmlRoot, { input, root });
Parser?.__emitEvent(ParserEvents.htmlRoot, { input, root });
let resHtml: HTMLParseResult['html'] = [];

if (asDocument) {
Expand All @@ -379,7 +382,7 @@ const ParserHtml = (em?: EditorModel, config: ParserConfig & { returnArray?: boo
}

res.html = resHtml;
em?.Parser?.__emitEvent(ParserEvents.html, { input, output: res, options });
Parser?.__emitEvent(ParserEvents.html, { input, output: res, options });

return res;
},
Expand Down
22 changes: 22 additions & 0 deletions packages/core/src/parser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,35 @@ export enum ParserEvents {
html = 'parse:html',
htmlRoot = 'parse:html:root',

/**
* @event `parse:html:before` Event triggered before the HTML parsing starts. An object containing the input is passed as an argument.
* @example
* editor.on('parse:html:before', (options) => {
* console.log('Parser input', options.input);
* // You can also process the input and update `options.input`
* options.input += '<div>Extra content</div>';
* });
*/
htmlBefore = 'parse:html:before',

/**
* @event `parse:css` On CSS parse, an object containing the input and the output of the parser is passed as an argument.
* @example
* editor.on('parse:css', ({ input, output }) => { ... });
*/
css = 'parse:css',

/**
* @event `parse:css:before` Event triggered before the CSS parsing starts. An object containing the input is passed as an argument.
* @example
* editor.on('parse:css:before', (options) => {
* console.log('Parser input', options.input);
* // You can also process the input and update `options.input`
* options.input += '.my-class { color: red; }';
* });
*/
cssBefore = 'parse:css:before',

/**
* @event `parse` Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback.
* @example
Expand Down
7 changes: 2 additions & 5 deletions packages/core/src/styles/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,15 @@ $colorsAll: (one, var(--gjs-primary-color)), (two, var(--gjs-secondary-color)),
border: none;
color: inherit;
}

.#{$app-prefix}no-app {
height: 10px;
}

.#{$app-prefix}test {
&btn {
color: '#fff';
}
}
.opac50 {
@include opacity(0.5);
}

.#{$app-prefix}checker-bg,
.checker-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==');
Expand Down
3 changes: 1 addition & 2 deletions packages/core/test/specs/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Backbone from 'backbone';
import Commands from '../../../src/commands';
import EditorModel from '../../../src/editor/model/Editor';
import { Command, CommandFunction } from '../../../src/commands/view/CommandAbstract';
Expand All @@ -24,7 +23,7 @@ describe('Commands', () => {
};
commFunc = () => commResultRun;
em = new EditorModel();
em.set('Editor', { ...Backbone.Events });
em.set('Editor', em);
obj = em.Commands;
});

Expand Down
Loading

0 comments on commit 13d1c23

Please sign in to comment.