From 6ddb5f8e9e8f4d5c09c6aae5738a5c5ef4f3acbf Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Tue, 10 May 2022 15:09:13 +0200 Subject: [PATCH] Revert "Merge pull request #4316 from xQwexx/canvas-module" This reverts commit 68c60ea47ebd0c903c00881d9d5faf5c76e1bdb2, reversing changes made to 706bf4fa2e73862c0e0ee2735179d35d4a36cee7. --- src/abstract/DomainViews.ts | 102 --------- src/abstract/Model.ts | 2 +- src/abstract/Module.ts | 10 +- src/abstract/View.ts | 20 +- src/canvas/{index.ts => index.js} | 179 ++++++++------- src/canvas/model/Canvas.ts | 32 +-- src/canvas/model/Frame.ts | 40 ++-- src/canvas/model/Frames.ts | 5 +- .../view/{CanvasView.ts => CanvasView.js} | 205 +++++++----------- .../view/{FrameView.ts => FrameView.js} | 130 +++++------ .../{FrameWrapView.ts => FrameWrapView.js} | 66 +++--- src/canvas/view/FramesView.js | 21 ++ src/canvas/view/FramesView.ts | 26 --- src/dom_components/model/Components.js | 26 +-- src/dom_components/view/ComponentView.js | 82 +++---- src/editor/index.ts | 19 +- src/editor/model/Editor.ts | 5 +- src/pages/model/Page.ts | 7 +- src/utils/dom.js | 15 +- src/utils/mixins.js | 15 +- 20 files changed, 420 insertions(+), 587 deletions(-) delete mode 100644 src/abstract/DomainViews.ts rename src/canvas/{index.ts => index.js} (78%) rename src/canvas/view/{CanvasView.ts => CanvasView.js} (64%) rename src/canvas/view/{FrameView.ts => FrameView.js} (78%) rename src/canvas/view/{FrameWrapView.ts => FrameWrapView.js} (83%) create mode 100644 src/canvas/view/FramesView.js delete mode 100644 src/canvas/view/FramesView.ts diff --git a/src/abstract/DomainViews.ts b/src/abstract/DomainViews.ts deleted file mode 100644 index 0750cd2fc..000000000 --- a/src/abstract/DomainViews.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { includes } from 'underscore'; -import Backbone from 'backbone'; -import View from './View'; -import Model from './Model'; -/*interface DomainView{ - constructor(model: TModel): TView -}*/ -type TModel = TCollection extends Backbone.Collection? TModel: Model; - -export default abstract class DomainViews, TItemView extends View> extends View> { - // Defines the View per type - itemsView = ''; - - protected itemType = 'type'; - - reuseView = false; - - viewCollection: TItemView[] = []; - constructor(opts: any = {}, autoAdd = false) { - super(opts); - autoAdd && this.listenTo(this.collection, 'add', this.addTo); - } - - /** - * Add new model to the collection - * @param {Model} model - * @private - * */ - private addTo(model: TModel) { - this.add(model); - } - - private itemViewNotFound(type: string) { - /*const { em, ns } = this; - const warn = `${ns ? `[${ns}]: ` : ''}'${type}' type not found`; - em?.logWarning(warn);*/ - } - protected abstract renderView(model: TModel, itemType: string): TItemView; - - /** - * Render new model inside the view - * @param {Model} model - * @param {Object} fragment Fragment collection - * @private - * */ - private add(model: TModel, fragment?: DocumentFragment) { - const { config, reuseView, viewCollection, itemsView = {} } = this; - var frag = fragment || null; - var typeField = model.get(this.itemType); - let view; - - //@ts-ignore - if (model.view && reuseView) { - //@ts-ignore - view = model.view; - } else { - view = this.renderView(model, typeField); - } - - viewCollection.push(view); - const rendered = view.render().el; - - if (frag) frag.appendChild(rendered); - else this.$el.append(rendered); - } - - render() { - var frag = document.createDocumentFragment(); - this.clearItems(); - this.$el.empty(); - - if (this.collection.length) - this.collection.each((model) => { - this.add(model, frag); - }, this); - - this.$el.append(frag); - this.onRender(); - return this; - } - - onRender() {} - - onRemoveBefore(items: TItemView[], opts: any) {} - onRemove(items: TItemView[], opts: any) {} - - remove(opts: any = {}) { - const { viewCollection } = this; - this.onRemoveBefore(viewCollection, opts); - this.clearItems(); - Backbone.View.prototype.remove.apply(this, opts); - this.onRemove(viewCollection, opts); - return this; - } - - clearItems() { - const items = this.viewCollection || []; - // TODO Traits do not update the target anymore - // items.forEach(item => item.remove()); - // this.items = []; - } -} diff --git a/src/abstract/Model.ts b/src/abstract/Model.ts index 324e27036..6a1bc3194 100644 --- a/src/abstract/Model.ts +++ b/src/abstract/Model.ts @@ -26,7 +26,7 @@ export default class Model< return this._module.config; } - public get em() { + protected get em() { return this._module.em; } } diff --git a/src/abstract/Module.ts b/src/abstract/Module.ts index 113fb2ae7..5e1a5f074 100644 --- a/src/abstract/Module.ts +++ b/src/abstract/Module.ts @@ -20,7 +20,7 @@ export interface IBaseModule { } export interface ModuleConfig { - //name: string; + name: string; stylePrefix?: string; } @@ -40,18 +40,20 @@ export default abstract class Module cls: any[] = []; events: any; - constructor(em: EditorModel, moduleName: string, defaults?: T) { + constructor(em: EditorModel, moduleName: string) { this._em = em; 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 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 = {...defaults, ...cfg}; + this._config = cfg; } public get em() { diff --git a/src/abstract/View.ts b/src/abstract/View.ts index 48034ad05..f1aaa9170 100644 --- a/src/abstract/View.ts +++ b/src/abstract/View.ts @@ -1,29 +1,19 @@ -import Backbone from "backbone"; -import Model from "./Model"; -import Module, { IBaseModule } from "./Module"; +import Backbone from 'backbone'; +import Model from './Model'; export default class View< TModel extends Model = Model, TElement extends Element = HTMLElement > extends Backbone.View { protected get pfx() { - return (this.em.config as any).stylePrefix || ""; + return (this.model.module.em.config as any).stylePrefix || ''; } protected get ppfx() { - return this.pfx + this.config.stylePrefix || ""; - } - - protected get module(): TModel extends Model? M: unknown { - //console.log((this.collection.first as any).module) - return this.model?.module ?? (this.collection as any).module; + return this.pfx + this.model.module.config.stylePrefix || ''; } protected get em() { - return this.module.em; - } - - protected get config(): TModel extends Model ? (M extends IBaseModule ? C : unknown) : unknown{ - return this.module.config as any + return this.model.module.em; } } diff --git a/src/canvas/index.ts b/src/canvas/index.js similarity index 78% rename from src/canvas/index.ts rename to src/canvas/index.js index 841e8b595..f71e56f55 100644 --- a/src/canvas/index.ts +++ b/src/canvas/index.js @@ -47,49 +47,49 @@ * @module Canvas */ -import { AddOptions } from 'backbone'; import { isUndefined } from 'underscore'; -import { Module } from '../abstract'; -import ComponentView from '../dom_components/view/ComponentView'; -import EditorModel from '../editor/model/Editor'; import { getElement, getViewEl } from '../utils/mixins'; import defaults from './config/config'; import Canvas from './model/Canvas'; import Frame from './model/Frame'; import CanvasView from './view/CanvasView'; -import FrameView from './view/FrameView'; -export default class CanvasModule extends Module { +export default class CanvasModule { /** * Used inside RTE * @private */ - getCanvasView(): CanvasView { - return this.canvasView as any; + getCanvasView() { + return this.canvasView; } - //name = 'Canvas'; - canvas: Canvas; - model: Canvas; - private canvasView?: CanvasView; + name = 'Canvas'; + c = {}; + canvas; + canvasView; /** * Initialize module. Automatically called with a new instance of the editor * @param {Object} config Configurations * @private */ - constructor(em: EditorModel) { - super(em, "Canvas", defaults) + init(config = {}) { + this.c = { + ...defaults, + ...config, + module: this, + }; - this.canvas = new Canvas(this); + this.em = this.c.em; + const { scripts, styles } = this.c; + const ppfx = this.c.pStylePrefix; + if (ppfx) this.c.stylePrefix = ppfx + this.c.stylePrefix; + this.canvas = new Canvas({ scripts, styles }, config); this.model = this.canvas; this.startAutoscroll = this.startAutoscroll.bind(this); this.stopAutoscroll = this.stopAutoscroll.bind(this); return this; } - init(){ - - } onLoad() { this.model.init(); @@ -99,15 +99,25 @@ export default class CanvasModule extends Module { return this.canvas; } + /** + * Get the configuration object + * @returns {Object} Configuration object + * @example + * console.log(canvas.getConfig()) + */ + getConfig() { + return this.c; + } + /** * Get the canvas element * @returns {HTMLElement} */ getElement() { - return this.getCanvasView().el; + return this.canvasView.el; } - getFrame(index?: number) { + getFrame(index) { return this.getFrames()[index || 0]; } @@ -117,11 +127,11 @@ export default class CanvasModule extends Module { */ getFrameEl() { const { frame } = this.canvasView || {}; - return frame?.el as HTMLIFrameElement; + return frame && frame.el; } getFramesEl() { - return this.canvasView?.framesArea as HTMLElement; + return this.canvasView.framesArea; } /** @@ -129,8 +139,7 @@ export default class CanvasModule extends Module { * @returns {Window} */ getWindow() { - const { frame } = this.canvasView || {}; - return frame?.getWindow() as Window; + return this.getFrameEl().contentWindow; } /** @@ -139,7 +148,7 @@ export default class CanvasModule extends Module { */ getDocument() { const frame = this.getFrameEl(); - return frame?.contentDocument as Document; + return frame && frame.contentDocument; } /** @@ -148,12 +157,16 @@ export default class CanvasModule extends Module { */ getBody() { const doc = this.getDocument(); - return doc?.body as HTMLBodyElement; + return doc && doc.body; } - _getLocalEl(globalEl: any, compView: any, method: keyof FrameView) { + _getCompFrame(compView) { + return compView && compView._getFrame(); + } + + _getLocalEl(globalEl, compView, method) { let result = globalEl; - const frameView = compView?._getFrame(); + const frameView = this._getCompFrame(compView); result = frameView ? frameView[method]() : result; return result; @@ -165,7 +178,7 @@ export default class CanvasModule extends Module { * @private */ getGlobalToolsEl() { - return this.canvasView?.toolsGlobEl; + return this.canvasView.toolsGlobEl; } /** @@ -173,8 +186,8 @@ export default class CanvasModule extends Module { * @returns {HTMLElement} * @private */ - getToolsEl(compView: any) { - return this._getLocalEl(this.getCanvasView().toolsEl, compView, 'getToolsEl'); + getToolsEl(compView) { + return this._getLocalEl(this.canvasView.toolsEl, compView, 'getToolsEl'); } /** @@ -182,8 +195,8 @@ export default class CanvasModule extends Module { * @returns {HTMLElement} * @private */ - getHighlighter(compView: any) { - return this._getLocalEl(this.getCanvasView().hlEl, compView, 'getHighlighter'); + getHighlighter(compView) { + return this._getLocalEl(this.canvasView.hlEl, compView, 'getHighlighter'); } /** @@ -191,8 +204,8 @@ export default class CanvasModule extends Module { * @returns {HTMLElement} * @private */ - getBadgeEl(compView: any) { - return this._getLocalEl(this.getCanvasView().badgeEl, compView, 'getBadgeEl'); + getBadgeEl(compView) { + return this._getLocalEl(this.canvasView.badgeEl, compView, 'getBadgeEl'); } /** @@ -201,7 +214,7 @@ export default class CanvasModule extends Module { * @private */ getPlacerEl() { - return this.getCanvasView().placerEl; + return this.canvasView.placerEl; } /** @@ -210,7 +223,7 @@ export default class CanvasModule extends Module { * @private */ getGhostEl() { - return this.getCanvasView().ghostEl; + return this.canvasView.ghostEl; } /** @@ -219,7 +232,7 @@ export default class CanvasModule extends Module { * @private */ getToolbarEl() { - return this.getCanvasView().toolbarEl; + return this.canvasView.toolbarEl; } /** @@ -228,7 +241,7 @@ export default class CanvasModule extends Module { * @private */ getResizerEl() { - return this.getCanvasView().resizerEl; + return this.canvasView.resizerEl; } /** @@ -236,8 +249,8 @@ export default class CanvasModule extends Module { * @returns {HTMLElement} * @private */ - getOffsetViewerEl(compView: any) { - return this._getLocalEl(this.getCanvasView().offsetEl, compView, 'getOffsetViewerEl'); + getOffsetViewerEl(compView) { + return this._getLocalEl(this.canvasView.offsetEl, compView, 'getOffsetViewerEl'); } /** @@ -246,12 +259,15 @@ export default class CanvasModule extends Module { * @private */ getFixedOffsetViewerEl() { - return this.getCanvasView().fixedOffsetEl; + return this.canvasView.fixedOffsetEl; } render() { this.canvasView?.remove(); - this.canvasView = new CanvasView(this.canvas); + this.canvasView = new CanvasView({ + model: this.canvas, + config: this.c, + }); return this.canvasView.render().el; } @@ -275,8 +291,8 @@ export default class CanvasModule extends Module { * @returns {Object} * @private */ - offset(el: HTMLElement) { - return this.getCanvasView().offset(el); + offset(el) { + return this.canvasView.offset(el); } /** @@ -287,9 +303,8 @@ export default class CanvasModule extends Module { * return component.getName(); * }); */ - setCustomBadgeLabel(f: Function) { - //@ts-ignore - this.config.customBadgeLabel = f; + setCustomBadgeLabel(f) { + this.c.customBadgeLabel = f; } /** @@ -298,8 +313,8 @@ export default class CanvasModule extends Module { * @returns {Object} * @private */ - getElementPos(el: HTMLElement, opts?: any) { - return this.getCanvasView().getElementPos(el, opts); + getElementPos(el, opts) { + return this.canvasView.getElementPos(el, opts); } /** @@ -308,8 +323,8 @@ export default class CanvasModule extends Module { * @returns {Object} * @private */ - getElementOffsets(el: HTMLElement) { - return this.getCanvasView().getElementOffsets(el); + getElementOffsets(el) { + return this.canvasView.getElementOffsets(el); } /** @@ -317,9 +332,9 @@ export default class CanvasModule extends Module { * @returns {Object} */ getRect() { - const { top = 0, left = 0 } = this.getCanvasView().getPosition() ?? {}; + const { top, left } = this.canvasView.getPosition(); return { - ...this.getCanvasView().getCanvasOffset(), + ...this.canvasView.getCanvasOffset(), topScroll: top, leftScroll: left, }; @@ -341,11 +356,11 @@ export default class CanvasModule extends Module { * @return {Object} * @private */ - getTargetToElementDim(target: HTMLElement, element: HTMLElement, options: any = {}) { + getTargetToElementDim(target, element, options = {}) { var opts = options || {}; - var canvasPos = this.getCanvasView().getPosition(); + var canvasPos = this.canvasView.getPosition(); if (!canvasPos) return; - var pos = opts.elPos || this.getCanvasView().getElementPos(element); + var pos = opts.elPos || this.canvasView.getElementPos(element); var toRight = options.toRight || 0; var targetHeight = opts.targetHeight || target.offsetHeight; var targetWidth = opts.targetWidth || target.offsetWidth; @@ -376,20 +391,20 @@ export default class CanvasModule extends Module { }; // In this way I can catch data and also change the position strategy - if (eventToTrigger && this.em) { - this.em.trigger(eventToTrigger, result); + if (eventToTrigger && this.c.em) { + this.c.em.trigger(eventToTrigger, result); } return result; } - canvasRectOffset(el: HTMLElement, pos: {top: number, left: number}, opts: any = {}) { - const getFrameElFromDoc = (doc: Document) => { + canvasRectOffset(el, pos, opts = {}) { + const getFrameElFromDoc = doc => { const { defaultView } = doc; - return defaultView?.frameElement as HTMLElement; + return defaultView && defaultView.frameElement; }; - const rectOff = (el: HTMLElement, top = 1, pos: {top: number, left: number}) => { + const rectOff = (el, top = 1, pos) => { const zoom = this.em.getZoomDecimal(); const side = top ? 'top' : 'left'; const doc = el.ownerDocument; @@ -411,7 +426,7 @@ export default class CanvasModule extends Module { }; } - getTargetToElementFixed(el: any, elToMove: any, opts: any = {}) { + getTargetToElementFixed(el, elToMove, opts = {}) { const pos = opts.pos || this.getElementPos(el); const cvOff = opts.canvasOff || this.canvasRectOffset(el, pos); const toolbarH = elToMove.offsetHeight || 0; @@ -425,8 +440,7 @@ export default class CanvasModule extends Module { let top = -toolbarH; let left = !isUndefined(opts.left) ? opts.left : pos.width - toolbarW; left = pos.left < -left ? -pos.left : left; - const frCvWidth = frCvOff?.width ?? 0; - left = elRight > frCvWidth ? left - (elRight - frCvWidth) : left; + left = elRight > frCvOff.width ? left - (elRight - frCvOff.width) : left; // Scroll with the window if the top edge is reached and the // element is bigger than the canvas @@ -463,7 +477,8 @@ export default class CanvasModule extends Module { * @return {Object} * @private */ - getMouseRelativePos(e: any, opts: any = {}) { + getMouseRelativePos(e, options) { + var opts = options || {}; var addTop = 0; var addLeft = 0; var subWinOffset = opts.subWinOffset; @@ -491,9 +506,9 @@ export default class CanvasModule extends Module { * @return {Object} * @private */ - getMouseRelativeCanvas(ev: MouseEvent, opts: any) { + getMouseRelativeCanvas(ev, opts) { const zoom = this.getZoomDecimal(); - const { top = 0, left = 0 } = this.getCanvasView().getPosition(opts) ?? {}; + const { top, left } = this.canvasView.getPosition(opts); return { y: ev.clientY * zoom + top, @@ -517,8 +532,7 @@ export default class CanvasModule extends Module { isInputFocused() { const doc = this.getDocument(); const frame = this.getFrameEl(); - //console.log(this.config) - const toIgnore = ['body', ...this.config.notTextable]; + const toIgnore = ['body', ...this.getConfig().notTextable]; const docActive = frame && document.activeElement === frame; const focused = docActive ? doc && doc.activeElement : document.activeElement; @@ -540,7 +554,7 @@ export default class CanvasModule extends Module { * // Force the scroll, even if the element is alredy visible * canvas.scrollTo(selected, { force: true }); */ - scrollTo(el: any, opts = {}) { + scrollTo(el, opts = {}) { const elem = getElement(el); const view = elem && getViewEl(elem); view && view.scrollIntoView(opts); @@ -550,7 +564,7 @@ export default class CanvasModule extends Module { * Start autoscroll * @private */ - startAutoscroll(frame: Frame) { + startAutoscroll(frame) { const fr = (frame && frame.view) || this.em.getCurrentFrame(); fr && fr.startAutoscroll(); } @@ -559,7 +573,7 @@ export default class CanvasModule extends Module { * Stop autoscroll * @private */ - stopAutoscroll(frame: Frame) { + stopAutoscroll(frame) { const fr = (frame && frame.view) || this.em.getCurrentFrame(); fr && fr.stopAutoscroll(); } @@ -571,7 +585,7 @@ export default class CanvasModule extends Module { * @example * canvas.setZoom(50); // set zoom to 50% */ - setZoom(value: string) { + setZoom(value) { this.canvas.set('zoom', parseFloat(value)); return this; } @@ -595,7 +609,7 @@ export default class CanvasModule extends Module { * @example * canvas.setCoords(100, 100); */ - setCoords(x: string, y: string) { + setCoords(x, y) { this.canvas.set({ x: parseFloat(x), y: parseFloat(y) }); return this; } @@ -608,7 +622,7 @@ export default class CanvasModule extends Module { * const coords = canvas.getCoords(); * // { x: 100, y: 100 } */ - getCoords(): {x: number, y: number} { + getCoords() { const { x, y } = this.canvas.attributes; return { x, y }; } @@ -622,13 +636,13 @@ export default class CanvasModule extends Module { return zoom ? 1 / zoom : 1; } - toggleFramesEvents(on: boolean) { + toggleFramesEvents(on) { const { style } = this.getFramesEl(); style.pointerEvents = on ? '' : 'none'; } getFrames() { - return this.canvas.frames.map(item => item); + return this.canvas.get('frames').map(item => item); } /** @@ -654,14 +668,13 @@ export default class CanvasModule extends Module { * }); */ addFrame(props = {}, opts = {}) { - return this.canvas.frames.add(new Frame(this, { ...props }), opts); + return this.canvas.frames.add(new Frame({ ...props }, { em: this.em }), opts); } destroy() { this.canvas.stopListening(); this.canvasView?.remove(); - //[this.canvas, this.canvasView].forEach(i => (i = {})); - //@ts-ignore - ['model', 'droppable'].forEach(i => (this[i] = {})); + [this.c, this.canvas, this.canvasView].forEach(i => (i = {})); + ['em', 'model', 'droppable'].forEach(i => (this[i] = {})); } } diff --git a/src/canvas/model/Canvas.ts b/src/canvas/model/Canvas.ts index 5b24e5c64..6bd976a57 100644 --- a/src/canvas/model/Canvas.ts +++ b/src/canvas/model/Canvas.ts @@ -1,14 +1,15 @@ -import { Model } from "../../abstract"; -import { evPageSelect } from "../../pages"; -import Frames from "./Frames"; -import Page from "../../pages/model/Page"; -import CanvasModule from ".."; +import { Model } from '../../common'; +import Backbone from 'backbone'; +import { evPageSelect } from '../../pages'; +import Frames from './Frames'; +import EditorModel from '../../editor/model/Editor'; +import Page from '../../pages/model/Page'; -export default class Canvas extends Model { +export default class Canvas extends Backbone.Model { defaults() { return { frame: '', - frames: [], + frames: new Frames(), rulers: false, zoom: 100, x: 0, @@ -19,17 +20,18 @@ export default class Canvas extends Model { styles: [], }; } + em: EditorModel; + config: any; - constructor(module: CanvasModule) { - const { em, config } = module; - const { scripts, styles } = config; - super(module, {scripts, styles}); - this.set("frames", new Frames(module)) - this.listenTo(this, "change:zoom", this.onZoomChange); - this.listenTo(em, "change:device", this.updateDevice); + constructor(props: any, config: any = {}) { + super(props); + const { em } = config; + this.config = config; + this.em = em; + this.listenTo(this, 'change:zoom', this.onZoomChange); + this.listenTo(em, 'change:device', this.updateDevice); this.listenTo(em, evPageSelect, this._pageUpdated); } - get frames(): Frames { return this.get('frames'); } diff --git a/src/canvas/model/Frame.ts b/src/canvas/model/Frame.ts index 61532be40..b3e9824f5 100644 --- a/src/canvas/model/Frame.ts +++ b/src/canvas/model/Frame.ts @@ -1,7 +1,7 @@ import { result, forEach, isEmpty, isString } from 'underscore'; -import { Model } from "../../abstract"; -import CanvasModule from ".."; +import { Model } from '../../common'; import ComponentWrapper from '../../dom_components/model/ComponentWrapper'; +import EditorModel from '../../editor/model/Editor'; import { isComponent, isObject } from '../../utils/mixins'; import FrameView from '../view/FrameView'; import Frames from './Frames'; @@ -17,7 +17,7 @@ const keyAutoH = '__ah'; * @property {Number} [y=0] Vertical position of the frame in the canvas. * */ -export default class Frame extends Model { +export default class Frame extends Model { defaults() { return { x: 0, @@ -33,16 +33,18 @@ export default class Frame extends Model { _undoexc: ['changesCount'], }; } + em: EditorModel; view?: FrameView; - constructor(module: CanvasModule, props: any) { - super(module, props); - const { em } = this; + constructor(props: any, opts: any) { + super(props); + const { em } = opts; const { styles, component } = this.attributes; const domc = em.get('DomComponents'); const conf = domc.getConfig(); const allRules = em.get('CssComposer').getAll(); const idMap: any = {}; + this.em = em; const modOpts = { em, config: conf, frame: this, idMap }; if (!isComponent(component)) { @@ -83,10 +85,6 @@ export default class Frame extends Model { !props.height && this.set(keyAutoH, 1); } - get head(): {tag: string, attributes: any}[]{ - return this.get("head"); - } - onRemove() { this.getComponent().remove({ root: 1 }); } @@ -117,19 +115,23 @@ export default class Frame extends Model { } getHead() { - return [...this.head]; + const head = this.get('head') || []; + return [...head]; } - setHead(value: {tag: string, attributes: any}[]) { - return this.set("head", [...value]); + setHead(value: any) { + return this.set('head', [...value]); } - addHeadItem(item: {tag: string, attributes: any}) { - this.head.push(item); + addHeadItem(item: any) { + const head = this.getHead(); + head.push(item); + this.setHead(head); } getHeadByAttr(attr: string, value: any, tag: string) { - return this.head.filter( + const head = this.getHead(); + return head.filter( (item) => item.attributes && item.attributes[attr] == value && @@ -138,11 +140,13 @@ export default class Frame extends Model { } removeHeadByAttr(attr: string, value: any, tag: string) { + const head = this.getHead(); const item = this.getHeadByAttr(attr, value, tag); - const index = this.head.indexOf(item); + const index = head.indexOf(item); if (index >= 0) { - this.head.splice(index, 1); + head.splice(index, 1); + this.setHead(head); } } diff --git a/src/canvas/model/Frames.ts b/src/canvas/model/Frames.ts index e69f3ca28..2db54e0f9 100644 --- a/src/canvas/model/Frames.ts +++ b/src/canvas/model/Frames.ts @@ -1,5 +1,4 @@ import { bindAll } from 'underscore'; -import CanvasModule from '..'; import { Collection } from '../../common'; import Page from '../../pages/model/Page'; import Frame from './Frame'; @@ -8,11 +7,9 @@ export default class Frames extends Collection { loadedItems = 0; itemsToLoad = 0; page?: Page; - module: CanvasModule - constructor(module: CanvasModule, models: Frame[] = []) { + constructor(models?: Frame[]) { super(models); - this.module = module; bindAll(this, 'itemLoaded'); this.on('reset', this.onReset); this.on('remove', this.onRemove); diff --git a/src/canvas/view/CanvasView.ts b/src/canvas/view/CanvasView.js similarity index 64% rename from src/canvas/view/CanvasView.ts rename to src/canvas/view/CanvasView.js index e8a161a2e..6d8051ca8 100644 --- a/src/canvas/view/CanvasView.ts +++ b/src/canvas/view/CanvasView.js @@ -1,24 +1,12 @@ import { bindAll } from 'underscore'; -import { View } from '../../abstract'; +import { View } from '../../common'; import { on, off, getElement, getKeyChar, isTextNode, getElRect, getUiClass } from '../../utils/mixins'; import { createEl } from '../../utils/dom'; import FramesView from './FramesView'; -import Canvas from '../model/Canvas'; -import FrameView from './FrameView'; -import ComponentView from '../../dom_components/view/ComponentView'; -import Component from '../../dom_components/model/Component'; - -interface MarginPaddingOffsets{ - marginTop?: number, - marginRight?: number, - marginBottom?: number, - marginLeft?: number, - paddingTop?: number, - paddingRight?: number, - paddingBottom?: number, - paddingLeft?: number, - } -export default class CanvasView extends View { + +let timerZoom; + +export default class CanvasView extends View { events() { return { wheel: 'onWheel', @@ -32,42 +20,22 @@ export default class CanvasView extends View {
`; } - /*get className(){ - return this.pfx + 'canvas': - }*/ - hlEl?: HTMLElement; - badgeEl?: HTMLElement; - placerEl?: HTMLElement; - ghostEl?: HTMLElement; - toolbarEl?: HTMLElement; - resizerEl?: HTMLElement; - offsetEl?: HTMLElement; - fixedOffsetEl?: HTMLElement; - toolsGlobEl?: HTMLElement; - toolsEl?: HTMLElement; - framesArea?: HTMLElement; - toolsWrapper?: HTMLElement; - ready = false; - - frames!: FramesView; - frame?: FrameView; - - private timerZoom?: number - - private frmOff?: {top: number, left: number, width: number, height: number} - private cvsOff?: {top: number, left: number, width: number, height: number} - - constructor(model: Canvas) { - super({model}); + + initialize(o) { bindAll(this, 'clearOff', 'onKeyPress', 'onCanvasMove'); - this.className = this.pfx + 'canvas'; + const { model } = this; + this.config = o.config || {}; + this.em = this.config.em || {}; + this.pfx = this.config.stylePrefix || ''; + this.ppfx = this.config.pStylePrefix || ''; + this.className = this.config.stylePrefix + 'canvas'; const { em } = this; this._initFrames(); this.listenTo(em, 'change:canvasOffset', this.clearOff); this.listenTo(em, 'component:selected', this.checkSelected); this.listenTo(model, 'change:zoom change:x change:y', this.updateFrames); this.listenTo(model, 'change:frames', this._onFramesUpdate); - this.toggleListeners(true); + this.toggleListeners(1); } _onFramesUpdate() { @@ -77,53 +45,51 @@ export default class CanvasView extends View { _initFrames() { const { frames, model, config, em } = this; - const collection = model.frames; + const collection = model.get('frames'); em.set('readyCanvas', 0); collection.once('loaded:all', () => em.set('readyCanvas', 1)); - frames?.remove(); - this.frames = new FramesView( - {collection}, - {config: { + frames && frames.remove(); + this.frames = new FramesView({ + collection, + config: { ...config, canvasView: this, }, }); } - checkSelected(component: Component, opts: any = {}) { + checkSelected(component, opts = {}) { const { scroll } = opts; const currFrame = this.em.get('currentFrame'); - scroll && component.views?.forEach(view => { + scroll && + component.views.forEach(view => { view._getFrame() === currFrame && view.scrollIntoView(scroll); }); } - remove(...args: any) { - this.frames?.remove(); - //@ts-ignore - this.frames = undefined; - View.prototype.remove.apply(this, args); - this.toggleListeners(false); - return this + remove() { + this.frames.remove(); + this.frames = {}; + View.prototype.remove.apply(this, arguments); + this.toggleListeners(); } - preventDefault(ev: Event) { + preventDefault(ev) { if (ev) { ev.preventDefault(); - //@ts-ignore - ev._parentEvent?.preventDefault(); + ev._parentEvent && ev._parentEvent.preventDefault(); } } - onCanvasMove(ev: Event) { + onCanvasMove(ev) { // const data = { x: ev.clientX, y: ev.clientY }; // const data2 = this.em.get('Canvas').getMouseRelativeCanvas(ev); // const data3 = this.em.get('Canvas').getMouseRelativePos(ev); // this.em.trigger('canvas:over', data, data2, data3); } - toggleListeners(enable: boolean) { + toggleListeners(enable) { const { el } = this; const fn = enable ? on : off; fn(document, 'keypress', this.onKeyPress); @@ -131,7 +97,7 @@ export default class CanvasView extends View { // fn(el, 'mousemove dragover', this.onCanvasMove); } - onKeyPress(ev: Event) { + onKeyPress(ev) { const { em } = this; const key = getKeyChar(ev); @@ -141,30 +107,28 @@ export default class CanvasView extends View { } } - onWheel(ev: KeyboardEvent) { + onWheel(ev) { if ((ev.ctrlKey || ev.metaKey) && this.em.getConfig().multiFrames) { this.preventDefault(ev); const { model } = this; - //@ts-ignore this is potentially deprecated const delta = Math.max(-1, Math.min(1, ev.wheelDelta || -ev.detail)); const zoom = model.get('zoom'); model.set('zoom', zoom + delta * 2); } } - updateFrames(ev: Event) { + updateFrames(ev) { const { em, model } = this; const { x, y } = model.attributes; const zoom = this.getZoom(); const defOpts = { preserveSelected: 1 }; const mpl = zoom ? 1 / zoom : 1; - //@ts-ignore this.framesArea.style.transform = `scale(${zoom}) translate(${x * mpl}px, ${y * mpl}px)`; this.clearOff(); em.stopDefault(defOpts); em.trigger('canvas:update', ev); - this.timerZoom && clearTimeout(this.timerZoom); - this.timerZoom = setTimeout(() => em.runDefault(defOpts), 300) as any; + timerZoom && clearTimeout(timerZoom); + timerZoom = setTimeout(() => em.runDefault(defOpts), 300); } getZoom() { @@ -176,7 +140,7 @@ export default class CanvasView extends View { * @param {HTMLElement} el * @return {Boolean} */ - isElInViewport(el: HTMLElement) { + isElInViewport(el) { const elem = getElement(el); const rect = getElRect(elem); const frameRect = this.getFrameOffset(elem); @@ -188,16 +152,16 @@ export default class CanvasView extends View { /** * Get the offset of the element * @param {HTMLElement} el - * @return { {top: number, left: number, width: number, height: number} } + * @return {Object} */ - offset(el?: HTMLElement, opts: any = {}) { + offset(el, opts = {}) { const rect = getElRect(el); - const docBody = el?.ownerDocument.body; + const docBody = el.ownerDocument.body; const { noScroll } = opts; return { - top: rect.top + (noScroll ? 0 : docBody?.scrollTop ?? 0), - left: rect.left + (noScroll ? 0 : docBody?.scrollLeft ?? 0), + top: rect.top + (noScroll ? 0 : docBody.scrollTop), + left: rect.left + (noScroll ? 0 : docBody.scrollLeft), width: rect.width, height: rect.height, }; @@ -208,20 +172,20 @@ export default class CanvasView extends View { * @private */ clearOff() { - this.frmOff = undefined; - this.cvsOff = undefined; + this.frmOff = null; + this.cvsOff = null; } /** * Return frame offset - * @return { {top: number, left: number, width: number, height: number} } - * @public + * @return {Object} + * @private */ - getFrameOffset(el?: HTMLElement) { + getFrameOffset(el) { if (!this.frmOff || el) { - const frame = this.frame?.el; - const winEl = el?.ownerDocument.defaultView; - const frEl = winEl ? winEl.frameElement as HTMLElement : frame; + const frame = this.frame.el; + const winEl = el && el.ownerDocument.defaultView; + const frEl = winEl ? winEl.frameElement : frame; this.frmOff = this.offset(frEl || frame); } return this.frmOff; @@ -229,8 +193,8 @@ export default class CanvasView extends View { /** * Return canvas offset - * @return { {top: number, left: number, width: number, height: number} } - * @public + * @return {Object} + * @private */ getCanvasOffset() { if (!this.cvsOff) this.cvsOff = this.offset(this.el); @@ -240,10 +204,10 @@ export default class CanvasView extends View { /** * Returns element's rect info * @param {HTMLElement} el - * @return { {top: number, left: number, width: number, height: number, zoom: number, rect: any} } - * @public + * @return {Object} + * @private */ - getElementPos(el: HTMLElement, opts: any = {}) { + getElementPos(el, opts) { const zoom = this.getZoom(); const opt = opts || {}; const frameOffset = this.getFrameOffset(el); @@ -264,14 +228,14 @@ export default class CanvasView extends View { /** * Returns element's offsets like margins and paddings * @param {HTMLElement} el - * @return { MarginPaddingOffsets } - * @public + * @return {Object} + * @private */ - getElementOffsets(el: HTMLElement) { + getElementOffsets(el) { if (!el || isTextNode(el)) return {}; - const result: MarginPaddingOffsets = {} ; + const result = {}; const styles = window.getComputedStyle(el); - const marginPaddingOffsets: (keyof MarginPaddingOffsets)[] =[ + [ 'marginTop', 'marginRight', 'marginBottom', @@ -280,8 +244,7 @@ export default class CanvasView extends View { 'paddingRight', 'paddingBottom', 'paddingLeft', - ] - marginPaddingOffsets.forEach(offset => { + ].forEach(offset => { result[offset] = parseFloat(styles[offset]) * this.getZoom(); }); @@ -290,12 +253,11 @@ export default class CanvasView extends View { /** * Returns position data of the canvas element - * @return { {top: number, left: number, width: number, height: number} } obj Position object - * @public + * @return {Object} obj Position object + * @private */ - getPosition(opts: any = {}) { - - const doc = this.frame?.el.contentDocument; + getPosition(opts = {}) { + const doc = this.frame.el.contentDocument; if (!doc) return; const bEl = doc.body; const zoom = this.getZoom(); @@ -316,8 +278,7 @@ export default class CanvasView extends View { * @param {View} view Component's View * @private */ - //TODO change type after the ComponentView was updated to ts - updateScript(view: any) { + updateScript(view) { const model = view.model; const id = model.getId(); @@ -352,25 +313,25 @@ export default class CanvasView extends View { * Get javascript container * @private */ - getJsContainer(view?: ComponentView) { + getJsContainer(view) { const frameView = this.getFrameView(view); return frameView && frameView.getJsContainer(); } - getFrameView(view?: ComponentView) { - return view?._getFrame() || this.em.get('currentFrame'); + getFrameView(view) { + return (view && view._getFrame()) || this.em.get('currentFrame'); } _renderFrames() { if (!this.ready) return; const { model, frames, em, framesArea } = this; - const frms = model.frames; + const frms = model.get('frames'); frms.listenToLoad(); frames.render(); const mainFrame = frms.at(0); - const currFrame = mainFrame?.view; + const currFrame = mainFrame && mainFrame.view; em.setCurrentFrame(currFrame); - framesArea?.appendChild(frames.el); + framesArea && framesArea.appendChild(frames.el); this.frame = currFrame; } @@ -399,18 +360,18 @@ export default class CanvasView extends View { `); const toolsEl = el.querySelector(`#${ppfx}tools`); - this.hlEl = el.querySelector(`.${ppfx}highlighter`) as HTMLElement; - this.badgeEl = el.querySelector(`.${ppfx}badge`) as HTMLElement; - this.placerEl = el.querySelector(`.${ppfx}placeholder`) as HTMLElement; - this.ghostEl = el.querySelector(`.${ppfx}ghost`) as HTMLElement; - this.toolbarEl = el.querySelector(`.${ppfx}toolbar`) as HTMLElement; - this.resizerEl = el.querySelector(`.${ppfx}resizer`) as HTMLElement; - this.offsetEl = el.querySelector(`.${ppfx}offset-v`) as HTMLElement; - this.fixedOffsetEl = el.querySelector(`.${ppfx}offset-fixed-v`) as HTMLElement; - this.toolsGlobEl = el.querySelector(`.${ppfx}tools-gl`) as HTMLElement; - this.toolsEl = toolsEl as HTMLElement; + this.hlEl = el.querySelector(`.${ppfx}highlighter`); + this.badgeEl = el.querySelector(`.${ppfx}badge`); + this.placerEl = el.querySelector(`.${ppfx}placeholder`); + this.ghostEl = el.querySelector(`.${ppfx}ghost`); + this.toolbarEl = el.querySelector(`.${ppfx}toolbar`); + this.resizerEl = el.querySelector(`.${ppfx}resizer`); + this.offsetEl = el.querySelector(`.${ppfx}offset-v`); + this.fixedOffsetEl = el.querySelector(`.${ppfx}offset-fixed-v`); + this.toolsGlobEl = el.querySelector(`.${ppfx}tools-gl`); + this.toolsEl = toolsEl; this.el.className = getUiClass(em, this.className); - this.ready = true; + this.ready = 1; this._renderFrames(); return this; diff --git a/src/canvas/view/FrameView.ts b/src/canvas/view/FrameView.js similarity index 78% rename from src/canvas/view/FrameView.ts rename to src/canvas/view/FrameView.js index fa4a2c15c..dff267953 100644 --- a/src/canvas/view/FrameView.ts +++ b/src/canvas/view/FrameView.js @@ -1,47 +1,31 @@ import { bindAll, isString, debounce, isUndefined } from 'underscore'; import { appendVNodes, append, createEl, createCustomEvent, motionsEv } from '../../utils/dom'; import { on, off, setViewEl, hasDnd, getPointerEvent } from '../../utils/mixins'; -import { View } from '../../abstract'; +import { View } from '../../common'; import CssRulesView from '../../css_composer/view/CssRulesView'; import Droppable from '../../utils/Droppable'; -import Frame from '../model/Frame'; -import Canvas from '../model/Canvas'; -import ComponentWrapper from '../../dom_components/model/ComponentWrapper'; -import FrameWrapView from './FrameWrapView'; -export default class FrameView extends View { - - //@ts-ignore - get tagName(){return 'iframe'}; - //@ts-ignore - get attributes() {return { allowfullscreen: 'allowfullscreen' }}; - - dragging = false; - droppable?: Droppable; - rect?: DOMRect; - - lastClientY?: number; - lastMaxHeight = 0; - private jsContainer?: HTMLElement; - private tools: {[key: string]: HTMLElement} = {}; - private wrapper?: any; - private frameWrapView?: FrameWrapView; +export default class FrameView extends View { + tagName() { + return 'iframe'; + } + attributes() { + return { + allowfullscreen: 'allowfullscreen', + }; + } - constructor(model: Frame, view?: FrameWrapView) { - super({model}); + initialize(o) { bindAll(this, 'updateClientY', 'stopAutoscroll', 'autoscroll', '_emitUpdate'); - const { el, em } = this; - //el = em.config.el - //@ts-ignore - this.module._config = { - ...(this.config || {}), - //@ts-ignore + const { model, el } = this; + this.tools = {}; + this.config = { + ...(o.config || {}), frameView: this, - //canvasView: view?.cv }; - //console.log(this.config) - this.frameWrapView = view; + this.ppfx = this.config.pStylePrefix || ''; + this.em = this.config.em; this.showGlobalTools = debounce(this.showGlobalTools.bind(this), 50); const cvModel = this.getCanvasModel(); this.listenTo(model, 'change:head', this.updateHead); @@ -56,16 +40,16 @@ export default class FrameView extends View { updateHead() { const { model } = this; const headEl = this.getHead(); - const toRemove: any[] = []; - const toAdd: any[] = []; - const current = model.head; + const toRemove = []; + const toAdd = []; + const current = model.get('head'); const prev = model.previous('head'); - const attrStr = (attr: any = {}) => + const attrStr = (attr = {}) => Object.keys(attr) .sort() .map(i => `[${i}="${attr[i]}"]`) .join(''); - const find = (items: any[], stack: any[], res: any[]) => { + const find = (items, stack, res) => { items.forEach(item => { const { tag, attributes } = item; const has = stack.some(s => s.tag === tag && attrStr(s.attributes) === attrStr(attributes)); @@ -76,7 +60,7 @@ export default class FrameView extends View { find(prev, current, toRemove); toRemove.forEach(stl => { const el = headEl.querySelector(`${stl.tag}${attrStr(stl.attributes)}`); - el?.parentNode?.removeChild(el); + el && el.parentNode.removeChild(el); }); appendVNodes(headEl, toAdd); } @@ -85,28 +69,28 @@ export default class FrameView extends View { return this.el; } - getCanvasModel(): Canvas { + getCanvasModel() { return this.em.get('Canvas').getModel(); } getWindow() { - return this.getEl().contentWindow as Window; + return this.getEl().contentWindow; } getDoc() { - return this.getEl().contentDocument as Document; + return this.getEl().contentDocument; } getHead() { - return this.getDoc().querySelector('head') as HTMLHeadElement; + return this.getDoc().querySelector('head'); } getBody() { - return this.getDoc().querySelector('body') as HTMLBodyElement; + return this.getDoc().querySelector('body'); } getWrapper() { - return this.getBody().querySelector('[data-gjs-type=wrapper]') as HTMLElement; + return this.getBody().querySelector('[data-gjs-type=wrapper]'); } getJsContainer() { @@ -118,7 +102,8 @@ export default class FrameView extends View { } getToolsEl() { - return this.frameWrapView?.elTools as HTMLElement; + const { frameWrapView } = this.config; + return frameWrapView && frameWrapView.elTools; } getGlobalToolsEl() { @@ -166,24 +151,23 @@ export default class FrameView extends View { }; } - _getTool(name: string) { + _getTool(name) { const { tools } = this; const toolsEl = this.getToolsEl(); if (!tools[name]) { - tools[name] = toolsEl.querySelector(name) as HTMLElement; + tools[name] = toolsEl.querySelector(name); } return tools[name]; } - remove(...args: any) { + remove() { const wrp = this.wrapper; - this._toggleEffects(false); + this._toggleEffects(); this.tools = {}; wrp && wrp.remove(); - View.prototype.remove.apply(this, args); - return this; + View.prototype.remove.apply(this, arguments); } startAutoscroll() { @@ -192,7 +176,7 @@ export default class FrameView extends View { // By detaching those from the stack avoid browsers lags // Noticeable with "fast" drag of blocks setTimeout(() => { - this._toggleAutoscrollFx(true); + this._toggleAutoscrollFx(1); requestAnimationFrame(this.autoscroll); }, 0); } @@ -233,7 +217,7 @@ export default class FrameView extends View { } } - updateClientY(ev: Event) { + updateClientY(ev) { ev.preventDefault(); this.lastClientY = getPointerEvent(ev).clientY * this.em.getZoomDecimal(); } @@ -243,10 +227,10 @@ export default class FrameView extends View { } stopAutoscroll() { - this.dragging && this._toggleAutoscrollFx(false); + this.dragging && this._toggleAutoscrollFx(); } - _toggleAutoscrollFx(enable: boolean) { + _toggleAutoscrollFx(enable) { this.dragging = enable; const win = this.getWindow(); const method = enable ? 'on' : 'off'; @@ -267,7 +251,7 @@ export default class FrameView extends View { const evLoad = 'frame:load'; const evOpts = { el, model, view: this }; const canvas = this.getCanvasModel(); - const appendScript = (scripts: any[]) => { + const appendScript = scripts => { if (scripts.length > 0) { const src = scripts.shift(); const scriptEl = createEl('script', { @@ -275,7 +259,7 @@ export default class FrameView extends View { ...(isString(src) ? { src } : src), }); scriptEl.onerror = scriptEl.onload = appendScript.bind(null, scripts); - el.contentDocument?.head.appendChild(scriptEl); + el.contentDocument.head.appendChild(scriptEl); } else { this.renderBody(); em && em.trigger(evLoad, evOpts); @@ -295,10 +279,10 @@ export default class FrameView extends View { }; } - renderStyles(opts: any = {}) { + renderStyles(opts = {}) { const head = this.getHead(); const canvas = this.getCanvasModel(); - const normalize = (stls: any[]) => + const normalize = stls => stls.map(href => ({ tag: 'link', attributes: { @@ -308,9 +292,9 @@ export default class FrameView extends View { })); const prevStyles = normalize(opts.prev || canvas.previous('styles')); const styles = normalize(canvas.get('styles')); - const toRemove: any[] = []; - const toAdd: any[] = []; - const find = (items: any[], stack: any[], res: any[]) => { + const toRemove = []; + const toAdd = []; + const find = (items, stack, res) => { items.forEach(item => { const { href } = item.attributes; const has = stack.some(s => s.attributes.href === href); @@ -321,18 +305,18 @@ export default class FrameView extends View { find(prevStyles, styles, toRemove); toRemove.forEach(stl => { const el = head.querySelector(`link[href="${stl.attributes.href}"]`); - el?.parentNode?.removeChild(el); + el && el.parentNode.removeChild(el); }); appendVNodes(head, toAdd); } renderBody() { - const { config, em, model, ppfx } = this; + const { config, model, ppfx } = this; + const { em } = config; const doc = this.getDoc(); const body = this.getBody(); const win = this.getWindow(); - const conf = em.config; - //@ts-ignore TODO I don't understand why this needed nowhere else is used + const conf = em.get('Config'); win._isEditor = true; this.renderStyles({ prev: [] }); @@ -415,12 +399,11 @@ export default class FrameView extends View { frameView: this, }, }).render(); - append(body, this.wrapper?.el); + append(body, this.wrapper.el); append( body, new CssRulesView({ collection: model.getStyles(), - //@ts-ignore config: { ...em.get('CssComposer').getConfig(), frameView: this, @@ -432,8 +415,7 @@ export default class FrameView extends View { //this.updateOffset(); // TOFIX (check if I need it) // Avoid some default behaviours - //@ts-ignore - on(body, 'click', ev => ev && ev.target?.tagName == 'A' && ev.preventDefault()); + on(body, 'click', ev => ev && ev.target.tagName == 'A' && ev.preventDefault()); on(body, 'submit', ev => ev && ev.preventDefault()); // When the iframe is focused the event dispatcher is not the same so @@ -449,12 +431,12 @@ export default class FrameView extends View { }) ); - this._toggleEffects(true); - this.droppable = hasDnd(em) && new Droppable(em, this.wrapper?.el); + this._toggleEffects(1); + this.droppable = hasDnd(em) && new Droppable(em, this.wrapper.el); model.trigger('loaded'); } - _toggleEffects(enable: boolean) { + _toggleEffects(enable) { const method = enable ? on : off; const win = this.getWindow(); win && method(win, `${motionsEv} resize`, this._emitUpdate); diff --git a/src/canvas/view/FrameWrapView.ts b/src/canvas/view/FrameWrapView.js similarity index 83% rename from src/canvas/view/FrameWrapView.ts rename to src/canvas/view/FrameWrapView.js index 89f36d2ca..af03496a6 100644 --- a/src/canvas/view/FrameWrapView.ts +++ b/src/canvas/view/FrameWrapView.js @@ -1,37 +1,34 @@ import { bindAll, isNumber, isNull, debounce } from 'underscore'; -import { View } from '../../abstract'; +import { View } from '../../common'; import FrameView from './FrameView'; import { createEl, removeEl } from '../../utils/dom'; import Dragger from '../../utils/Dragger'; -import CanvasView from './CanvasView'; -import Frame from '../model/Frame'; -export default class FrameWrapView extends View { +export default class FrameWrapView extends View { events() { return { 'click [data-action-remove]': 'remove', 'mousedown [data-action-move]': 'startDrag', }; } - elTools?: HTMLElement; - frame: FrameView; - dragger?: Dragger; - cv: CanvasView - classAnim: string - - constructor(model: Frame, canvasView: CanvasView) { - super({model}); + + initialize(opts = {}, conf = {}) { bindAll(this, 'onScroll', 'frameLoaded', 'updateOffset', 'remove', 'startDrag'); - //console.log(model.module) + const { model } = this; const config = { - ...(model.config), + ...(opts.config || conf), frameWrapView: this, }; + const { canvasView, em } = config; this.cv = canvasView; - this.frame = new FrameView(model, this); + this.config = config; + this.em = em; + this.canvas = em && em.get('Canvas'); + this.ppfx = config.pStylePrefix || ''; + this.frame = new FrameView({ model, config }); this.classAnim = `${this.ppfx}frame-wrapper--anim`; - this.updateOffset = debounce(this.updateOffset.bind(this), 0); - this.updateSize = debounce(this.updateSize.bind(this), 0); + this.updateOffset = debounce(this.updateOffset.bind(this)); + this.updateSize = debounce(this.updateSize.bind(this)); this.listenTo(model, 'loaded', this.frameLoaded); this.listenTo(model, 'change:x change:y', this.updatePos); this.listenTo(model, 'change:width change:height', this.updateSize); @@ -41,10 +38,10 @@ export default class FrameWrapView extends View { } setupDragger() { - const { module, model } = this; - let dragX: number, dragY: number, zoom: number; - const toggleEffects = (on: boolean) => { - module.toggleFramesEvents(on); + const { canvas, model } = this; + let dragX, dragY, zoom; + const toggleEffects = on => { + canvas.toggleFramesEvents(on); }; this.dragger = new Dragger({ @@ -53,10 +50,10 @@ export default class FrameWrapView extends View { zoom = this.em.getZoomMultiplier(); dragX = x; dragY = y; - toggleEffects(false); + toggleEffects(); }, - onEnd: () => toggleEffects(true), - setPosition: (posOpts: any) => { + onEnd: () => toggleEffects(1), + setPosition: posOpts => { model.set({ x: dragX + posOpts.x * zoom, y: dragY + posOpts.y * zoom, @@ -65,21 +62,20 @@ export default class FrameWrapView extends View { }); } - startDrag(ev?: Event) { - ev && this.dragger?.start(ev); + startDrag(ev) { + ev && this.dragger.start(ev); } - __clear(opts?: any) { + __clear(opts) { const { frame } = this; frame && frame.remove(opts); removeEl(this.elTools); } - remove(opts?: any) { + remove(opts) { this.__clear(opts); - View.prototype.remove.apply(this, opts); - //@ts-ignore - ['frame', 'dragger', 'cv', 'elTools'].forEach(i => (this[i] = 0)); + View.prototype.remove.apply(this, arguments); + ['frame', 'dragger', 'cv', 'em', 'canvas', 'elTools'].forEach(i => (this[i] = 0)); return this; } @@ -91,11 +87,11 @@ export default class FrameWrapView extends View { frame.model._emitUpdated(); } - updatePos(md?: boolean) { + updatePos(md) { const { model, el } = this; const { x, y } = model.attributes; const { style } = el; - this.frame.rect = undefined; + this.frame.rect = 0; style.left = isNaN(x) ? x : `${x}px`; style.top = isNaN(y) ? y : `${y}px`; md && this.updateOffset(); @@ -112,7 +108,7 @@ export default class FrameWrapView extends View { updateDim() { const { em, el, $el, model, classAnim, frame } = this; if (!frame) return; - frame.rect = undefined; + frame.rect = 0; $el.addClass(classAnim); const { noChanges, width, height } = this.__handleSize(); @@ -223,7 +219,7 @@ export default class FrameWrapView extends View { ` ); this.elTools = elTools; - const twrp = cv?.toolsWrapper; + const twrp = cv.toolsWrapper; twrp && twrp.appendChild(elTools); // TODO remove on frame remove onRender && onRender({ diff --git a/src/canvas/view/FramesView.js b/src/canvas/view/FramesView.js new file mode 100644 index 000000000..01ae1ef1b --- /dev/null +++ b/src/canvas/view/FramesView.js @@ -0,0 +1,21 @@ +import DomainViews from '../../domain_abstract/view/DomainViews'; +import FrameWrapView from './FrameWrapView'; + +export default class FramesView extends DomainViews { + constructor(opts = {}, config) { + super(opts, config, true); + this.listenTo(this.collection, 'reset', this.render); + } + + onRemoveBefore(items, opts) { + items.forEach(item => item.remove(opts)); + } + + onRender() { + const { config, $el } = this; + const { em } = config; + em && $el.attr({ class: `${em.getConfig().stylePrefix}frames` }); + } +} + +FramesView.prototype.itemView = FrameWrapView; diff --git a/src/canvas/view/FramesView.ts b/src/canvas/view/FramesView.ts deleted file mode 100644 index 10761fedc..000000000 --- a/src/canvas/view/FramesView.ts +++ /dev/null @@ -1,26 +0,0 @@ -import DomainViews from '../../abstract/DomainViews'; -import Frames from '../model/Frames'; -import CanvasView from './CanvasView'; -import FrameWrapView from './FrameWrapView'; - -export default class FramesView extends DomainViews { - canvasView: CanvasView; - constructor(opts = {}, config: any) { - super(opts, true); - //console.log(this.collection) - this.listenTo(this.collection, 'reset', this.render); - this.canvasView = config.canvasView - } - - onRemoveBefore(items: FrameWrapView[], opts = {}) { - items.forEach(item => item.remove(opts)); - } - - onRender() { - const { $el, em } = this; - em && $el.attr({ class: `${em.config.stylePrefix}frames` }); - } - protected renderView(item: any, type: string){return new FrameWrapView(item, this.canvasView)} -} - -//FramesView.prototype.itemView = FrameWrapView; diff --git a/src/dom_components/model/Components.js b/src/dom_components/model/Components.js index 0ccb91565..bbf039546 100644 --- a/src/dom_components/model/Components.js +++ b/src/dom_components/model/Components.js @@ -40,7 +40,7 @@ const getComponentsFromDefs = (items, all = {}, opts = {}) => { }); }; -export default class Components extends Backbone.Collection { +export default Backbone.Collection.extend({ initialize(models, opt = {}) { this.opt = opt; this.listenTo(this, 'add', this.onAdd); @@ -50,7 +50,7 @@ export default class Components extends Backbone.Collection { this.config = config; this.em = em; this.domc = opt.domc || (em && em.get('DomComponents')); - } + }, resetChildren(models, opts = {}) { const coll = this; @@ -60,7 +60,7 @@ export default class Components extends Backbone.Collection { opts.keepIds = getComponentIds(prev).filter(pr => newIds.indexOf(pr) >= 0); toRemove.forEach(md => this.removeChildren(md, coll, opts)); models.each(model => this.onAdd(model)); - } + }, resetFromString(input = '', opts = {}) { opts.keepIds = getComponentIds(this); @@ -71,7 +71,7 @@ export default class Components extends Backbone.Collection { const newCmps = getComponentsFromDefs(cmps, allByID, opts); this.reset(newCmps, opts); this.em?.trigger('component:content', this.parent, opts, input); - } + }, removeChildren(removed, coll, opts = {}) { // Removing a parent component can cause this function @@ -123,7 +123,7 @@ export default class Components extends Backbone.Collection { em.stopListening(removed); em.stopListening(removed.get('classes')); removed.__postRemove(); - } + }, model(attrs, options) { const { opt } = options.collection; @@ -155,7 +155,7 @@ export default class Components extends Backbone.Collection { } return new model(attrs, options); - } + }, parseString(value, opt = {}) { const { em, domc } = this; @@ -173,7 +173,7 @@ export default class Components extends Backbone.Collection { } return parsed.html; - } + }, add(models, opt = {}) { opt.keepIds = [...(opt.keepIds || []), ...getComponentIds(opt.previousModels)]; @@ -197,7 +197,7 @@ export default class Components extends Backbone.Collection { const result = Backbone.Collection.prototype.add.apply(this, [models, opt]); this.__firstAdd = result; return result; - } + }, /** * Process component definition. @@ -250,7 +250,7 @@ export default class Components extends Backbone.Collection { } return model; - } + }, onAdd(model, c, opts = {}) { const { domc, em } = this; @@ -267,9 +267,9 @@ export default class Components extends Backbone.Collection { model.__postAdd({ recursive: 1 }); this.__onAddEnd(); - } + }, - __onAddEnd = debounce(function () { + __onAddEnd: debounce(function () { // TODO to check symbols on load, probably this might be removed as symbols // are always recovered from the model // const { domc } = this; @@ -295,5 +295,5 @@ export default class Components extends Backbone.Collection { // }); // }; // onAll(toCheck); - }); -} + }), +}); diff --git a/src/dom_components/view/ComponentView.js b/src/dom_components/view/ComponentView.js index ffbe1c0e0..3c1e3d43e 100644 --- a/src/dom_components/view/ComponentView.js +++ b/src/dom_components/view/ComponentView.js @@ -6,14 +6,14 @@ import Selectors from 'selector_manager/model/Selectors'; import { replaceWith } from 'utils/dom'; import { setViewEl } from 'utils/mixins'; -export default class ComponentView extends Backbone.View { +export default Backbone.View.extend({ className() { return this.getClasses(); - } + }, tagName() { return this.model.get('tagName'); - } + }, initialize(opt = {}) { const model = this.model; @@ -50,13 +50,13 @@ export default class ComponentView extends Backbone.View { }; this.delegateEvents(); !modelOpt.temporary && this.init(this._clbObj()); - } + }, __isDraggable() { const { model, config } = this; const { draggable } = model.attributes; return config.draggableComponents && draggable; - } + }, _clbObj() { const { em, model, el } = this; @@ -65,27 +65,27 @@ export default class ComponentView extends Backbone.View { model, el, }; - } + }, /** * Initialize callback */ - init() {} + init() {}, /** * Remove callback */ - removed() {} + removed() {}, /** * Callback executed when the `active` event is triggered on component */ - onActive() {} + onActive() {}, /** * Callback executed when the `disable` event is triggered on component */ - onDisable() {} + onDisable() {}, remove() { Backbone.View.prototype.remove.apply(this, arguments); @@ -102,7 +102,7 @@ export default class ComponentView extends Backbone.View { $el.data({ model: '', collection: '', view: '' }); // delete model.view; // Sorter relies on this property return this; - } + }, handleDragStart(event) { if (!this.__isDraggable()) return false; @@ -112,7 +112,7 @@ export default class ComponentView extends Backbone.View { target: this.model, event, }); - } + }, initClasses() { const { model } = this; @@ -125,7 +125,7 @@ export default class ComponentView extends Backbone.View { this.listenTo(classes, 'add remove change', this.updateClasses); classes.length && this.importClasses(); } - } + }, initComponents(opts = {}) { const { model, $el, childrenView } = this; @@ -140,7 +140,7 @@ export default class ComponentView extends Backbone.View { !opts.avoidRender && this.renderChildren(); this.listenTo(...toListen); } - } + }, /** * Handle any property change @@ -155,7 +155,7 @@ export default class ComponentView extends Backbone.View { for (let prop in model.changed) { model.emitUpdate(prop); } - } + }, /** * Import, if possible, classes inside main container @@ -169,7 +169,7 @@ export default class ComponentView extends Backbone.View { clm.add(m.get('name')); }); } - } + }, /** * Update item on status change @@ -212,7 +212,7 @@ export default class ComponentView extends Backbone.View { cls = cls.trim(); cls && el.setAttribute('class', cls); - } + }, /** * Update highlight attribute @@ -223,7 +223,7 @@ export default class ComponentView extends Backbone.View { const isTextable = model.get('textable'); const hl = model.get('highlightable') && (isTextable || !model.isChildOf('text')); this.setAttribute('data-gjs-highlightable', hl ? true : ''); - } + }, /** * Update style attribute @@ -238,7 +238,7 @@ export default class ComponentView extends Backbone.View { } else { this.setAttribute('style', model.styleToString(opts)); } - } + }, /** * Update classe attribute @@ -251,7 +251,7 @@ export default class ComponentView extends Backbone.View { // Regenerate status class this.updateStatus(); this.onAttrUpdate(); - } + }, /** * Update single attribute @@ -261,7 +261,7 @@ export default class ComponentView extends Backbone.View { setAttribute(name, value) { const el = this.$el; value ? el.attr(name, value) : el.removeAttr(name); - } + }, /** * Get classes from attributes. @@ -272,7 +272,7 @@ export default class ComponentView extends Backbone.View { * */ getClasses() { return this.model.getClasses().join(' '); - } + }, /** * Update attributes @@ -304,7 +304,7 @@ export default class ComponentView extends Backbone.View { keys(attr).forEach(key => attr[key] === false && delete attr[key]); $el.attr(attr); - } + }, /** * Update component content @@ -314,7 +314,7 @@ export default class ComponentView extends Backbone.View { const content = this.model.get('content'); const hasComps = this.model.components().length; this.getChildrenContainer().innerHTML = hasComps ? '' : content; - } + }, /** * Prevent default helper @@ -323,7 +323,7 @@ export default class ComponentView extends Backbone.View { */ prevDef(e) { e.preventDefault(); - } + }, /** * Render component's script @@ -333,7 +333,7 @@ export default class ComponentView extends Backbone.View { const { model, em } = this; if (!model.get('script')) return; em && em.get('Canvas').getCanvasView().updateScript(this); - } + }, /** * Return children container @@ -369,7 +369,7 @@ export default class ComponentView extends Backbone.View { } return container; - } + }, /** * This returns rect informations not affected by the canvas zoom. @@ -399,7 +399,7 @@ export default class ComponentView extends Backbone.View { assignRect(target); return rect; - } + }, isInViewport({ rect } = {}) { const { el } = this; @@ -415,7 +415,7 @@ export default class ComponentView extends Backbone.View { top <= frame.scrollBottom && left <= frameElement.offsetWidth + body.scrollLeft ); - } + }, scrollIntoView(opts = {}) { const rect = this.getOffsetRect(); @@ -435,7 +435,7 @@ export default class ComponentView extends Backbone.View { }); } } - } + }, /** * Recreate the element of the view @@ -447,18 +447,18 @@ export default class ComponentView extends Backbone.View { this._setData(); replaceWith(el, this.el); this.render(); - } + }, _setData() { const { model } = this; const collection = model.components(); const view = this; this.$el.data({ model, collection, view }); - } + }, _getFrame() { - return this.config.em?.get('Canvas').config.frameView; - } + return this.config.frameView; + }, /** * Render children components @@ -482,14 +482,14 @@ export default class ComponentView extends Backbone.View { for (var i = 0, len = childNodes.length; i < len; i++) { container.appendChild(childNodes.shift()); } - } + }, renderAttributes() { this.updateAttributes(); this.updateClasses(); - } + }, - onAttrUpdate() {} + onAttrUpdate() {}, render() { this.renderAttributes(); @@ -500,13 +500,13 @@ export default class ComponentView extends Backbone.View { this.postRender(); return this; - } + }, postRender() { if (!this.modelOpt.temporary) { this.onRender(this._clbObj()); } - } + }, - onRender() {} -} + onRender() {}, +}); diff --git a/src/editor/index.ts b/src/editor/index.ts index c1ca114d3..42dfd7627 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -54,15 +54,14 @@ * ## Methods * @module Editor */ -import { EventHandler } from "backbone"; -import { isUndefined } from "underscore"; -import { IBaseModule } from "../abstract/Module"; -import CanvasModule from "../canvas"; -import cash from "../utils/cash-dom"; -import html from "../utils/html"; -import defaults from "./config/config"; -import EditorModel from "./model/Editor"; -import EditorView from "./view/EditorView"; +import { EventHandler } from 'backbone'; +import { isUndefined } from 'underscore'; +import { IBaseModule } from '../abstract/Module'; +import cash from '../utils/cash-dom'; +import html from '../utils/html'; +import defaults from './config/config'; +import EditorModel from './model/Editor'; +import EditorView from './view/EditorView'; export default class EditorModule implements IBaseModule { constructor(config = {}, opts: any = {}) { @@ -113,7 +112,7 @@ export default class EditorModule implements IBaseModule { get Panels(): PanelsModule { return this.em.get('Panels'); } - + //@ts-ignore get Canvas(): CanvasModule { return this.em.get('Canvas'); } diff --git a/src/editor/model/Editor.ts b/src/editor/model/Editor.ts index 4c70b14fd..ed12e06d5 100644 --- a/src/editor/model/Editor.ts +++ b/src/editor/model/Editor.ts @@ -101,6 +101,7 @@ export default class EditorModel extends Model { get selected(): Selected { return this.get('selected'); } + constructor(conf = {}) { super(); this._config = conf; @@ -821,8 +822,8 @@ export default class EditorModel extends Model { return this.get('DomComponents').getWrapper(); } - setCurrentFrame(frameView?: FrameView) { - return this.set("currentFrame", frameView); + setCurrentFrame(frameView: FrameView) { + return this.set('currentFrame', frameView); } getCurrentFrame(): FrameView { diff --git a/src/pages/model/Page.ts b/src/pages/model/Page.ts index d247b82ff..adde8ed0e 100644 --- a/src/pages/model/Page.ts +++ b/src/pages/model/Page.ts @@ -25,9 +25,7 @@ export default class Page extends Model { ['component', 'styles'].map((i) => this.unset(i)); } const frms: any[] = props.frames || [defFrame]; - const frames = new Frames(em.get("Canvas"), - frms?.map((model) => new Frame(em.get("Canvas"), model)) - ); + const frames = new Frames(frms?.map((model) => new Frame(model, opts))); frames.page = this; this.set('frames', frames); !this.getId() && this.set('id', em?.get('PageManager')._createId()); @@ -36,7 +34,7 @@ export default class Page extends Model { } onRemove() { - this.getFrames().reset(); + this.get('frames').reset(); } getFrames(): Frames { @@ -87,6 +85,7 @@ export default class Page extends Model { * const mainFrame = page.getMainFrame(); */ getMainFrame(): Frame { + //@ts-ignore return this.getFrames().at(0); } diff --git a/src/utils/dom.js b/src/utils/dom.js index 2e5b5f993..01d718649 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -5,7 +5,8 @@ const KEY_TAG = 'tag'; const KEY_ATTR = 'attributes'; const KEY_CHILD = 'children'; -export const motionsEv = 'transitionend oTransitionEnd transitionend webkitTransitionEnd'; +export const motionsEv = + 'transitionend oTransitionEnd transitionend webkitTransitionEnd'; export const isDoc = el => el && el.nodeType === 9; @@ -17,10 +18,14 @@ export const removeEl = el => { export const find = (el, query) => el.querySelectorAll(query); export const attrUp = (el, attrs = {}) => - el && el.setAttribute && each(attrs, (value, key) => el.setAttribute(key, value)); + el && + el.setAttribute && + each(attrs, (value, key) => el.setAttribute(key, value)); export const isVisible = el => { - return el && !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); + return ( + el && !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length) + ); }; export const empty = node => { @@ -51,7 +56,7 @@ export const appendAtIndex = (parent, child, index) => { export const append = (parent, child) => appendAtIndex(parent, child); -export const createEl = (tag, attrs = {}, child) => { +export const createEl = (tag, attrs = '', child) => { const el = document.createElement(tag); attrs && each(attrs, (value, key) => el.setAttribute(key, value)); @@ -85,7 +90,7 @@ export const createCustomEvent = (e, cls) => { Object.defineProperty(oEvent, prop, { get() { return this.keyCodeVal; - }, + } }); }); } diff --git a/src/utils/mixins.js b/src/utils/mixins.js index c12153fe6..eea59a0a1 100644 --- a/src/utils/mixins.js +++ b/src/utils/mixins.js @@ -85,13 +85,7 @@ const shallowDiff = (objOrig, objNew) => { return result; }; -/** - * @param {Object} el - * @param {string} ev - * @param {(ev: Event) => any} fn - * @param {Objec} opts - */ -const on = (el, ev, fn, opts = {}) => { +const on = (el, ev, fn, opts) => { ev = ev.split(/\s+/); el = el instanceof Array ? el : [el]; @@ -222,11 +216,6 @@ const getModel = (el, $) => { return model; }; -/** - * Get DomRect for the el - * @param {any} el Component or HTML element - * @return {DOMRect} - */ const getElRect = el => { const def = { top: 0, @@ -250,7 +239,7 @@ const getElRect = el => { /** * Get cross-device pointer event * @param {Event} ev - * @return {PointerEvent} + * @return {Event} */ const getPointerEvent = ev => (ev.touches && ev.touches[0] ? ev.touches[0] : ev);