Browse Source

Convert DomComponent Module to ts

pull/4312/head
Alex 4 years ago
parent
commit
f386203b26
  1. 43
      src/abstract/Module.ts
  2. 326
      src/dom_components/index.ts
  3. 4
      src/dom_components/model/Component.js
  4. 26
      src/dom_components/model/Components.js
  5. 293
      src/editor/model/Editor.ts
  6. 4
      test/specs/code_manager/model/CodeModels.js
  7. 2
      test/specs/dom_components/index.js
  8. 2
      test/specs/dom_components/model/Component.js
  9. 2
      test/specs/dom_components/view/ComponentV.js
  10. 6
      test/specs/dom_components/view/ComponentsView.js
  11. 4
      test/specs/parser/model/ParserHtml.js
  12. 2
      test/specs/style_manager/view/PropertyColorView.js
  13. 2
      test/specs/style_manager/view/PropertyCompositeView.js
  14. 2
      test/specs/style_manager/view/PropertyIntegerView.js
  15. 2
      test/specs/style_manager/view/PropertyRadioView.js
  16. 2
      test/specs/style_manager/view/PropertySelectView.js
  17. 2
      test/specs/style_manager/view/PropertyStackView.js
  18. 2
      test/specs/style_manager/view/PropertyView.js

43
src/abstract/Module.ts

