Browse Source

Add EditorEvents

pull/6360/head
Artur Arseniev 2 years ago
parent
commit
68d87f9388
  1. 2
      packages/core/src/editor/index.ts
  2. 35
      packages/core/src/editor/model/Editor.ts
  3. 52
      packages/core/src/editor/types.ts
  4. 3
      packages/core/src/undo_manager/index.ts

2
packages/core/src/editor/index.ts

@ -91,6 +91,7 @@ import UtilsModule from '../utils';
import html from '../utils/html'; import html from '../utils/html';
import defConfig, { EditorConfig, EditorConfigKeys } from './config/config'; import defConfig, { EditorConfig, EditorConfigKeys } from './config/config';
import EditorModel, { EditorLoadOptions } from './model/Editor'; import EditorModel, { EditorLoadOptions } from './model/Editor';
import { EditorEvents } from './types';
import EditorView from './view/EditorView'; import EditorView from './view/EditorView';
export type ParsedRule = { export type ParsedRule = {
@ -130,6 +131,7 @@ export default class Editor implements IBaseModule<EditorConfig> {
$: any; $: any;
em: EditorModel; em: EditorModel;
config: EditorConfigType; config: EditorConfigType;
events = EditorEvents;
constructor(config: EditorConfig = {}, opts: any = {}) { constructor(config: EditorConfig = {}, opts: any = {}) {
const defaults = defConfig(); const defaults = defConfig();

35
packages/core/src/editor/model/Editor.ts

@ -45,6 +45,7 @@ import { CanvasSpotBuiltInTypes } from '../../canvas/model/CanvasSpot';
import DataSourceManager from '../../data_sources'; import DataSourceManager from '../../data_sources';
import { ComponentsEvents } from '../../dom_components/types'; import { ComponentsEvents } from '../../dom_components/types';
import { InitEditorConfig } from '../..'; import { InitEditorConfig } from '../..';
import { EditorEvents } from '../types';
Backbone.$ = $; Backbone.$ = $;
@ -89,6 +90,7 @@ const logs = {
export interface EditorLoadOptions { export interface EditorLoadOptions {
/** Clear the editor state (eg. dirty counter, undo manager, etc.). */ /** Clear the editor state (eg. dirty counter, undo manager, etc.). */
clear?: boolean; clear?: boolean;
initial?: boolean;
} }
export default class EditorModel extends Model { export default class EditorModel extends Model {
@ -333,6 +335,7 @@ export default class EditorModel extends Model {
*/ */
loadOnStart() { loadOnStart() {
const { projectData, headless } = this.config; const { projectData, headless } = this.config;
const loadOpts: EditorLoadOptions = { initial: true };
const sm = this.Storage; const sm = this.Storage;
// In `onLoad`, the module will try to load the data from its configurations. // In `onLoad`, the module will try to load the data from its configurations.
@ -345,16 +348,16 @@ export default class EditorModel extends Model {
}; };
if (headless) { if (headless) {
projectData && this.loadData(projectData); projectData && this.loadData(projectData, loadOpts);
postLoad(); postLoad();
} else { } else {
// Defer for storage load events. // Defer for storage load events.
this._storageTimeout = setTimeout(async () => { this._storageTimeout = setTimeout(async () => {
if (projectData) { if (projectData) {
this.loadData(projectData); this.loadData(projectData, loadOpts);
} else if (sm?.canAutoload()) { } else if (sm?.canAutoload()) {
try { try {
await this.load(); await this.load({}, loadOpts);
} catch (error) { } catch (error) {
this.logError(error as string); this.logError(error as string);
} }
@ -388,7 +391,7 @@ export default class EditorModel extends Model {
if (!opts.isClear) { if (!opts.isClear) {
this.updateItr && clearTimeout(this.updateItr); this.updateItr && clearTimeout(this.updateItr);
this.updateItr = setTimeout(() => this.trigger('update')); this.updateItr = setTimeout(() => this.trigger(EditorEvents.update));
} }
if (this.config.noticeOnUnload) { if (this.config.noticeOnUnload) {
@ -851,7 +854,7 @@ export default class EditorModel extends Model {
*/ */
async load<T extends StorageOptions>(options?: T, loadOptions: EditorLoadOptions = {}) { async load<T extends StorageOptions>(options?: T, loadOptions: EditorLoadOptions = {}) {
const result = await this.Storage.load(options); const result = await this.Storage.load(options);
this.loadData(result); this.loadData(result, loadOptions);
// Wait in order to properly update the dirty counter (#5385) // Wait in order to properly update the dirty counter (#5385)
await wait(); await wait();
@ -875,12 +878,15 @@ export default class EditorModel extends Model {
return JSON.parse(JSON.stringify(result)); return JSON.parse(JSON.stringify(result));
} }
loadData(data: ProjectData = {}): ProjectData { loadData(project: ProjectData = {}, opts: EditorLoadOptions = {}): ProjectData {
if (!isEmptyObj(data)) { let loaded = false;
if (!isEmptyObj(project)) {
this.storables.forEach((module) => module.clear()); this.storables.forEach((module) => module.clear());
this.storables.forEach((module) => module.load(data)); this.storables.forEach((module) => module.load(project));
loaded = true;
} }
return data; this.trigger(EditorEvents.projectLoad, { project, loaded, initial: !!opts.initial });
return project;
} }
/** /**
@ -1025,7 +1031,7 @@ export default class EditorModel extends Model {
*/ */
destroyAll() { destroyAll() {
const { config, view } = this; const { config, view } = this;
this.trigger('destroy'); this.trigger(EditorEvents.destroy);
const editor = this.getEditor(); const editor = this.getEditor();
// @ts-ignore // @ts-ignore
const { editors = [] } = config.grapesjs || {}; const { editors = [] } = config.grapesjs || {};
@ -1048,7 +1054,7 @@ export default class EditorModel extends Model {
editors.splice(editors.indexOf(editor), 1); editors.splice(editors.indexOf(editor), 1);
//@ts-ignore //@ts-ignore
hasWin() && $(config.el).empty().attr(this.attrsOrig); hasWin() && $(config.el).empty().attr(this.attrsOrig);
this.trigger('destroyed'); this.trigger(EditorEvents.destroyed);
} }
getEditing(): Component | undefined { getEditing(): Component | undefined {
@ -1066,12 +1072,13 @@ export default class EditorModel extends Model {
} }
log(msg: string, opts: any = {}) { log(msg: string, opts: any = {}) {
const logEvent = EditorEvents.log;
const { ns, level = 'debug' } = opts; const { ns, level = 'debug' } = opts;
this.trigger('log', msg, opts); this.trigger(logEvent, msg, opts);
level && this.trigger(`log:${level}`, msg, opts); level && this.trigger(`${logEvent}:${level}`, msg, opts);
if (ns) { if (ns) {
const logNs = `log-${ns}`; const logNs = `${logEvent}-${ns}`;
this.trigger(logNs, msg, opts); this.trigger(logNs, msg, opts);
level && this.trigger(`${logNs}:${level}`, msg, opts); level && this.trigger(`${logNs}:${level}`, msg, opts);
} }

52
packages/core/src/editor/types.ts

@ -0,0 +1,52 @@
/**{START_EVENTS}*/
export enum EditorEvents {
/**
* @event `update` Event triggered on any change of the project (eg. component added/removed, style changes, etc.)
* @example
* editor.on('update', () => { ... });
*/
update = 'update',
/**
* @event `undo` Undo executed.
* @example
* editor.on('undo', () => { ... });
*/
undo = 'undo',
/**
* @event `redo` Redo executed.
* @example
* editor.on('redo', () => { ... });
*/
redo = 'redo',
/**
* @event `project:load` Project JSON loaded in the editor. The event is triggered on the initial load and on the `editor.loadProjectData` method.
* @example
* editor.on('project:load', ({ project, initial }) => { ... });
*/
projectLoad = 'project:load',
/**
* @event `log` Log message triggered.
* @example
* editor.on('log', (msg, opts) => { ... });
*/
log = 'log',
/**
* @event `destroy` Editor started destroy (on `editor.destroy()`).
* @example
* editor.on('destroy', () => { ... });
*/
destroy = 'destroy',
/**
* @event `destroyed` Editor destroyed.
* @example
* editor.on('destroyed', () => { ... });
*/
destroyed = 'destroyed',
}
/**{END_EVENTS}*/

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

@ -29,6 +29,7 @@ import { isArray, isBoolean, isEmpty, unique, times } from 'underscore';
import { Module } from '../abstract'; import { Module } from '../abstract';
import EditorModel from '../editor/model/Editor'; import EditorModel from '../editor/model/Editor';
import defConfig, { UndoManagerConfig } from './config'; import defConfig, { UndoManagerConfig } from './config';
import { EditorEvents } from '../editor/types';
export interface UndoGroup { export interface UndoGroup {
index: number; index: number;
@ -144,7 +145,7 @@ export default class UndoManagerModule extends Module<UndoManagerConfig & { name
this.um.on('undo redo', () => { this.um.on('undo redo', () => {
em.getSelectedAll().map((c) => c.trigger('rerender:layer')); em.getSelectedAll().map((c) => c.trigger('rerender:layer'));
}); });
['undo', 'redo'].forEach((ev) => this.um.on(ev, () => em.trigger(ev))); [EditorEvents.undo, EditorEvents.redo].forEach((ev) => this.um.on(ev, () => em.trigger(ev)));
} }
postLoad() { postLoad() {

Loading…
Cancel
Save