Browse Source

Convert pages into Module class

pull/4302/head
Alex 4 years ago
parent
commit
48b33e12bd
  1. 211
      src/abstract/Module.ts
  2. 8
      src/abstract/index.ts
  3. 3
      src/canvas/model/Frames.js
  4. 41
      src/editor/index.ts
  5. 6
      src/editor/model/Editor.ts
  6. 415
      src/pages/index.js
  7. 7
      src/pages/model/Page.ts

211
src/abstract/Module.ts

@ -1,6 +1,10 @@
import { isElement, isUndefined } from "underscore";
import { Collection } from "../common";
import EditorModel from "../editor/model/Editor"; import EditorModel from "../editor/model/Editor";
import { createId, isDef } from "../utils/mixins";
export interface IModule<TConfig extends any = any> extends IBaseModule<TConfig> { export interface IModule<TConfig extends any = any>
extends IBaseModule<TConfig> {
init(cfg: any): void; init(cfg: any): void;
destroy(): void; destroy(): void;
postLoad(key: any): any; postLoad(key: any): any;
@ -15,26 +19,41 @@ export interface IBaseModule<TConfig extends any> {
config: TConfig; config: TConfig;
} }
interface ModuleConfig{ interface ModuleConfig {
name: string; name: string;
stylePrefix?: string; stylePrefix?: string;
} }
export interface IStorableModule extends IModule {
storageKey: string[] | string;
store(result: any): any;
load(keys: string[]): void;
postLoad(key: any): any;
}
export default abstract class Module<T extends ModuleConfig = ModuleConfig> export default abstract class Module<T extends ModuleConfig = ModuleConfig>
implements IModule<T> implements IModule<T>
{ {
//conf: CollectionCollectionModuleConfig;
private _em: EditorModel; private _em: EditorModel;
private _config: T; private _config: T;
private _name: string;
cls: any[] = []; cls: any[] = [];
events: any; events: any;
constructor( constructor(em: EditorModel, moduleName: string) {
em: EditorModel,
config: T
) {
this._em = em; this._em = em;
this._config = config; this._name = moduleName;
const name = this.name.charAt(0).toLowerCase() + this.name.slice(1);
const cfgParent = !isUndefined(em.config[name])
? em.config[name]
: em.config[this.name];
const cfg = cfgParent === true ? {} : cfgParent || {};
cfg.pStylePrefix = em.config.pStylePrefix || "";
if (!isUndefined(cfgParent) && !cfgParent) {
cfg._disable = 1;
}
this._config = cfg;
} }
public get em() { public get em() {
@ -51,16 +70,186 @@ export default abstract class Module<T extends ModuleConfig = ModuleConfig>
postLoad(key: any): void {} postLoad(key: any): void {}
get name(): string { get name(): string {
return this.config.name; return this._name;
} }
getConfig() { getConfig() {
return this.config; return this.config;
} }
__logWarn(str: string) { __logWarn(str: string, opts = {}) {
this.em.logWarning(`[${this.name}]: ${str}`); this.em.logWarning(`[${this.name}]: ${str}`, opts);
} }
postRender?(view: any): void; postRender?(view: any): void;
} }
export abstract class ItemManagerModule<
TConf extends ModuleConfig = any,
TModel extends Collection = any
> extends Module<TConf> {
cls: any[] = [];
protected all: TModel;
constructor(em: EditorModel, moduleName: string, all: any, events: any) {
super(em, moduleName);
this.all = all;
this.events = events;
this.__initListen();
}
private: boolean = false;
abstract storageKey: string;
abstract init(cfg: any): void;
abstract destroy(): void;
postLoad(key: any): void {}
abstract postRender(view: any): void;
abstract render(): any;
getProjectData(data: any) {
const obj: any = {};
const key = this.storageKey;
if (key) {
obj[key] = data || this.getAll();
}
return obj;
}
loadProjectData(
data: any = {},
param: { all?: TModel; onResult?: Function; reset?: boolean } = {}
) {
const { all, onResult, reset } = param;
const key = this.storageKey;
const opts: any = { action: "load" };
const coll = all || this.getAll();
let result = data[key];
if (typeof result == "string") {
try {
result = JSON.parse(result);
} catch (err) {
this.__logWarn("Data parsing failed", { input: result });
}
}
reset && result && coll.reset(undefined, opts);
if (onResult) {
result && onResult(result, opts);
} else if (result && isDef(result.length)) {
coll.reset(result, opts);
}
return result;
}
clear(opts = {}) {
const { all } = this;
all && all.reset(undefined, opts);
return this;
}
getAll() {
return this.all;
}
getAllMap() {
return this.getAll().reduce((acc: { [id: string]: TModel }, i: any) => {
acc[i.get(i.idAttribute)] = i;
return acc;
}, {});
}
__initListen(opts: any = {}) {
const { all, em, events } = this;
all &&
em &&
all
.on("add", (m: any, c: any, o: any) => em.trigger(events.add, m, o))
.on("remove", (m: any, c: any, o: any) =>
em.trigger(events.remove, m, o)
)
.on("change", (p: any, c: any) =>
em.trigger(events.update, p, p.changedAttributes(), c)
)
.on("all", this.__catchAllEvent, this);
// Register collections
this.cls = [all].concat(opts.collections || []);
// Propagate events
((opts.propagate as any[]) || []).forEach(({ entity, event }) => {
entity.on("all", (ev: any, model: any, coll: any, opts: any) => {
const options = opts || coll;
const opt = { event: ev, ...options };
[em, all].map((md) => md.trigger(event, model, opt));
});
});
}
__remove(model: any, opts: any = {}) {
const { em } = this;
//@ts-ignore
const md = isString(model) ? this.get(model) : model;
const rm = () => {
md && this.all.remove(md, opts);
return md;
};
!opts.silent && em?.trigger(this.events.removeBefore, md, rm, opts);
return !opts.abort && rm();
}
__catchAllEvent(event: any, model: any, coll: any, opts: any) {
const { em, events } = this;
const options = opts || coll;
em && events.all && em.trigger(events.all, { event, model, options });
this.__onAllEvent();
}
__appendTo() {
//@ts-ignore
const elTo = this.config.appendTo;
if (elTo) {
const el = isElement(elTo) ? elTo : document.querySelector(elTo);
if (!el) return this.__logWarn('"appendTo" element not found');
el.appendChild(this.render());
}
}
__onAllEvent() {}
_createId(len = 16) {
const all = this.getAll();
const ln = all.length + len;
const allMap = this.getAllMap();
let id;
do {
id = createId(ln);
} while (allMap[id]);
return id;
}
__listenAdd(model: TModel, event: string) {
model.on("add", (m, c, o) => this.em.trigger(event, m, o));
}
__listenRemove(model: TModel, event: string) {
model.on("remove", (m, c, o) => this.em.trigger(event, m, o));
}
__listenUpdate(model: TModel, event: string) {
model.on("change", (p, c) =>
this.em.trigger(event, p, p.changedAttributes(), c)
);
}
__destroy() {
this.cls.forEach((coll) => {
coll.stopListening();
coll.reset();
});
}
}

8
src/abstract/index.ts

@ -1,4 +1,4 @@
export { default as Model } from './Model'; export { default as Model } from "./Model";
export { default as Collection } from './Collection'; export { default as Collection } from "./Collection";
export { default as View } from './View'; export { default as View } from "./View";
export { default as Module } from './moduleLegacy'; export { default as Module } from "./Module";

3
src/canvas/model/Frames.js

@ -4,7 +4,8 @@ import { Collection } from '../../common';
import Frame from './Frame'; import Frame from './Frame';
export default class Frames extends Collection { export default class Frames extends Collection {
initialize(models, config = {}) { constructor(models, config = {}) {
super(models);
bindAll(this, 'itemLoaded'); bindAll(this, 'itemLoaded');
this.config = config; this.config = config;
this.on('reset', this.onReset); this.on('reset', this.onReset);

41
src/editor/index.ts

@ -54,19 +54,24 @@
* ## Methods * ## Methods
* @module Editor * @module Editor
*/ */
import { EventHandler } from 'backbone'; import { EventHandler } from "backbone";
import { isUndefined } from 'underscore'; import { isUndefined } from "underscore";
import { IBaseModule } from '../abstract/Module'; import { IBaseModule } from "../abstract/Module";
import cash from '../utils/cash-dom'; import cash from "../utils/cash-dom";
import html from '../utils/html'; import html from "../utils/html";
import defaults from './config/config'; import defaults from "./config/config";
import EditorModel from './model/Editor'; import EditorModel from "./model/Editor";
import EditorView from './view/EditorView'; import EditorView from "./view/EditorView";
export default class EditorModule implements IBaseModule<typeof defaults> { export default class EditorModule implements IBaseModule<typeof defaults> {
constructor(config = {}, opts: any = {}) { constructor(config = {}, opts: any = {}) {
//@ts-ignore //@ts-ignore
this.config = { ...defaults, ...config, pStylePrefix: defaults.stylePrefix }; this.config = {
...defaults,
...config,
//@ts-ignore
pStylePrefix: defaults.stylePrefix,
};
this.em = new EditorModel(this.config); this.em = new EditorModel(this.config);
this.$ = opts.$; this.$ = opts.$;
this.em.init(this); this.em.init(this);
@ -206,7 +211,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
//@ts-ignore //@ts-ignore
get Devices(): DeviceManagerModule { get Devices(): DeviceManagerModule {
return this.em.get("DeviceManager"); return this.em.get("DeviceManager");
} }
//@ts-ignore //@ts-ignore
get DeviceManager(): DeviceManagerModule { get DeviceManager(): DeviceManagerModule {
return this.em.get("DeviceManager"); return this.em.get("DeviceManager");
@ -259,7 +264,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* @return {Components} * @return {Components}
*/ */
getComponents() { getComponents() {
return this.em.get('DomComponents').getComponents(); return this.em.get("DomComponents").getComponents();
} }
/** /**
@ -267,7 +272,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* @return {Component} * @return {Component}
*/ */
getWrapper() { getWrapper() {
return this.em.get('DomComponents').getWrapper(); return this.em.get("DomComponents").getWrapper();
} }
/** /**
@ -315,7 +320,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* @return {Object} * @return {Object}
*/ */
getStyle() { getStyle() {
return this.em.get('CssComposer').getAll(); return this.em.get("CssComposer").getAll();
} }
/** /**
@ -453,7 +458,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* editor.setDevice('Tablet'); * editor.setDevice('Tablet');
*/ */
setDevice(name: string) { setDevice(name: string) {
this.em.set('device', name); this.em.set("device", name);
return this; return this;
} }
@ -466,7 +471,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* // 'Tablet' * // 'Tablet'
*/ */
getDevice() { getDevice() {
return this.em.get('device'); return this.em.get("device");
} }
/** /**
@ -478,7 +483,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* editor.runCommand('myCommand', {someValue: 1}); * editor.runCommand('myCommand', {someValue: 1});
*/ */
runCommand(id: string, options = {}) { runCommand(id: string, options = {}) {
return this.em.get('Commands').run(id, options); return this.em.get("Commands").run(id, options);
} }
/** /**
@ -490,7 +495,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* editor.stopCommand('myCommand', {someValue: 1}); * editor.stopCommand('myCommand', {someValue: 1});
*/ */
stopCommand(id: string, options = {}) { stopCommand(id: string, options = {}) {
return this.em.get('Commands').stop(id, options); return this.em.get("Commands").stop(id, options);
} }
/** /**
@ -779,7 +784,7 @@ export default class EditorModule implements IBaseModule<typeof defaults> {
* }); * });
*/ */
onReady(clb: EventHandler) { onReady(clb: EventHandler) {
this.em.get('ready') ? clb(this) : this.em.on('load', clb); this.em.get("ready") ? clb(this) : this.em.on("load", clb);
} }
/** /**

6
src/editor/model/Editor.ts

@ -45,7 +45,9 @@ const deps = [
require("block_manager"), require("block_manager"),
]; ];
const ts_deps: any[] = []; const ts_deps: any[] = [
//require("pages")
];
Extender({ Extender({
//@ts-ignore //@ts-ignore
@ -264,7 +266,7 @@ export default class EditorModel extends Model {
loadModule(moduleName: any) { loadModule(moduleName: any) {
const { config } = this; const { config } = this;
const Module = moduleName.default || moduleName; const Module = moduleName.default || moduleName;
const Mod = new Module(); const Mod = new Module(this);
const name = Mod.name.charAt(0).toLowerCase() + Mod.name.slice(1); const name = Mod.name.charAt(0).toLowerCase() + Mod.name.slice(1);
const cfgParent = !isUndefined(config[name]) const cfgParent = !isUndefined(config[name])
? config[name] ? config[name]

415
src/pages/index.js

@ -46,9 +46,11 @@
import { isString, bindAll, unique, flatten } from 'underscore'; import { isString, bindAll, unique, flatten } from 'underscore';
import { createId } from '../utils/mixins'; import { createId } from '../utils/mixins';
import { Model, Module } from '../common'; import { Model, Module } from '../abstract';
import { ItemManagerModule } from '../abstract/Module';
import Pages from './model/Pages'; import Pages from './model/Pages';
import Page from './model/Page'; import Page from './model/Page';
import EditorModel from '../editor/model/Editor';
export const evAll = 'page'; export const evAll = 'page';
export const evPfx = `${evAll}:`; export const evPfx = `${evAll}:`;
@ -61,239 +63,226 @@ export const evPageRemove = `${evPfx}remove`;
export const evPageRemoveBefore = `${evPageRemove}:before`; export const evPageRemoveBefore = `${evPageRemove}:before`;
const chnSel = 'change:selected'; const chnSel = 'change:selected';
const typeMain = 'main'; const typeMain = 'main';
const events = {
all: evAll,
select: evPageSelect,
selectBefore: evPageSelectBefore,
update: evPageUpdate,
add: evPageAdd,
addBefore: evPageAddBefore,
remove: evPageRemove,
removeBefore: evPageRemoveBefore,
};
export default class PageManager extends ItemManagerModule {
name = 'PageManager';
export default () => { storageKey = 'pages';
return {
...Module,
name: 'PageManager',
storageKey: 'pages',
Page,
Pages, Page;
events: { Pages;
all: evAll,
select: evPageSelect,
selectBefore: evPageSelectBefore,
update: evPageUpdate,
add: evPageAdd,
addBefore: evPageAddBefore,
remove: evPageRemove,
removeBefore: evPageRemoveBefore,
},
/** get pages() {
* Initialize module return this.all;
* @param {Object} config Configurations }
* @private /**
*/ * Initialize module
init(opts = {}) { * @param {Object} config Configurations
bindAll(this, '_onPageChange'); * @private
const { em } = opts; */
const cnf = { ...opts }; constructor(em) {
this.config = cnf; const pages = new Pages([]);
this.em = em; super(em, 'PageManager', pages, events);
const pages = new Pages([]); bindAll(this, '_onPageChange');
this.pages = pages; const model = new Model({ _undo: true });
this.all = pages; this.model = model;
const model = new Model({ _undo: true }); pages.on('reset', coll => coll.at(0) && this.select(coll.at(0)));
this.model = model; pages.on('all', this.__onChange, this);
pages.on('add', (p, c, o) => em.trigger(evPageAdd, p, o)); model.on(chnSel, this._onPageChange);
pages.on('remove', (p, c, o) => em.trigger(evPageRemove, p, o));
pages.on('change', (p, c) => {
em.trigger(evPageUpdate, p, p.changedAttributes(), c);
});
pages.on('reset', coll => coll.at(0) && this.select(coll.at(0)));
pages.on('all', this.__onChange, this);
model.on(chnSel, this._onPageChange);
return this; return this;
}, }
__onChange(event, page, coll, opts) { __onChange(event, page, coll, opts) {
const options = opts || coll; const options = opts || coll;
this.em.trigger(evAll, { event, page, options }); this.em.trigger(evAll, { event, page, options });
}, }
onLoad() { onLoad() {
const { pages } = this; const { pages } = this;
const opt = { silent: true }; const opt = { silent: true };
pages.add(this.config.pages?.map(page => new Page(page, { em: this.em, config: this.config })) || [], opt); pages.add(this.config.pages?.map(page => new Page(page, { em: this.em, config: this.config })) || [], opt);
const mainPage = !pages.length ? this.add({ type: typeMain }, opt) : this.getMain(); const mainPage = !pages.length ? this.add({ type: typeMain }, opt) : this.getMain();
this.select(mainPage, opt); this.select(mainPage, opt);
}, }
_onPageChange(m, page, opts) { _onPageChange(m, page, opts) {
const { em } = this; const { em } = this;
const lm = em.get('LayerManager'); const lm = em.get('LayerManager');
const mainComp = page.getMainComponent(); const mainComp = page.getMainComponent();
lm && mainComp && lm.setRoot(mainComp); lm && mainComp && lm.setRoot(mainComp);
em.trigger(evPageSelect, page, m.previous('selected')); em.trigger(evPageSelect, page, m.previous('selected'));
this.__onChange(chnSel, page, opts); this.__onChange(chnSel, page, opts);
}, }
postLoad() { postLoad() {
const { em, model } = this; const { em, model } = this;
const um = em.get('UndoManager'); const um = em.get('UndoManager');
um && um.add(model); um && um.add(model);
um && um.add(this.pages); um && um.add(this.pages);
}, }
/** /**
* Add new page * Add new page
* @param {Object} props Page properties * @param {Object} props Page properties
* @param {Object} [opts] Options * @param {Object} [opts] Options
* @returns {[Page]} * @returns {[Page]}
* @example * @example
* const newPage = pageManager.add({ * const newPage = pageManager.add({
* id: 'new-page-id', // without an explicit ID, a random one will be created * id: 'new-page-id', // without an explicit ID, a random one will be created
* styles: `.my-class { color: red }`, // or a JSON of styles * styles: `.my-class { color: red }`, // or a JSON of styles
* component: '<div class="my-class">My element</div>', // or a JSON of components * component: '<div class="my-class">My element</div>', // or a JSON of components
* }); * });
*/ */
add(props, opts = {}) { add(props, opts = {}) {
const { em } = this; const { em } = this;
props.id = props.id || this._createId(); props.id = props.id || this._createId();
const add = () => { const add = () => {
const page = this.pages.add(new Page(props, { em: this.em, config: this.config }), opts); const page = this.pages.add(new Page(props, { em: this.em, config: this.config }), opts);
opts.select && this.select(page); opts.select && this.select(page);
return page; return page;
}; };
!opts.silent && em.trigger(evPageAddBefore, props, add, opts); !opts.silent && em.trigger(evPageAddBefore, props, add, opts);
return !opts.abort && add(); return !opts.abort && add();
}, }
/** /**
* Remove page * Remove page
* @param {String|[Page]} page Page or page id * @param {String|[Page]} page Page or page id
* @returns {[Page]} Removed Page * @returns {[Page]} Removed Page
* @example * @example
* const removedPage = pageManager.remove('page-id'); * const removedPage = pageManager.remove('page-id');
* // or by passing the page * // or by passing the page
* const somePage = pageManager.get('page-id'); * const somePage = pageManager.get('page-id');
* pageManager.remove(somePage); * pageManager.remove(somePage);
*/ */
remove(page, opts = {}) { remove(page, opts = {}) {
const { em } = this; const { em } = this;
const pg = isString(page) ? this.get(page) : page; const pg = isString(page) ? this.get(page) : page;
const rm = () => { const rm = () => {
pg && this.pages.remove(pg, opts); pg && this.pages.remove(pg, opts);
return pg; return pg;
}; };
!opts.silent && em.trigger(evPageRemoveBefore, pg, rm, opts); !opts.silent && em.trigger(evPageRemoveBefore, pg, rm, opts);
return !opts.abort && rm(); return !opts.abort && rm();
}, }
/** /**
* Get page by id * Get page by id
* @param {String} id Page id * @param {String} id Page id
* @returns {[Page]} * @returns {[Page]}
* @example * @example
* const somePage = pageManager.get('page-id'); * const somePage = pageManager.get('page-id');
*/ */
get(id) { get(id) {
return this.pages.filter(p => p.get('id') === id)[0]; return this.pages.filter(p => p.get('id') === id)[0];
}, }
/** /**
* Get main page (the first one available) * Get main page (the first one available)
* @returns {[Page]} * @returns {[Page]}
* @example * @example
* const mainPage = pageManager.getMain(); * const mainPage = pageManager.getMain();
*/ */
getMain() { getMain() {
const { pages } = this; const { pages } = this;
return pages.filter(p => p.get('type') === typeMain)[0] || pages.at(0); return pages.filter(p => p.get('type') === typeMain)[0] || pages.at(0);
}, }
/** /**
* Get all pages * Get all pages
* @returns {Array<[Page]>} * @returns {Array<[Page]>}
* @example * @example
* const arrayOfPages = pageManager.getAll(); * const arrayOfPages = pageManager.getAll();
*/ */
getAll() { getAll() {
return [...this.pages.models]; return [...this.pages.models];
}, }
/** /**
* Get wrapper components (aka body) from all pages and frames. * Get wrapper components (aka body) from all pages and frames.
* @returns {Array<[Component]>} * @returns {Array<[Component]>}
* @example * @example
* const wrappers = pageManager.getAllWrappers(); * const wrappers = pageManager.getAllWrappers();
* // Get all `image` components from the project * // Get all `image` components from the project
* const allImages = wrappers.map(wrp => wrp.findType('image')).flat(); * const allImages = wrappers.map(wrp => wrp.findType('image')).flat();
*/ */
getAllWrappers() { getAllWrappers() {
const pages = this.getAll(); const pages = this.getAll();
return unique(flatten(pages.map(page => page.getAllFrames().map(frame => frame.getComponent())))); return unique(flatten(pages.map(page => page.getAllFrames().map(frame => frame.getComponent()))));
}, }
getAllMap() { getAllMap() {
return this.getAll().reduce((acc, i) => { return this.getAll().reduce((acc, i) => {
acc[i.get('id')] = i; acc[i.get('id')] = i;
return acc; return acc;
}, {}); }, {});
}, }
/** /**
* Change the selected page. This will switch the page rendered in canvas * Change the selected page. This will switch the page rendered in canvas
* @param {String|[Page]} page Page or page id * @param {String|[Page]} page Page or page id
* @returns {this} * @returns {this}
* @example * @example
* pageManager.select('page-id'); * pageManager.select('page-id');
* // or by passing the page * // or by passing the page
* const somePage = pageManager.get('page-id'); * const somePage = pageManager.get('page-id');
* pageManager.select(somePage); * pageManager.select(somePage);
*/ */
select(page, opts = {}) { select(page, opts = {}) {
const pg = isString(page) ? this.get(page) : page; const pg = isString(page) ? this.get(page) : page;
if (pg) { if (pg) {
this.em.trigger(evPageSelectBefore, pg, opts); this.em.trigger(evPageSelectBefore, pg, opts);
this.model.set('selected', pg, opts); this.model.set('selected', pg, opts);
} }
return this; return this;
}, }
/** /**
* Get the selected page * Get the selected page
* @returns {[Page]} * @returns {[Page]}
* @example * @example
* const selectedPage = pageManager.getSelected(); * const selectedPage = pageManager.getSelected();
*/ */
getSelected() { getSelected() {
return this.model.get('selected'); return this.model.get('selected');
}, }
destroy() { destroy() {
this.pages.off().reset(); this.pages.off().reset();
this.model.stopListening(); this.model.stopListening();
this.model.clear({ silent: true }); this.model.clear({ silent: true });
['selected', 'config', 'em', 'pages', 'model'].map(i => (this[i] = 0)); ['selected', 'model'].map(i => (this[i] = 0));
}, }
store() { store() {
return this.getProjectData(); return this.getProjectData();
}, }
load(data) { load(data) {
return this.loadProjectData(data, { all: this.pages, reset: true }); return this.loadProjectData(data, { all: this.pages, reset: true });
}, }
_createId() { _createId() {
const pages = this.getAll(); const pages = this.getAll();
const len = pages.length + 16; const len = pages.length + 16;
const pagesMap = this.getAllMap(); const pagesMap = this.getAllMap();
let id; let id;
do { do {
id = createId(len); id = createId(len);
} while (pagesMap[id]); } while (pagesMap[id]);
return id; return id;
}, }
}; }
};

7
src/pages/model/Page.ts

@ -24,8 +24,11 @@ export default class Page extends Model {
defFrame.styles = props.styles; defFrame.styles = props.styles;
["component", "styles"].map((i) => this.unset(i)); ["component", "styles"].map((i) => this.unset(i));
} }
const frms = props.frames || [defFrame]; const frms: any[] = props.frames || [defFrame];
const frames = new Frames(frms, config); const frames = new Frames(
frms?.map((model) => new Frame(model, opts)),
opts
);
frames.page = this; frames.page = this;
this.set("frames", frames); this.set("frames", frames);
const um = em && em.get("UndoManager"); const um = em && em.get("UndoManager");

Loading…
Cancel
Save