@ -1,14 +1,14 @@
import { isElement, isUndefined } from 'underscore'; import { isElement, isUndefined } from "underscore";
import { Collection } from '../common'; import { Collection, View } from "../common";
import EditorModel from '../editor/model/Editor'; import EditorModel from "../editor/model/Editor";
import { createId, isDef } from '../utils/mixins'; import { createId, isDef } from "../utils/mixins";
export interface IModule<TConfig extends any = any> export interface IModule<TConfig extends any = any>
extends IBaseModule<TConfig> { extends IBaseModule<TConfig> {
init(cfg: any): void; init(cfg: any): void;
destroy(): void; destroy(): void;
postLoad(key: any): any; postLoad(key: any): any;
getConfig(): ModuleConfig; config: TConfig;
onLoad?(): void; onLoad?(): void;
name: string; name: string;
postRender?(view: any): void; postRender?(view: any): void;
@ -48,7 +48,7 @@ export default abstract class Module<T extends ModuleConfig = ModuleConfig>
? em.config[name] ? em.config[name]
: em.config[this.name]; : em.config[this.name];
const cfg = cfgParent === true ? {} : cfgParent || {}; const cfg = cfgParent === true ? {} : cfgParent || {};
cfg.pStylePrefix = em.config.pStylePrefix || ''; cfg.pStylePrefix = em.config.pStylePrefix || "";
if (!isUndefined(cfgParent) && !cfgParent) { if (!isUndefined(cfgParent) && !cfgParent) {
cfg._disable = 1; cfg._disable = 1;
@ -73,8 +73,8 @@ export default abstract class Module<T extends ModuleConfig = ModuleConfig>
return this._name; return this._name;
} }
getConfig() { getConfig(name?: string) {
return this.config; return name ? this.config.name : this.config;
} }
__logWarn(str: string, opts = {}) { __logWarn(str: string, opts = {}) {
@ -90,8 +90,9 @@ export abstract class ItemManagerModule<
> extends Module<TConf> { > extends Module<TConf> {
cls: any[] = []; cls: any[] = [];
protected all: TCollection; protected all: TCollection;
view?: View;
constructor(em: EditorModel, moduleName: string, all: any, events: any) { constructor(em: EditorModel, moduleName: string, all: any, events?: any) {
super(em, moduleName); super(em, moduleName);
this.all = all; this.all = all;
this.events = events; this.events = events;
@ -120,15 +121,15 @@ export abstract class ItemManagerModule<
) { ) {
const { all, onResult, reset } = param; const { all, onResult, reset } = param;
const key = this.storageKey; const key = this.storageKey;
const opts: any = { action: 'load' }; const opts: any = { action: "load" };
const coll = all || this.all; const coll = all || this.all;
let result = data[key]; let result = data[key];
if (typeof result == 'string') { if (typeof result == "string") {
try { try {
result = JSON.parse(result); result = JSON.parse(result);
} catch (err) { } catch (err) {
this.__logWarn('Data parsing failed', { input: result }); this.__logWarn("Data parsing failed", { input: result });
} }
} }
@ -167,19 +168,19 @@ export abstract class ItemManagerModule<
all && all &&
em && em &&
all all
.on('add', (m: any, c: any, o: any) => em.trigger(events.add, m, o)) .on("add", (m: any, c: any, o: any) => em.trigger(events.add, m, o))
.on('remove', (m: any, c: any, o: any) => .on("remove", (m: any, c: any, o: any) =>
em.trigger(events.remove, m, o) em.trigger(events.remove, m, o)
) )
.on('change', (p: any, c: any) => .on("change", (p: any, c: any) =>
em.trigger(events.update, p, p.changedAttributes(), c) em.trigger(events.update, p, p.changedAttributes(), c)
) )
.on('all', this.__catchAllEvent, this); .on("all", this.__catchAllEvent, this);
// Register collections // Register collections
this.cls = [all].concat(opts.collections || []); this.cls = [all].concat(opts.collections || []);
// Propagate events // Propagate events
((opts.propagate as any[]) || []).forEach(({ entity, event }) => { ((opts.propagate as any[]) || []).forEach(({ entity, event }) => {
entity.on('all', (ev: any, model: any, coll: any, opts: any) => { entity.on("all", (ev: any, model: any, coll: any, opts: any) => {
const options = opts || coll; const options = opts || coll;
const opt = { event: ev, ...options }; const opt = { event: ev, ...options };
[em, all].map((md) => md.trigger(event, model, opt)); [em, all].map((md) => md.trigger(event, model, opt));
@ -233,15 +234,15 @@ export abstract class ItemManagerModule<
} }
__listenAdd(model: TCollection, event: string) { __listenAdd(model: TCollection, event: string) {
model.on('add', (m, c, o) => this.em.trigger(event, m, o)); model.on("add", (m, c, o) => this.em.trigger(event, m, o));
} }
__listenRemove(model: TCollection, event: string) { __listenRemove(model: TCollection, event: string) {
model.on('remove', (m, c, o) => this.em.trigger(event, m, o)); model.on("remove", (m, c, o) => this.em.trigger(event, m, o));
} }
__listenUpdate(model: TCollection, event: string) { __listenUpdate(model: TCollection, event: string) {
model.on('change', (p, c) => model.on("change", (p, c) =>
this.em.trigger(event, p, p.changedAttributes(), c) this.em.trigger(event, p, p.changedAttributes(), c)
); );
} }
@ -251,5 +252,7 @@ export abstract class ItemManagerModule<
coll.stopListening(); coll.stopListening();
coll.reset(); coll.reset();
}); });
this.view?.remove();
this.view = undefined;
} }
} }

326
src/dom_components/index.js → src/dom_components/index.ts

@ -53,156 +53,167 @@
* *
* @module Components * @module Components
*/ */
import { isEmpty, isObject, isArray, isFunction, isString, result, debounce } from 'underscore'; import {
import defaults from './config/config'; isEmpty,
import Component, { keyUpdate, keyUpdateInside } from './model/Component'; isObject,
import Components from './model/Components'; isArray,
import ComponentView from './view/ComponentView'; isFunction,
import ComponentWrapperView from './view/ComponentWrapperView'; isString,
import ComponentsView from './view/ComponentsView'; result,
import ComponentTableCell from './model/ComponentTableCell'; debounce,
import ComponentTableCellView from './view/ComponentTableCellView'; } from "underscore";
import ComponentTableRow from './model/ComponentTableRow'; import defaults from "./config/config";
import ComponentTableRowView from './view/ComponentTableRowView'; import Component, { keyUpdate, keyUpdateInside } from "./model/Component";
import ComponentTable from './model/ComponentTable'; import Components from "./model/Components";
import ComponentTableView from './view/ComponentTableView'; import ComponentView from "./view/ComponentView";
import ComponentTableHead from './model/ComponentTableHead'; import ComponentWrapperView from "./view/ComponentWrapperView";
import ComponentTableHeadView from './view/ComponentTableHeadView'; import ComponentsView from "./view/ComponentsView";
import ComponentTableBody from './model/ComponentTableBody'; import ComponentTableCell from "./model/ComponentTableCell";
import ComponentTableBodyView from './view/ComponentTableBodyView'; import ComponentTableCellView from "./view/ComponentTableCellView";
import ComponentTableFoot from './model/ComponentTableFoot'; import ComponentTableRow from "./model/ComponentTableRow";
import ComponentTableFootView from './view/ComponentTableFootView'; import ComponentTableRowView from "./view/ComponentTableRowView";
import ComponentMap from './model/ComponentMap'; import ComponentTable from "./model/ComponentTable";
import ComponentMapView from './view/ComponentMapView'; import ComponentTableView from "./view/ComponentTableView";
import ComponentLink from './model/ComponentLink'; import ComponentTableHead from "./model/ComponentTableHead";
import ComponentLinkView from './view/ComponentLinkView'; import ComponentTableHeadView from "./view/ComponentTableHeadView";
import ComponentLabel from './model/ComponentLabel'; import ComponentTableBody from "./model/ComponentTableBody";
import ComponentLabelView from './view/ComponentLabelView'; import ComponentTableBodyView from "./view/ComponentTableBodyView";
import ComponentVideo from './model/ComponentVideo'; import ComponentTableFoot from "./model/ComponentTableFoot";
import ComponentVideoView from './view/ComponentVideoView'; import ComponentTableFootView from "./view/ComponentTableFootView";
import ComponentImage from './model/ComponentImage'; import ComponentMap from "./model/ComponentMap";
import ComponentImageView from './view/ComponentImageView'; import ComponentMapView from "./view/ComponentMapView";
import ComponentScript from './model/ComponentScript'; import ComponentLink from "./model/ComponentLink";
import ComponentScriptView from './view/ComponentScriptView'; import ComponentLinkView from "./view/ComponentLinkView";
import ComponentSvg from './model/ComponentSvg'; import ComponentLabel from "./model/ComponentLabel";
import ComponentSvgIn from './model/ComponentSvgIn'; import ComponentLabelView from "./view/ComponentLabelView";
import ComponentSvgView from './view/ComponentSvgView'; import ComponentVideo from "./model/ComponentVideo";
import ComponentComment from './model/ComponentComment'; import ComponentVideoView from "./view/ComponentVideoView";
import ComponentCommentView from './view/ComponentCommentView'; import ComponentImage from "./model/ComponentImage";
import ComponentTextNode from './model/ComponentTextNode'; import ComponentImageView from "./view/ComponentImageView";
import ComponentTextNodeView from './view/ComponentTextNodeView'; import ComponentScript from "./model/ComponentScript";
import ComponentText from './model/ComponentText'; import ComponentScriptView from "./view/ComponentScriptView";
import ComponentTextView from './view/ComponentTextView'; import ComponentSvg from "./model/ComponentSvg";
import ComponentWrapper from './model/ComponentWrapper'; import ComponentSvgIn from "./model/ComponentSvgIn";
import ComponentFrame from './model/ComponentFrame'; import ComponentSvgView from "./view/ComponentSvgView";
import ComponentFrameView from './view/ComponentFrameView'; import ComponentComment from "./model/ComponentComment";
import Module from 'abstract/moduleLegacy'; import ComponentCommentView from "./view/ComponentCommentView";
import ComponentTextNode from "./model/ComponentTextNode";
export default class ComponentManager extends Module { import ComponentTextNodeView from "./view/ComponentTextNodeView";
import ComponentText from "./model/ComponentText";
import ComponentTextView from "./view/ComponentTextView";
import ComponentWrapper from "./model/ComponentWrapper";
import ComponentFrame from "./model/ComponentFrame";
import ComponentFrameView from "./view/ComponentFrameView";
import { ItemManagerModule } from "../abstract/Module";
import EditorModel from "../editor/model/Editor";
import { Model } from "backbone";
export default class ComponentManager extends ItemManagerModule {
componentTypes = [ componentTypes = [
{ {
id: 'cell', id: "cell",
model: ComponentTableCell, model: ComponentTableCell,
view: ComponentTableCellView, view: ComponentTableCellView,
}, },
{ {
id: 'row', id: "row",
model: ComponentTableRow, model: ComponentTableRow,
view: ComponentTableRowView, view: ComponentTableRowView,
}, },
{ {
id: 'table', id: "table",
model: ComponentTable, model: ComponentTable,
view: ComponentTableView, view: ComponentTableView,
}, },
{ {
id: 'thead', id: "thead",
model: ComponentTableHead, model: ComponentTableHead,
view: ComponentTableHeadView, view: ComponentTableHeadView,
}, },
{ {
id: 'tbody', id: "tbody",
model: ComponentTableBody, model: ComponentTableBody,
view: ComponentTableBodyView, view: ComponentTableBodyView,
}, },
{ {
id: 'tfoot', id: "tfoot",
model: ComponentTableFoot, model: ComponentTableFoot,
view: ComponentTableFootView, view: ComponentTableFootView,
}, },
{ {
id: 'map', id: "map",
model: ComponentMap, model: ComponentMap,
view: ComponentMapView, view: ComponentMapView,
}, },
{ {
id: 'link', id: "link",
model: ComponentLink, model: ComponentLink,
view: ComponentLinkView, view: ComponentLinkView,
}, },
{ {
id: 'label', id: "label",
model: ComponentLabel, model: ComponentLabel,
view: ComponentLabelView, view: ComponentLabelView,
}, },
{ {
id: 'video', id: "video",
model: ComponentVideo, model: ComponentVideo,
view: ComponentVideoView, view: ComponentVideoView,
}, },
{ {
id: 'image', id: "image",
model: ComponentImage, model: ComponentImage,
view: ComponentImageView, view: ComponentImageView,
}, },
{ {
id: 'script', id: "script",
model: ComponentScript, model: ComponentScript,
view: ComponentScriptView, view: ComponentScriptView,
}, },
{ {
id: 'svg-in', id: "svg-in",
model: ComponentSvgIn, model: ComponentSvgIn,
view: ComponentSvgView, view: ComponentSvgView,
}, },
{ {
id: 'svg', id: "svg",
model: ComponentSvg, model: ComponentSvg,
view: ComponentSvgView, view: ComponentSvgView,
}, },
{ {
id: 'iframe', id: "iframe",
model: ComponentFrame, model: ComponentFrame,
view: ComponentFrameView, view: ComponentFrameView,
}, },
{ {
id: 'comment', id: "comment",
model: ComponentComment, model: ComponentComment,
view: ComponentCommentView, view: ComponentCommentView,
}, },
{ {
id: 'textnode', id: "textnode",
model: ComponentTextNode, model: ComponentTextNode,
view: ComponentTextNodeView, view: ComponentTextNodeView,
}, },
{ {
id: 'text', id: "text",
model: ComponentText, model: ComponentText,
view: ComponentTextView, view: ComponentTextView,
}, },
{ {
id: 'wrapper', id: "wrapper",
model: ComponentWrapper, model: ComponentWrapper,
view: ComponentWrapperView, view: ComponentWrapperView,
}, },
{ {
id: 'default', id: "default",
model: Component, model: Component,
view: ComponentView, view: ComponentView,
}, },
]; ];
componentsById = {}; componentsById: { [id: string]: Component } = {};
componentView?: ComponentWrapperView;
Component = Component; Component = Component;
@ -215,18 +226,11 @@ export default class ComponentManager extends Module {
* @type {String} * @type {String}
* @private * @private
*/ */
name = 'DomComponents'; //name = "DomComponents";
storageKey = 'components'; storageKey = "components";
/** shallow?: Component;
* Returns config
* @return {Object} Config object
* @private
*/
getConfig() {
return this.c;
}
/** /**
* Initialize module. Called on a new instance of the editor with configurations passed * Initialize module. Called on a new instance of the editor with configurations passed
@ -234,44 +238,47 @@ export default class ComponentManager extends Module {
* @param {Object} config Configurations * @param {Object} config Configurations
* @private * @private
*/ */
init(config) { constructor(em: EditorModel) {
this.c = config || {}; super(em, "DomComponents", new Components(undefined, { em }));
const em = this.c.em;
this.em = em;
if (em) { if (em) {
this.c.components = em.config.components || this.c.components; this.config.components = em.config.components || this.config.components;
} }
for (var name in defaults) { for (var name in defaults) {
if (!(name in this.c)) this.c[name] = defaults[name]; //@ts-ignore
if (!(name in this.config)) this.config[name] = defaults[name];
} }
var ppfx = this.c.pStylePrefix; var ppfx = this.config.pStylePrefix;
if (ppfx) this.c.stylePrefix = ppfx + this.c.stylePrefix; if (ppfx) this.config.stylePrefix = ppfx + this.config.stylePrefix;
// Load dependencies // Load dependencies
if (em) { if (em) {
this.c.modal = em.get('Modal') || ''; this.config.modal = em.get("Modal") || "";
this.c.am = em.get('AssetManager') || ''; this.config.am = em.get("AssetManager") || "";
em.get('Parser').compTypes = this.componentTypes; em.get("Parser").compTypes = this.componentTypes;
em.on('change:componentHovered', this.componentHovered, this); em.on("change:componentHovered", this.componentHovered, this);
const selected = em.get('selected'); const selected = em.get("selected");
em.listenTo(selected, 'add', (sel, c, opts) => this.selectAdd(selected.getComponent(sel), opts)); em.listenTo(selected, "add", (sel, c, opts) =>
em.listenTo(selected, 'remove', (sel, c, opts) => this.selectRemove(selected.getComponent(sel), opts)); this.selectAdd(selected.getComponent(sel), opts)
);
em.listenTo(selected, "remove", (sel, c, opts) =>
this.selectRemove(selected.getComponent(sel), opts)
);
} }
return this; return this;
} }
load(data) { load(data: any) {
return this.loadProjectData(data, { return this.loadProjectData(data, {
onResult: result => { onResult: (result: Component) => {
let wrapper = this.getWrapper(); let wrapper = this.getWrapper();
if (!wrapper) { if (!wrapper) {
this.em.get('PageManager').add({}, { select: true }); this.em.get("PageManager").add({}, { select: true });
wrapper = this.getWrapper(); wrapper = this.getWrapper();
} }
@ -280,6 +287,7 @@ export default class ComponentManager extends Module {
} else { } else {
const { components = [], ...rest } = result; const { components = [], ...rest } = result;
wrapper.set(rest); wrapper.set(rest);
//@ts-ignore
wrapper.components(components); wrapper.components(components);
} }
}, },
@ -295,8 +303,8 @@ export default class ComponentManager extends Module {
* @return {Object} * @return {Object}
* @private * @private
*/ */
getComponent() { getComponent(): Component {
const sel = this.em.get('PageManager').getSelected(); const sel = this.em.get("PageManager").getSelected();
const frame = sel && sel.getMainFrame(); const frame = sel && sel.getMainFrame();
return frame && frame.getComponent(); return frame && frame.getComponent();
} }
@ -342,9 +350,9 @@ export default class ComponentManager extends Module {
* // Remove comp2 * // Remove comp2
* wrapperChildren.remove(comp2); * wrapperChildren.remove(comp2);
*/ */
getComponents() { getComponents(): Components {
const wrp = this.getWrapper(); const wrp = this.getWrapper();
return wrp && wrp.get('components'); return wrp && wrp.get("components");
} }
/** /**
@ -376,7 +384,7 @@ export default class ComponentManager extends Module {
* attributes: { title: 'here' } * attributes: { title: 'here' }
* }); * });
*/ */
addComponent(component, opt = {}) { addComponent(component: Component, opt = {}) {
return this.getComponents().add(component, opt); return this.getComponents().add(component, opt);
} }
@ -388,7 +396,7 @@ export default class ComponentManager extends Module {
* @return {HTMLElement} * @return {HTMLElement}
*/ */
render() { render() {
return this.componentView.render().el; return this.componentView?.render().el;
} }
/** /**
@ -397,7 +405,8 @@ export default class ComponentManager extends Module {
*/ */
clear(opts = {}) { clear(opts = {}) {
const components = this.getComponents(); const components = this.getComponents();
components?.filter(Boolean).forEach(i => i.remove(opts)); //@ts-ignore
components?.filter(Boolean).forEach((i) => i.remove(opts));
return this; return this;
} }
@ -408,7 +417,7 @@ export default class ComponentManager extends Module {
* @return {this} * @return {this}
* @private * @private
*/ */
setComponents(components, opt = {}) { setComponents(components: Component, opt = {}) {
this.clear(opt).addComponent(components, opt); this.clear(opt).addComponent(components, opt);
} }
@ -419,23 +428,35 @@ export default class ComponentManager extends Module {
* @param {Object} methods Component methods * @param {Object} methods Component methods
* @return {this} * @return {this}
*/ */
addType(type, methods) { addType(type: string, methods: any) {
const { em } = this; const { em } = this;
const { model = {}, view = {}, isComponent, extend, extendView, extendFn = [], extendFnView = [] } = methods; const {
model = {},
view = {},
isComponent,
extend,
extendView,
extendFn = [],
extendFnView = [],
} = methods;
const compType = this.getType(type); const compType = this.getType(type);
const extendType = this.getType(extend); const extendType = this.getType(extend);
const extendViewType = this.getType(extendView); const extendViewType = this.getType(extendView);
const typeToExtend = extendType ? extendType : compType ? compType : this.getType('default'); const typeToExtend = extendType
? extendType
: compType
? compType
: this.getType("default");
const modelToExt = typeToExtend.model; const modelToExt = typeToExtend.model;
const viewToExt = extendViewType ? extendViewType.view : typeToExtend.view; const viewToExt = extendViewType ? extendViewType.view : typeToExtend.view;
// Function for extending source object methods // Function for extending source object methods
const getExtendedObj = (fns, target, srcToExt) => const getExtendedObj = (fns: any[], target: any, srcToExt: any) =>
fns.reduce((res, next) => { fns.reduce((res, next) => {
const fn = target[next]; const fn = target[next];
const parentFn = srcToExt.prototype[next]; const parentFn = srcToExt.prototype[next];
if (fn && parentFn) { if (fn && parentFn) {
res[next] = function (...args) { res[next] = (...args: any[]) => {
parentFn.bind(this)(...args); parentFn.bind(this)(...args);
fn.bind(this)(...args); fn.bind(this)(...args);
}; };
@ -444,23 +465,26 @@ export default class ComponentManager extends Module {
}, {}); }, {});
// If the model/view is a simple object I need to extend it // If the model/view is a simple object I need to extend it
if (typeof model === 'object') { if (typeof model === "object") {
methods.model = modelToExt.extend( methods.model = modelToExt.extend(
{ {
...model, ...model,
...getExtendedObj(extendFn, model, modelToExt), ...getExtendedObj(extendFn, model, modelToExt),
defaults: { defaults: {
...(result(modelToExt.prototype, 'defaults') || {}), ...(result(modelToExt.prototype, "defaults") || {}),
...(result(model, 'defaults') || {}), ...(result(model, "defaults") || {}),
}, },
}, },
{ {
isComponent: compType && !extendType && !isComponent ? modelToExt.isComponent : isComponent || (() => 0), isComponent:
compType && !extendType && !isComponent
? modelToExt.isComponent
: isComponent || (() => 0),
} }
); );
} }
if (typeof view === 'object') { if (typeof view === "object") {
methods.view = viewToExt.extend({ methods.view = viewToExt.extend({
...view, ...view,
...getExtendedObj(extendFnView, view, viewToExt), ...getExtendedObj(extendFnView, view, viewToExt),
@ -475,7 +499,7 @@ export default class ComponentManager extends Module {
this.componentTypes.unshift(methods); this.componentTypes.unshift(methods);
} }
const event = `component:type:${compType ? 'update' : 'add'}`; const event = `component:type:${compType ? "update" : "add"}`;
em?.trigger(event, compType || methods); em?.trigger(event, compType || methods);
return this; return this;
@ -487,7 +511,9 @@ export default class ComponentManager extends Module {
* @param {string} type Component ID * @param {string} type Component ID
* @return {Object} Component type definition, eg. `{ model: ..., view: ... }` * @return {Object} Component type definition, eg. `{ model: ..., view: ... }`
*/ */
getType(type) { getType(type: "default"): { id: string; model: any; view: any };
getType(type: string): { id: string; model: any; view: any } | undefined;
getType(type: string) {
var df = this.componentTypes; var df = this.componentTypes;
for (var it = 0; it < df.length; it++) { for (var it = 0; it < df.length; it++) {
@ -504,7 +530,7 @@ export default class ComponentManager extends Module {
* @param {string} type Component ID * @param {string} type Component ID
* @returns {Object|undefined} Removed component type, undefined otherwise * @returns {Object|undefined} Removed component type, undefined otherwise
*/ */
removeType(id) { removeType(id: string) {
const df = this.componentTypes; const df = this.componentTypes;
const type = this.getType(id); const type = this.getType(id);
if (!type) return; if (!type) return;
@ -521,23 +547,27 @@ export default class ComponentManager extends Module {
return this.componentTypes; return this.componentTypes;
} }
selectAdd(component, opts = {}) { selectAdd(component: Component, opts = {}) {
if (component) { if (component) {
component.set({ component.set({
status: 'selected', status: "selected",
}); });
['component:selected', 'component:toggled'].forEach(event => this.em.trigger(event, component, opts)); ["component:selected", "component:toggled"].forEach((event) =>
this.em.trigger(event, component, opts)
);
} }
} }
selectRemove(component, opts = {}) { selectRemove(component: Component, opts = {}) {
if (component) { if (component) {
const { em } = this; const { em } = this;
component.set({ component.set({
status: '', status: "",
state: '', state: "",
}); });
['component:deselected', 'component:toggled'].forEach(event => this.em.trigger(event, component, opts)); ["component:deselected", "component:toggled"].forEach((event) =>
this.em.trigger(event, component, opts)
);
} }
} }
@ -547,35 +577,35 @@ export default class ComponentManager extends Module {
*/ */
componentHovered() { componentHovered() {
const { em } = this; const { em } = this;
const model = em.get('componentHovered'); const model = em.get("componentHovered");
const previous = em.previous('componentHovered'); const previous = em.previous("componentHovered");
const state = 'hovered'; const state = "hovered";
// Deselect the previous component // Deselect the previous component
previous && previous &&
previous.get('status') == state && previous.get("status") == state &&
previous.set({ previous.set({
status: '', status: "",
state: '', state: "",
}); });
model && isEmpty(model.get('status')) && model.set('status', state); model && isEmpty(model.get("status")) && model.set("status", state);
} }
getShallowWrapper() { getShallowWrapper() {
let { shallow, em } = this; let { shallow, em } = this;
if (!shallow && em) { if (!shallow && em) {
const shallowEm = em.get('shallow'); const shallowEm = em.shallow;
if (!shallowEm) return; if (!shallowEm) return;
const domc = shallowEm.get('DomComponents'); const domc = shallowEm.get("DomComponents");
domc.componentTypes = this.componentTypes; domc.componentTypes = this.componentTypes;
shallow = domc.getWrapper(); shallow = domc.getWrapper();
if (shallow) { if (shallow) {
const events = [keyUpdate, keyUpdateInside].join(' '); const events = [keyUpdate, keyUpdateInside].join(" ");
shallow.on( shallow.on(
events, events,
debounce(() => shallow.components(''), 100) debounce(() => shallow?.components(""), 100)
); );
} }
this.shallow = shallow; this.shallow = shallow;
@ -595,7 +625,7 @@ export default class ComponentManager extends Module {
* * `2` - Target doesn't accept source. * * `2` - Target doesn't accept source.
* @private * @private
*/ */
canMove(target, source, index) { canMove(target: Component, source?: Component, index?: number) {
const at = index || index === 0 ? index : null; const at = index || index === 0 ? index : null;
const result = { const result = {
result: false, result: false,
@ -606,41 +636,47 @@ export default class ComponentManager extends Module {
if (!source) return result; if (!source) return result;
let srcModel = source?.toHTML ? source : null; //@ts-ignore
let srcModel = source.toHTML ? source : null;
if (!srcModel) { if (!srcModel) {
const wrapper = this.getShallowWrapper(); const wrapper = this.getShallowWrapper();
srcModel = wrapper?.append(source)[0]; srcModel = wrapper?.append(source)[0];
} }
//@ts-ignore
result.source = srcModel; result.source = srcModel;
if (!srcModel) return result; if (!srcModel) return result;
// Check if the source is draggable in the target // Check if the source is draggable in the target
let draggable = srcModel.get('draggable'); let draggable = srcModel.get("draggable");
if (isFunction(draggable)) { if (isFunction(draggable)) {
draggable = !!draggable(srcModel, target, at); draggable = !!draggable(srcModel, target, at);
} else { } else {
const el = target.getEl(); const el = target.getEl();
draggable = isArray(draggable) ? draggable.join(',') : draggable; draggable = isArray(draggable) ? draggable.join(",") : draggable;
draggable = isString(draggable) ? el?.matches(draggable) : draggable; draggable = isString(draggable) ? el?.matches(draggable) : draggable;
} }
if (!draggable) return { ...result, reason: 1 }; if (!draggable) return { ...result, reason: 1 };
// Check if the target accepts the source // Check if the target accepts the source
let droppable = target.get('droppable'); let droppable = target.get("droppable");
if (isFunction(droppable)) { if (isFunction(droppable)) {
droppable = !!droppable(srcModel, target, at); droppable = !!droppable(srcModel, target, at);
} else { } else {
if (droppable === false && target.isInstanceOf('text') && srcModel.get('textable')) { if (
droppable === false &&
target.isInstanceOf("text") &&
srcModel.get("textable")
) {
droppable = true; droppable = true;
} else { } else {
const el = srcModel.getEl(); const el = srcModel.getEl();
droppable = isArray(droppable) ? droppable.join(',') : droppable; droppable = isArray(droppable) ? droppable.join(",") : droppable;
droppable = isString(droppable) ? el?.matches(droppable) : droppable; droppable = isString(droppable) ? el?.matches(droppable) : droppable;
} }
} }
@ -654,14 +690,14 @@ export default class ComponentManager extends Module {
return this.componentsById; return this.componentsById;
} }
getById(id) { getById(id: string) {
return this.componentsById[id] || null; return this.componentsById[id] || null;
} }
destroy() { destroy() {
const all = this.allById(); const all = this.allById();
Object.keys(all).forEach(id => all[id] && all[id].remove()); Object.keys(all).forEach((id) => all[id] && all[id].remove());
this.componentView?.remove(); this.componentView?.remove();
[this.c, this.em, this.componentsById, this.component, this.componentView].forEach(i => (i = {})); [this.em, this.componentsById, this.componentView].forEach((i) => (i = {}));
} }
} }

4
src/dom_components/model/Component.js

@ -978,7 +978,7 @@ export default class Component extends StyleableModel {
/** /**
* Set new collection if `components` are provided, otherwise the * Set new collection if `components` are provided, otherwise the
* current collection is returned * current collection is returned
* @param {Component|String} [components] Component Definitions or HTML string * @param {Component|Component[]|String} [components] Component Definitions or HTML string
* @param {Object} [opts={}] Options, same as in `Component.append()` * @param {Object} [opts={}] Options, same as in `Component.append()`
* @returns {Collection|Array<[Component]>} * @returns {Collection|Array<[Component]>}
* @example * @example
@ -1560,7 +1560,7 @@ export default class Component extends StyleableModel {
* @param {Frame} frame Specific frame from which taking the element * @param {Frame} frame Specific frame from which taking the element
* @return {HTMLElement} * @return {HTMLElement}
*/ */
getEl(frame) { getEl(frame = undefined) {
const view = this.getView(frame); const view = this.getView(frame);
return view && view.el; return view && view.el;
} }

26
src/dom_components/model/Components.js

@ -40,7 +40,7 @@ const getComponentsFromDefs = (items, all = {}, opts = {}) => {
}); });
}; };
export default Backbone.Collection.extend({ export default class Components extends Backbone.Collection {
initialize(models, opt = {}) { initialize(models, opt = {}) {
this.opt = opt; this.opt = opt;
this.listenTo(this, 'add', this.onAdd); this.listenTo(this, 'add', this.onAdd);
@ -50,7 +50,7 @@ export default Backbone.Collection.extend({
this.config = config; this.config = config;
this.em = em; this.em = em;
this.domc = opt.domc || (em && em.get('DomComponents')); this.domc = opt.domc || (em && em.get('DomComponents'));
}, }
resetChildren(models, opts = {}) { resetChildren(models, opts = {}) {
const coll = this; const coll = this;
@ -60,7 +60,7 @@ export default Backbone.Collection.extend({
opts.keepIds = getComponentIds(prev).filter(pr => newIds.indexOf(pr) >= 0); opts.keepIds = getComponentIds(prev).filter(pr => newIds.indexOf(pr) >= 0);
toRemove.forEach(md => this.removeChildren(md, coll, opts)); toRemove.forEach(md => this.removeChildren(md, coll, opts));
models.each(model => this.onAdd(model)); models.each(model => this.onAdd(model));
}, }
resetFromString(input = '', opts = {}) { resetFromString(input = '', opts = {}) {
opts.keepIds = getComponentIds(this); opts.keepIds = getComponentIds(this);
@ -71,7 +71,7 @@ export default Backbone.Collection.extend({
const newCmps = getComponentsFromDefs(cmps, allByID, opts); const newCmps = getComponentsFromDefs(cmps, allByID, opts);
this.reset(newCmps, opts); this.reset(newCmps, opts);
this.em?.trigger('component:content', this.parent, opts, input); this.em?.trigger('component:content', this.parent, opts, input);
}, }
removeChildren(removed, coll, opts = {}) { removeChildren(removed, coll, opts = {}) {
// Removing a parent component can cause this function // Removing a parent component can cause this function
@ -123,7 +123,7 @@ export default Backbone.Collection.extend({
em.stopListening(removed); em.stopListening(removed);
em.stopListening(removed.get('classes')); em.stopListening(removed.get('classes'));
removed.__postRemove(); removed.__postRemove();
}, }
model(attrs, options) { model(attrs, options) {
const { opt } = options.collection; const { opt } = options.collection;
@ -155,7 +155,7 @@ export default Backbone.Collection.extend({
} }
return new model(attrs, options); return new model(attrs, options);
}, }
parseString(value, opt = {}) { parseString(value, opt = {}) {
const { em, domc } = this; const { em, domc } = this;
@ -173,7 +173,7 @@ export default Backbone.Collection.extend({
} }
return parsed.html; return parsed.html;
}, }
add(models, opt = {}) { add(models, opt = {}) {
opt.keepIds = [...(opt.keepIds || []), ...getComponentIds(opt.previousModels)]; opt.keepIds = [...(opt.keepIds || []), ...getComponentIds(opt.previousModels)];
@ -197,7 +197,7 @@ export default Backbone.Collection.extend({
const result = Backbone.Collection.prototype.add.apply(this, [models, opt]); const result = Backbone.Collection.prototype.add.apply(this, [models, opt]);
this.__firstAdd = result; this.__firstAdd = result;
return result; return result;
}, }
/** /**
* Process component definition. * Process component definition.
@ -250,7 +250,7 @@ export default Backbone.Collection.extend({
} }
return model; return model;
}, }
onAdd(model, c, opts = {}) { onAdd(model, c, opts = {}) {
const { domc, em } = this; const { domc, em } = this;
@ -267,9 +267,9 @@ export default Backbone.Collection.extend({
model.__postAdd({ recursive: 1 }); model.__postAdd({ recursive: 1 });
this.__onAddEnd(); this.__onAddEnd();
}, }
__onAddEnd: debounce(function () { __onAddEnd = debounce(function () {
// TODO to check symbols on load, probably this might be removed as symbols // TODO to check symbols on load, probably this might be removed as symbols
// are always recovered from the model // are always recovered from the model
// const { domc } = this; // const { domc } = this;
@ -295,5 +295,5 @@ export default Backbone.Collection.extend({
// }); // });
// }; // };
// onAll(toCheck); // onAll(toCheck);
}), });
}); }

293
src/editor/model/Editor.ts

@ -5,44 +5,44 @@ import {
toArray, toArray,
keys, keys,
bindAll, bindAll,
} from 'underscore'; } from "underscore";
import Backbone from 'backbone'; import Backbone from "backbone";
import $ from '../../utils/cash-dom'; import $ from "../../utils/cash-dom";
import Extender from '../../utils/extender'; import Extender from "../../utils/extender";
import { getModel, hasWin, isEmptyObj } from '../../utils/mixins'; import { getModel, hasWin, isEmptyObj } from "../../utils/mixins";
import { Model } from '../../common'; import { Model } from "../../common";
import Selected from './Selected'; import Selected from "./Selected";
import FrameView from '../../canvas/view/FrameView'; import FrameView from "../../canvas/view/FrameView";
import EditorModule from '..'; import EditorModule from "..";
import EditorView from '../view/EditorView'; import EditorView from "../view/EditorView";
import { IModule } from '../../abstract/Module'; import { IModule } from "../../abstract/Module";
//@ts-ignore //@ts-ignore
Backbone.$ = $; Backbone.$ = $;
const deps = [ const deps = [
require('utils'), require("utils"),
require('i18n'), require("i18n"),
require('keymaps'), require("keymaps"),
require('undo_manager'), require("undo_manager"),
require('storage_manager'), require("storage_manager"),
require('device_manager'), require("device_manager"),
require('parser'), require("parser"),
require('style_manager'), require("style_manager"),
require('selector_manager'), require("selector_manager"),
require('modal_dialog'), require("modal_dialog"),
require('code_manager'), require("code_manager"),
require('panels'), require("panels"),
require('rich_text_editor'), require("rich_text_editor"),
require('asset_manager'), require("asset_manager"),
require('css_composer'), require("css_composer"),
require('pages'), require("pages"),
require('trait_manager'), require("trait_manager"),
require('dom_components'), require("dom_components"),
require('navigator'), require("navigator"),
require('canvas'), require("canvas"),
require('commands'), require("commands"),
require('block_manager'), require("block_manager"),
]; ];
const ts_deps: any[] = []; const ts_deps: any[] = [];
@ -74,7 +74,7 @@ export default class EditorModel extends Model {
modules: [], modules: [],
toLoad: [], toLoad: [],
opened: {}, opened: {},
device: '', device: "",
}; };
} }
@ -88,33 +88,38 @@ export default class EditorModel extends Model {
view?: EditorView; view?: EditorView;
get storables(): any[] { get storables(): any[] {
return this.get('storables'); return this.get("storables");
} }
get modules(): IModule[] { get modules(): IModule[] {
return this.get('modules'); return this.get("modules");
} }
get toLoad(): any[] { get toLoad(): any[] {
return this.get('toLoad'); return this.get("toLoad");
} }
get selected(): Selected { get selected(): Selected {
return this.get('selected'); return this.get("selected");
}
get shallow(): EditorModel {
return this.get("shallow");
} }
constructor(conf = {}) { constructor(conf = {}) {
super(); super();
this._config = conf; this._config = conf;
const { config } = this; const { config } = this;
this.set('Config', conf); this.set("Config", conf);
this.set('modules', []); this.set("modules", []);
this.set('toLoad', []); this.set("toLoad", []);
this.set('storables', []); this.set("storables", []);
this.set('selected', new Selected()); this.set("selected", new Selected());
this.set('dmode', config.dragMode); this.set("dmode", config.dragMode);
const { el, log } = config; const { el, log } = config;
const toLog = log === true ? keys(logs) : isArray(log) ? log : []; const toLog = log === true ? keys(logs) : isArray(log) ? log : [];
bindAll(this, 'initBaseColorPicker'); bindAll(this, "initBaseColorPicker");
if (el && config.fromElement) { if (el && config.fromElement) {
config.components = el.innerHTML; config.components = el.innerHTML;
@ -125,7 +130,7 @@ export default class EditorModel extends Model {
res[next.nodeName] = next.nodeValue; res[next.nodeName] = next.nodeValue;
return res; return res;
}, {}) }, {})
: ''; : "";
// Move components to pages // Move components to pages
if (config.components && !config.pageManager) { if (config.components && !config.pageManager) {
@ -135,13 +140,13 @@ export default class EditorModel extends Model {
// Load modules // Load modules
deps.forEach((name) => this.loadModule(name)); deps.forEach((name) => this.loadModule(name));
ts_deps.forEach((name) => this.tsLoadModule(name)); ts_deps.forEach((name) => this.tsLoadModule(name));
this.on('change:componentHovered', this.componentHovered, this); this.on("change:componentHovered", this.componentHovered, this);
this.on('change:changesCount', this.updateChanges, this); this.on("change:changesCount", this.updateChanges, this);
this.on('change:readyLoad change:readyCanvas', this._checkReady, this); this.on("change:readyLoad change:readyCanvas", this._checkReady, this);
toLog.forEach((e) => this.listenLog(e)); toLog.forEach((e) => this.listenLog(e));
// Deprecations // Deprecations
[{ from: 'change:selectedComponent', to: 'component:toggled' }].forEach( [{ from: "change:selectedComponent", to: "component:toggled" }].forEach(
(event) => { (event) => {
const eventFrom = event.from; const eventFrom = event.from;
const eventTo = event.to; const eventTo = event.to;
@ -157,11 +162,11 @@ export default class EditorModel extends Model {
_checkReady() { _checkReady() {
if ( if (
this.get('readyLoad') && this.get("readyLoad") &&
this.get('readyCanvas') && this.get("readyCanvas") &&
!this.get('ready') !this.get("ready")
) { ) {
this.set('ready', true); this.set("ready", true);
} }
} }
@ -195,7 +200,7 @@ export default class EditorModel extends Model {
*/ */
loadOnStart() { loadOnStart() {
const { projectData, headless } = this.config; const { projectData, headless } = this.config;
const sm = this.get('StorageManager'); const sm = this.get("StorageManager");
// 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.
this.toLoad.forEach((mdl) => mdl.onLoad()); this.toLoad.forEach((mdl) => mdl.onLoad());
@ -203,7 +208,7 @@ export default class EditorModel extends Model {
// Stuff to do post load // Stuff to do post load
const postLoad = () => { const postLoad = () => {
this.modules.forEach((mdl) => mdl.postLoad && mdl.postLoad(this)); this.modules.forEach((mdl) => mdl.postLoad && mdl.postLoad(this));
this.set('readyLoad', 1); this.set("readyLoad", 1);
}; };
if (headless) { if (headless) {
@ -233,8 +238,8 @@ export default class EditorModel extends Model {
undoManager: false, undoManager: false,
}); });
// We only need to load a few modules // We only need to load a few modules
['PageManager', 'Canvas'].forEach((key) => shallow.get(key).onLoad()); ["PageManager", "Canvas"].forEach((key) => shallow.get(key).onLoad());
this.set('shallow', shallow); this.set("shallow", shallow);
} }
/** /**
@ -243,11 +248,11 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
updateChanges() { updateChanges() {
const stm = this.get('StorageManager'); const stm = this.get("StorageManager");
const changes = this.getDirtyCount(); const changes = this.getDirtyCount();
this.updateItr && clearTimeout(this.updateItr); this.updateItr && clearTimeout(this.updateItr);
//@ts-ignore //@ts-ignore
this.updateItr = setTimeout(() => this.trigger('update')); this.updateItr = setTimeout(() => this.trigger("update"));
if (this.config.noticeOnUnload) { if (this.config.noticeOnUnload) {
window.onbeforeunload = changes ? () => true : null; window.onbeforeunload = changes ? () => true : null;
@ -273,7 +278,7 @@ export default class EditorModel extends Model {
? config[name] ? config[name]
: config[Mod.name]; : config[Mod.name];
const cfg = cfgParent === true ? {} : cfgParent || {}; const cfg = cfgParent === true ? {} : cfgParent || {};
cfg.pStylePrefix = config.pStylePrefix || ''; cfg.pStylePrefix = config.pStylePrefix || "";
if (!isUndefined(cfgParent) && !cfgParent) { if (!isUndefined(cfgParent) && !cfgParent) {
cfg._disable = 1; cfg._disable = 1;
@ -324,11 +329,11 @@ export default class EditorModel extends Model {
this.initialize(opts); this.initialize(opts);
this.destroyed = false; this.destroyed = false;
} }
this.set('Editor', editor); this.set("Editor", editor);
} }
getEditor() { getEditor() {
return this.get('Editor'); return this.get("Editor");
} }
/** /**
@ -346,7 +351,7 @@ export default class EditorModel extends Model {
opt.temporary || opt.temporary ||
opt.noCount || opt.noCount ||
opt.avoidStore || opt.avoidStore ||
!this.get('ready') !this.get("ready")
) { ) {
return; return;
} }
@ -356,7 +361,7 @@ export default class EditorModel extends Model {
this.timedInterval = setTimeout(() => { this.timedInterval = setTimeout(() => {
const curr = this.getDirtyCount() || 0; const curr = this.getDirtyCount() || 0;
const { unset, ...opts } = opt; const { unset, ...opts } = opt;
this.set('changesCount', curr + 1, opts); this.set("changesCount", curr + 1, opts);
}, 0); }, 0);
} }
@ -372,9 +377,9 @@ export default class EditorModel extends Model {
* @private * @private
* */ * */
componentHovered(editor: any, component: any, options: any) { componentHovered(editor: any, component: any, options: any) {
const prev = this.previous('componentHovered'); const prev = this.previous("componentHovered");
prev && this.trigger('component:unhovered', prev, options); prev && this.trigger("component:unhovered", prev, options);
component && this.trigger('component:hovered', component, options); component && this.trigger("component:hovered", component, options);
} }
/** /**
@ -405,7 +410,7 @@ export default class EditorModel extends Model {
const { event } = opts; const { event } = opts;
const ctrlKey = event && (event.ctrlKey || event.metaKey); const ctrlKey = event && (event.ctrlKey || event.metaKey);
const { shiftKey } = event || {}; const { shiftKey } = event || {};
const els = (isArray(el) ? el : [el]).map(el => getModel(el, $)); const els = (isArray(el) ? el : [el]).map((el) => getModel(el, $));
const selected = this.getSelectedAll(); const selected = this.getSelectedAll();
const mltSel = this.getConfig().multipleSelection; const mltSel = this.getConfig().multipleSelection;
let added; let added;
@ -413,19 +418,19 @@ export default class EditorModel extends Model {
// If an array is passed remove all selected // If an array is passed remove all selected
// expect those yet to be selected // expect those yet to be selected
const multiple = isArray(el); const multiple = isArray(el);
multiple && this.removeSelected(selected.filter(s => !contains(els, s))); multiple && this.removeSelected(selected.filter((s) => !contains(els, s)));
els.forEach((el) => { els.forEach((el) => {
let model = getModel(el, undefined); let model = getModel(el, undefined);
if (model) { if (model) {
this.trigger('component:select:before', model, opts); this.trigger("component:select:before", model, opts);
// Check for valid selectable // Check for valid selectable
if (!model.get('selectable') || opts.abort) { if (!model.get("selectable") || opts.abort) {
if (opts.useValid) { if (opts.useValid) {
let parent = model.parent(); let parent = model.parent();
while (parent && !parent.get('selectable')) while (parent && !parent.get("selectable"))
parent = parent.parent(); parent = parent.parent();
model = parent; model = parent;
} else { } else {
@ -438,7 +443,7 @@ export default class EditorModel extends Model {
if (ctrlKey && mltSel) { if (ctrlKey && mltSel) {
return this.toggleSelected(model); return this.toggleSelected(model);
} else if (shiftKey && mltSel) { } else if (shiftKey && mltSel) {
this.clearSelection(this.get('Canvas').getWindow()); this.clearSelection(this.get("Canvas").getWindow());
const coll = model.collection; const coll = model.collection;
const index = model.index(); const index = model.index();
let min: number | undefined, max: number | undefined; let min: number | undefined, max: number | undefined;
@ -491,12 +496,12 @@ export default class EditorModel extends Model {
const model = getModel(el, $); const model = getModel(el, $);
const models = isArray(model) ? model : [model]; const models = isArray(model) ? model : [model];
models.forEach(model => { models.forEach((model) => {
if (model && !model.get('selectable')) return; if (model && !model.get("selectable")) return;
const { selected } = this; const { selected } = this;
opts.forceChange && this.removeSelected(model, opts); opts.forceChange && this.removeSelected(model, opts);
selected.addComponent(model, opts); selected.addComponent(model, opts);
model && this.trigger('component:select', model, opts); model && this.trigger("component:select", model, opts);
}); });
} }
@ -520,7 +525,7 @@ export default class EditorModel extends Model {
const model = getModel(el, $); const model = getModel(el, $);
const models = isArray(model) ? model : [model]; const models = isArray(model) ? model : [model];
models.forEach(model => { models.forEach((model) => {
if (this.selected.hasComponent(model)) { if (this.selected.hasComponent(model)) {
this.removeSelected(model, opts); this.removeSelected(model, opts);
} else { } else {
@ -536,21 +541,21 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
setHovered(el: any, opts: any = {}) { setHovered(el: any, opts: any = {}) {
if (!el) return this.set('componentHovered', ''); if (!el) return this.set("componentHovered", "");
const ev = 'component:hover'; const ev = "component:hover";
let model = getModel(el, undefined); let model = getModel(el, undefined);
if (!model) return; if (!model) return;
opts.forceChange && this.set('componentHovered', ''); opts.forceChange && this.set("componentHovered", "");
this.trigger(`${ev}:before`, model, opts); this.trigger(`${ev}:before`, model, opts);
// Check for valid hoverable // Check for valid hoverable
if (!model.get('hoverable')) { if (!model.get("hoverable")) {
if (opts.useValid && !opts.abort) { if (opts.useValid && !opts.abort) {
let parent = model && model.parent(); let parent = model && model.parent();
while (parent && !parent.get('hoverable')) parent = parent.parent(); while (parent && !parent.get("hoverable")) parent = parent.parent();
model = parent; model = parent;
} else { } else {
return; return;
@ -558,13 +563,13 @@ export default class EditorModel extends Model {
} }
if (!opts.abort) { if (!opts.abort) {
this.set('componentHovered', model, opts); this.set("componentHovered", model, opts);
this.trigger(ev, model, opts); this.trigger(ev, model, opts);
} }
} }
getHovered() { getHovered() {
return this.get('componentHovered'); return this.get("componentHovered");
} }
/** /**
@ -575,7 +580,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
setComponents(components: any, opt = {}) { setComponents(components: any, opt = {}) {
return this.get('DomComponents').setComponents(components, opt); return this.get("DomComponents").setComponents(components, opt);
} }
/** /**
@ -584,13 +589,13 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
getComponents() { getComponents() {
var cmp = this.get('DomComponents'); var cmp = this.get("DomComponents");
var cm = this.get('CodeManager'); var cm = this.get("CodeManager");
if (!cmp || !cm) return; if (!cmp || !cm) return;
var wrp = cmp.getComponents(); var wrp = cmp.getComponents();
return cm.getCode(wrp, 'json'); return cm.getCode(wrp, "json");
} }
/** /**
@ -601,7 +606,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
setStyle(style: any, opt = {}) { setStyle(style: any, opt = {}) {
const cssc = this.get('CssComposer'); const cssc = this.get("CssComposer");
cssc.clear(opt); cssc.clear(opt);
cssc.getAll().add(style, opt); cssc.getAll().add(style, opt);
return this; return this;
@ -624,7 +629,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
getStyle() { getStyle() {
return this.get('CssComposer').getAll(); return this.get("CssComposer").getAll();
} }
/** /**
@ -633,7 +638,7 @@ export default class EditorModel extends Model {
* @returns {this} * @returns {this}
*/ */
setState(value: string) { setState(value: string) {
this.set('state', value); this.set("state", value);
return this; return this;
} }
@ -642,7 +647,7 @@ export default class EditorModel extends Model {
* @returns {String} * @returns {String}
*/ */
getState() { getState() {
return this.get('state') || ''; return this.get("state") || "";
} }
/** /**
@ -654,15 +659,15 @@ export default class EditorModel extends Model {
getHtml(opts: any = {}) { getHtml(opts: any = {}) {
const { config } = this; const { config } = this;
const { optsHtml } = config; const { optsHtml } = config;
const js = config.jsInHtml ? this.getJs(opts) : ''; const js = config.jsInHtml ? this.getJs(opts) : "";
const cmp = opts.component || this.get('DomComponents').getComponent(); const cmp = opts.component || this.get("DomComponents").getComponent();
let html = cmp let html = cmp
? this.get('CodeManager').getCode(cmp, 'html', { ? this.get("CodeManager").getCode(cmp, "html", {
...optsHtml, ...optsHtml,
...opts, ...opts,
}) })
: ''; : "";
html += js ? `<script>${js}</script>` : ''; html += js ? `<script>${js}</script>` : "";
return html; return html;
} }
@ -679,18 +684,18 @@ export default class EditorModel extends Model {
const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles) const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles)
? opts.keepUnusedStyles ? opts.keepUnusedStyles
: config.keepUnusedStyles; : config.keepUnusedStyles;
const cssc = this.get('CssComposer'); const cssc = this.get("CssComposer");
const wrp = opts.component || this.get('DomComponents').getComponent(); const wrp = opts.component || this.get("DomComponents").getComponent();
const protCss = !avoidProt ? config.protectedCss : ''; const protCss = !avoidProt ? config.protectedCss : "";
const css = const css =
wrp && wrp &&
this.get('CodeManager').getCode(wrp, 'css', { this.get("CodeManager").getCode(wrp, "css", {
cssc, cssc,
keepUnusedStyles, keepUnusedStyles,
...optsCss, ...optsCss,
...opts, ...opts,
}); });
return wrp ? (opts.json ? css : protCss + css) : ''; return wrp ? (opts.json ? css : protCss + css) : "";
} }
/** /**
@ -699,8 +704,8 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
getJs(opts: any = {}) { getJs(opts: any = {}) {
var wrp = opts.component || this.get('DomComponents').getWrapper(); var wrp = opts.component || this.get("DomComponents").getWrapper();
return wrp ? this.get('CodeManager').getCode(wrp, 'js').trim() : ''; return wrp ? this.get("CodeManager").getCode(wrp, "js").trim() : "";
} }
/** /**
@ -709,7 +714,7 @@ export default class EditorModel extends Model {
*/ */
async store(options?: any) { async store(options?: any) {
const data = this.storeData(); const data = this.storeData();
await this.get('StorageManager').store(data, options); await this.get("StorageManager").store(data, options);
this.clearDirtyCount(); this.clearDirtyCount();
return data; return data;
} }
@ -719,7 +724,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
async load(options?: any) { async load(options?: any) {
const result = await this.get('StorageManager').load(options); const result = await this.get("StorageManager").load(options);
this.loadData(result); this.loadData(result);
return result; return result;
} }
@ -728,7 +733,7 @@ export default class EditorModel extends Model {
let result = {}; let result = {};
// Sync content if there is an active RTE // Sync content if there is an active RTE
const editingCmp = this.getEditing(); const editingCmp = this.getEditing();
editingCmp && editingCmp.trigger('sync:content', { noCount: true }); editingCmp && editingCmp.trigger("sync:content", { noCount: true });
this.storables.forEach((m) => { this.storables.forEach((m) => {
result = { ...result, ...m.store(1) }; result = { ...result, ...m.store(1) };
@ -750,8 +755,8 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
getDeviceModel() { getDeviceModel() {
var name = this.get('device'); var name = this.get("device");
return this.get('DeviceManager').get(name); return this.get("DeviceManager").get(name);
} }
/** /**
@ -760,7 +765,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
runDefault(opts = {}) { runDefault(opts = {}) {
var command = this.get('Commands').get(this.config.defaultCommand); var command = this.get("Commands").get(this.config.defaultCommand);
if (!command || this.defaultRunning) return; if (!command || this.defaultRunning) return;
command.stop(this, this, opts); command.stop(this, this, opts);
command.run(this, this, opts); command.run(this, this, opts);
@ -773,7 +778,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
stopDefault(opts = {}) { stopDefault(opts = {}) {
const commands = this.get('Commands'); const commands = this.get("Commands");
const command = commands.get(this.config.defaultCommand); const command = commands.get(this.config.defaultCommand);
if (!command || !this.defaultRunning) return; if (!command || !this.defaultRunning) return;
command.stop(this, this, opts); command.stop(this, this, opts);
@ -785,9 +790,9 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
refreshCanvas(opts: any = {}) { refreshCanvas(opts: any = {}) {
this.set('canvasOffset', null); this.set("canvasOffset", null);
this.set('canvasOffset', this.get('Canvas').getOffset()); this.set("canvasOffset", this.get("Canvas").getOffset());
opts.tools && this.trigger('canvas:updateTools'); opts.tools && this.trigger("canvas:updateTools");
} }
/** /**
@ -810,8 +815,8 @@ export default class EditorModel extends Model {
const device = this.getDeviceModel(); const device = this.getDeviceModel();
const condition = config.mediaCondition; const condition = config.mediaCondition;
const preview = config.devicePreviewMode; const preview = config.devicePreviewMode;
const width = device && device.get('widthMedia'); const width = device && device.get("widthMedia");
return device && width && !preview ? `(${condition}: ${width})` : ''; return device && width && !preview ? `(${condition}: ${width})` : "";
} }
/** /**
@ -819,15 +824,15 @@ export default class EditorModel extends Model {
* @return {Component} * @return {Component}
*/ */
getWrapper() { getWrapper() {
return this.get('DomComponents').getWrapper(); return this.get("DomComponents").getWrapper();
} }
setCurrentFrame(frameView: FrameView) { setCurrentFrame(frameView: FrameView) {
return this.set('currentFrame', frameView); return this.set("currentFrame", frameView);
} }
getCurrentFrame(): FrameView { getCurrentFrame(): FrameView {
return this.get('currentFrame'); return this.get("currentFrame");
} }
getCurrentFrameModel() { getCurrentFrameModel() {
@ -836,7 +841,7 @@ export default class EditorModel extends Model {
getIcon(icon: string) { getIcon(icon: string) {
const icons = this.config.icons || {}; const icons = this.config.icons || {};
return icons[icon] || ''; return icons[icon] || "";
} }
/** /**
@ -845,27 +850,27 @@ export default class EditorModel extends Model {
* @return {number} * @return {number}
*/ */
getDirtyCount(): number { getDirtyCount(): number {
return this.get('changesCount'); return this.get("changesCount");
} }
clearDirtyCount() { clearDirtyCount() {
return this.set('changesCount', 0); return this.set("changesCount", 0);
} }
getZoomDecimal() { getZoomDecimal() {
return this.get('Canvas').getZoomDecimal(); return this.get("Canvas").getZoomDecimal();
} }
getZoomMultiplier() { getZoomMultiplier() {
return this.get('Canvas').getZoomMultiplier(); return this.get("Canvas").getZoomMultiplier();
} }
setDragMode(value: string) { setDragMode(value: string) {
return this.set('dmode', value); return this.set("dmode", value);
} }
t(...args: any[]) { t(...args: any[]) {
const i18n = this.get('I18n'); const i18n = this.get("I18n");
return i18n?.t(...args); return i18n?.t(...args);
} }
@ -874,7 +879,7 @@ export default class EditorModel extends Model {
* @returns {Boolean} * @returns {Boolean}
*/ */
inAbsoluteMode() { inAbsoluteMode() {
return this.get('dmode') === 'absolute'; return this.get("dmode") === "absolute";
} }
/** /**
@ -884,7 +889,7 @@ export default class EditorModel extends Model {
const { config, view } = this; const { config, view } = this;
const editor = this.getEditor(); const editor = this.getEditor();
const { editors = [] } = config.grapesjs || {}; const { editors = [] } = config.grapesjs || {};
const shallow = this.get('shallow'); const shallow = this.get("shallow");
shallow?.destroyAll(); shallow?.destroyAll();
this.stopListening(); this.stopListening();
this.stopDefault(); this.stopDefault();
@ -895,9 +900,9 @@ export default class EditorModel extends Model {
view && view.remove(); view && view.remove();
this.clear({ silent: true }); this.clear({ silent: true });
this.destroyed = true; this.destroyed = true;
['_config', 'view', '_previousAttributes', '_events', '_listeners'].forEach( ["_config", "view", "_previousAttributes", "_events", "_listeners"].forEach(
//@ts-ignore //@ts-ignore
i => (this[i] = {}) (i) => (this[i] = {})
); );
editors.splice(editors.indexOf(editor), 1); editors.splice(editors.indexOf(editor), 1);
//@ts-ignore //@ts-ignore
@ -905,22 +910,22 @@ export default class EditorModel extends Model {
} }
getEditing() { getEditing() {
const res = this.get('editing'); const res = this.get("editing");
return (res && res.model) || null; return (res && res.model) || null;
} }
setEditing(value: boolean) { setEditing(value: boolean) {
this.set('editing', value); this.set("editing", value);
return this; return this;
} }
isEditing() { isEditing() {
return !!this.get('editing'); return !!this.get("editing");
} }
log(msg: string, opts: any = {}) { log(msg: string, opts: any = {}) {
const { ns, level = 'debug' } = opts; const { ns, level = "debug" } = opts;
this.trigger('log', msg, opts); this.trigger("log", msg, opts);
level && this.trigger(`log:${level}`, msg, opts); level && this.trigger(`log:${level}`, msg, opts);
if (ns) { if (ns) {
@ -931,15 +936,15 @@ export default class EditorModel extends Model {
} }
logInfo(msg: string, opts?: any) { logInfo(msg: string, opts?: any) {
this.log(msg, { ...opts, level: 'info' }); this.log(msg, { ...opts, level: "info" });
} }
logWarning(msg: string, opts?: any) { logWarning(msg: string, opts?: any) {
this.log(msg, { ...opts, level: 'warning' }); this.log(msg, { ...opts, level: "warning" });
} }
logError(msg: string, opts?: any) { logError(msg: string, opts?: any) {
this.log(msg, { ...opts, level: 'error' }); this.log(msg, { ...opts, level: "error" });
} }
initBaseColorPicker(el: any, opts = {}) { initBaseColorPicker(el: any, opts = {}) {
@ -951,13 +956,13 @@ export default class EditorModel extends Model {
//@ts-ignore //@ts-ignore
return $(el).spectrum({ return $(el).spectrum({
containerClassName: `${ppfx}one-bg ${ppfx}two-color`, containerClassName: `${ppfx}one-bg ${ppfx}two-color`,
appendTo: elToAppend || 'body', appendTo: elToAppend || "body",
maxSelectionSize: 8, maxSelectionSize: 8,
showPalette: true, showPalette: true,
palette: [], palette: [],
showAlpha: true, showAlpha: true,
chooseText: 'Ok', chooseText: "Ok",
cancelText: '⨯', cancelText: "⨯",
...opts, ...opts,
...colorPicker, ...colorPicker,
}); });
@ -970,7 +975,7 @@ export default class EditorModel extends Model {
*/ */
skip(clb: Function) { skip(clb: Function) {
this.__skip = true; this.__skip = true;
const um = this.get('UndoManager'); const um = this.get("UndoManager");
um ? um.skip(clb) : clb(); um ? um.skip(clb) : clb();
this.__skip = false; this.__skip = false;
} }
@ -984,7 +989,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
data(el: any, name: string, value: any) { data(el: any, name: string, value: any) {
const varName = '_gjs-data'; const varName = "_gjs-data";
if (!el[varName]) { if (!el[varName]) {
el[varName] = {}; el[varName] = {};

4
test/specs/code_manager/model/CodeModels.js

@ -15,7 +15,7 @@ describe('HtmlGenerator', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor(); em = new Editor();
obj = new HtmlGenerator(); obj = new HtmlGenerator();
dcomp = new DomComponents(); dcomp = new DomComponents(em);
comp = new Component( comp = new Component(
{}, {},
{ {
@ -73,7 +73,7 @@ describe('CssGenerator', () => {
cc = em.get('CssComposer'); cc = em.get('CssComposer');
obj = new CssGenerator(); obj = new CssGenerator();
dcomp = new DomComponents(); dcomp = new DomComponents(em);
comp = new Component( comp = new Component(
{}, {},
{ {

2
test/specs/dom_components/index.js

@ -54,7 +54,7 @@ describe('DOM Components', () => {
storeWrapper: 1, storeWrapper: 1,
}; };
obj = em.get('DomComponents'); obj = em.get('DomComponents');
// obj = new DomComponents().init(config); // obj = new DomComponents(em).init(config);
}); });
afterEach(() => { afterEach(() => {

2
test/specs/dom_components/model/Component.js

@ -21,7 +21,7 @@ describe('Component', () => {
em = new Editor({ avoidDefaults: true }); em = new Editor({ avoidDefaults: true });
dcomp = em.get('DomComponents'); dcomp = em.get('DomComponents');
em.get('PageManager').onLoad(); em.get('PageManager').onLoad();
// dcomp = new DomComponents(); // dcomp = new DomComponents(em);
compOpts = { compOpts = {
em, em,
componentTypes: dcomp.componentTypes, componentTypes: dcomp.componentTypes,

2
test/specs/dom_components/view/ComponentV.js

@ -14,7 +14,7 @@ describe('ComponentView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { compOpts = {
em, em,
componentTypes: dcomp.componentTypes, componentTypes: dcomp.componentTypes,

6
test/specs/dom_components/view/ComponentsView.js

@ -11,16 +11,16 @@ describe('ComponentsView', () => {
const em = new Editor(); const em = new Editor();
beforeEach(() => { beforeEach(() => {
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { compOpts = {
em, em,
componentTypes: dcomp.componentTypes componentTypes: dcomp.componentTypes,
}; };
model = new Components([], compOpts); model = new Components([], compOpts);
view = new ComponentsView({ view = new ComponentsView({
collection: model, collection: model,
componentTypes: dcomp.componentTypes, componentTypes: dcomp.componentTypes,
config: { em } config: { em },
}); });
document.body.innerHTML = '<div id="fixtures"></div>'; document.body.innerHTML = '<div id="fixtures"></div>';
document.body.querySelector('#fixtures').appendChild(view.render().el); document.body.querySelector('#fixtures').appendChild(view.render().el);

4
test/specs/parser/model/ParserHtml.js

@ -1,12 +1,14 @@
import ParserHtml from 'parser/model/ParserHtml'; import ParserHtml from 'parser/model/ParserHtml';
import ParserCss from 'parser/model/ParserCss'; import ParserCss from 'parser/model/ParserCss';
import DomComponents from 'dom_components'; import DomComponents from 'dom_components';
import Editor from 'editor/model/Editor';
describe('ParserHtml', () => { describe('ParserHtml', () => {
var obj; var obj;
beforeEach(() => { beforeEach(() => {
var dom = new DomComponents(); const em = new Editor({});
var dom = new DomComponents(em);
obj = new ParserHtml({ obj = new ParserHtml({
textTags: ['br', 'b', 'i', 'u'], textTags: ['br', 'b', 'i', 'u'],
pStylePrefix: 'gjs-', pStylePrefix: 'gjs-',

2
test/specs/style_manager/view/PropertyColorView.js

@ -24,7 +24,7 @@ describe('PropertyColorView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { em, componentTypes: dcomp.componentTypes }; compOpts = { em, componentTypes: dcomp.componentTypes };
target = new Component({}, compOpts); target = new Component({}, compOpts);
component = new Component({}, compOpts); component = new Component({}, compOpts);

2
test/specs/style_manager/view/PropertyCompositeView.js

@ -34,7 +34,7 @@ describe('PropertyCompositeView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { em, componentTypes: dcomp.componentTypes }; compOpts = { em, componentTypes: dcomp.componentTypes };
target = new Component({}, compOpts); target = new Component({}, compOpts);
component = new Component({}, compOpts); component = new Component({}, compOpts);

2
test/specs/style_manager/view/PropertyIntegerView.js

@ -24,7 +24,7 @@ describe('PropertyNumberView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { em, componentTypes: dcomp.componentTypes }; compOpts = { em, componentTypes: dcomp.componentTypes };
target = new Component({}, compOpts); target = new Component({}, compOpts);
component = new Component({}, compOpts); component = new Component({}, compOpts);

2
test/specs/style_manager/view/PropertyRadioView.js

@ -28,7 +28,7 @@ describe('PropertyRadioView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { em, componentTypes: dcomp.componentTypes }; compOpts = { em, componentTypes: dcomp.componentTypes };
target = new Component({}, compOpts); target = new Component({}, compOpts);
component = new Component({}, compOpts); component = new Component({}, compOpts);

2
test/specs/style_manager/view/PropertySelectView.js

@ -24,7 +24,7 @@ describe('PropertySelectView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { em, componentTypes: dcomp.componentTypes }; compOpts = { em, componentTypes: dcomp.componentTypes };
target = new Component({}, compOpts); target = new Component({}, compOpts);
component = new Component({}, compOpts); component = new Component({}, compOpts);

2
test/specs/style_manager/view/PropertyStackView.js

@ -32,7 +32,7 @@ describe('PropertyStackView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { em, componentTypes: dcomp.componentTypes }; compOpts = { em, componentTypes: dcomp.componentTypes };
target = new Component({}, compOpts); target = new Component({}, compOpts);
component = new Component({}, compOpts); component = new Component({}, compOpts);

2
test/specs/style_manager/view/PropertyView.js

@ -19,7 +19,7 @@ describe('PropertyView', () => {
beforeEach(() => { beforeEach(() => {
em = new Editor({}); em = new Editor({});
dcomp = new DomComponents(); dcomp = new DomComponents(em);
compOpts = { em, componentTypes: dcomp.componentTypes }; compOpts = { em, componentTypes: dcomp.componentTypes };
target = new Component({}, compOpts); target = new Component({}, compOpts);
component = new Component({}, compOpts); component = new Component({}, compOpts);

Loading…
Cancel
Save