Browse Source

Convert rest to ts

pull/4316/head
Alex Ritter 4 years ago
parent
commit
e9c933ae2e
  1. 102
      src/abstract/DomainViews.ts
  2. 4
      src/abstract/Model.ts
  3. 7
      src/abstract/View.ts
  4. 82
      src/canvas/index.ts
  5. 3
      src/canvas/model/Canvas.ts
  6. 61
      src/canvas/model/Frame.ts
  7. 5
      src/canvas/model/Frames.ts
  8. 12
      src/canvas/view/CanvasView.ts
  9. 125
      src/canvas/view/FrameView.ts
  10. 66
      src/canvas/view/FrameWrapView.ts
  11. 21
      src/canvas/view/FramesView.js
  12. 26
      src/canvas/view/FramesView.ts
  13. 2
      src/dom_components/view/ComponentView.js
  14. 3
      src/editor/model/Editor.ts
  15. 8
      src/pages/model/Page.ts
  16. 15
      src/utils/mixins.js

102
src/abstract/DomainViews.ts

@ -0,0 +1,102 @@
import { includes } from 'underscore';
import Backbone from 'backbone';
import View from './View';
import Model from './Model';
/*interface DomainView<TView, TModel>{
constructor(model: TModel): TView
}*/
type TModel<TCollection> = TCollection extends Backbone.Collection<infer TModel>? TModel: Model;
export default abstract class DomainViews<TCollection extends Backbone.Collection<Model>, TItemView extends View> extends View<TModel<TCollection>> {
// 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<TCollection>) {
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<TCollection>, itemType: string): TItemView;
/**
* Render new model inside the view
* @param {Model} model
* @param {Object} fragment Fragment collection
* @private
* */
private add(model: TModel<TCollection>, 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 = [];
}
}

4
src/abstract/Model.ts

@ -26,10 +26,6 @@ export default class Model<
return this._module.config;
}
protected get em() {
return this._module.em;
}
public get em() {
return this._module.em;
}

7
src/abstract/View.ts

@ -7,7 +7,7 @@ export default class View<
TElement extends Element = HTMLElement
> extends Backbone.View<TModel, TElement> {
protected get pfx() {
return (this.model.em.config as any).stylePrefix || "";
return (this.em.config as any).stylePrefix || "";
}
protected get ppfx() {
@ -15,11 +15,12 @@ export default class View<
}
protected get module(): TModel extends Model<infer M>? M: unknown {
return this.model.module as any;
//console.log((this.collection.first as any).module)
return this.model?.module ?? (this.collection as any).module;
}
protected get em() {
return this.model.em;
return this.module.em;
}
protected get config(): TModel extends Model<infer M> ? (M extends IBaseModule<infer C> ? C : unknown) : unknown{

82
src/canvas/index.ts

@ -69,16 +69,10 @@ export default class CanvasModule extends Module<typeof defaults> {
}
//name = 'Canvas';
c: any;
//em: EditorModel;
canvas: Canvas;
model: Canvas;
private _canvasView?: CanvasView;
private canvasView?: CanvasView;
get canvasView(): CanvasView{
return this._canvasView as any
}
/**
* Initialize module. Automatically called with a new instance of the editor
* @param {Object} config Configurations
@ -86,10 +80,7 @@ export default class CanvasModule extends Module<typeof defaults> {
*/
constructor(em: EditorModel) {
super(em, "Canvas", defaults)
this.c = {
...this.config,
module: this,
};
this.canvas = new Canvas(this);
this.model = this.canvas;
this.startAutoscroll = this.startAutoscroll.bind(this);
@ -108,22 +99,12 @@ export default class CanvasModule extends Module<typeof defaults> {
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.canvasView.el;
return this.getCanvasView().el;
}
getFrame(index?: number) {
@ -134,9 +115,9 @@ export default class CanvasModule extends Module<typeof defaults> {
* Get the main frame element of the canvas
* @returns {HTMLIFrameElement}
*/
getFrameEl(): HTMLIFrameElement {
getFrameEl() {
const { frame } = this.canvasView || {};
return frame && frame.el;
return frame?.el as HTMLIFrameElement;
}
getFramesEl() {
@ -148,7 +129,8 @@ export default class CanvasModule extends Module<typeof defaults> {
* @returns {Window}
*/
getWindow() {
return this.getFrameEl().contentWindow;
const { frame } = this.canvasView || {};
return frame?.getWindow() as Window;
}
/**
@ -157,7 +139,7 @@ export default class CanvasModule extends Module<typeof defaults> {
*/
getDocument() {
const frame = this.getFrameEl();
return frame && frame.contentDocument as Document;
return frame?.contentDocument as Document;
}
/**
@ -166,7 +148,7 @@ export default class CanvasModule extends Module<typeof defaults> {
*/
getBody() {
const doc = this.getDocument();
return doc && doc.body;
return doc?.body as HTMLBodyElement;
}
_getLocalEl(globalEl: any, compView: any, method: keyof FrameView) {
@ -192,7 +174,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getToolsEl(compView: any) {
return this._getLocalEl(this.canvasView.toolsEl, compView, 'getToolsEl');
return this._getLocalEl(this.getCanvasView().toolsEl, compView, 'getToolsEl');
}
/**
@ -201,7 +183,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getHighlighter(compView: any) {
return this._getLocalEl(this.canvasView.hlEl, compView, 'getHighlighter');
return this._getLocalEl(this.getCanvasView().hlEl, compView, 'getHighlighter');
}
/**
@ -210,7 +192,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getBadgeEl(compView: any) {
return this._getLocalEl(this.canvasView.badgeEl, compView, 'getBadgeEl');
return this._getLocalEl(this.getCanvasView().badgeEl, compView, 'getBadgeEl');
}
/**
@ -219,7 +201,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getPlacerEl() {
return this.canvasView.placerEl;
return this.getCanvasView().placerEl;
}
/**
@ -228,7 +210,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getGhostEl() {
return this.canvasView.ghostEl;
return this.getCanvasView().ghostEl;
}
/**
@ -237,7 +219,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getToolbarEl() {
return this.canvasView.toolbarEl;
return this.getCanvasView().toolbarEl;
}
/**
@ -246,7 +228,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getResizerEl() {
return this.canvasView.resizerEl;
return this.getCanvasView().resizerEl;
}
/**
@ -255,7 +237,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getOffsetViewerEl(compView: any) {
return this._getLocalEl(this.canvasView.offsetEl, compView, 'getOffsetViewerEl');
return this._getLocalEl(this.getCanvasView().offsetEl, compView, 'getOffsetViewerEl');
}
/**
@ -264,12 +246,12 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getFixedOffsetViewerEl() {
return this.canvasView.fixedOffsetEl;
return this.getCanvasView().fixedOffsetEl;
}
render() {
this.canvasView?.remove();
this._canvasView = new CanvasView({model: this.canvas, config: this.c});
this.canvasView = new CanvasView(this.canvas);
return this.canvasView.render().el;
}
@ -294,7 +276,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
offset(el: HTMLElement) {
return this.canvasView?.offset(el);
return this.getCanvasView().offset(el);
}
/**
@ -306,7 +288,8 @@ export default class CanvasModule extends Module<typeof defaults> {
* });
*/
setCustomBadgeLabel(f: Function) {
this.c.customBadgeLabel = f;
//@ts-ignore
this.config.customBadgeLabel = f;
}
/**
@ -316,7 +299,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getElementPos(el: HTMLElement, opts?: any) {
return this.canvasView.getElementPos(el, opts);
return this.getCanvasView().getElementPos(el, opts);
}
/**
@ -326,7 +309,7 @@ export default class CanvasModule extends Module<typeof defaults> {
* @private
*/
getElementOffsets(el: HTMLElement) {
return this.canvasView.getElementOffsets(el);
return this.getCanvasView().getElementOffsets(el);
}
/**
@ -334,9 +317,9 @@ export default class CanvasModule extends Module<typeof defaults> {
* @returns {Object}
*/
getRect() {
const { top, left } = this.canvasView.getPosition();
const { top = 0, left = 0 } = this.getCanvasView().getPosition() ?? {};
return {
...this.canvasView.getCanvasOffset(),
...this.getCanvasView().getCanvasOffset(),
topScroll: top,
leftScroll: left,
};
@ -360,9 +343,9 @@ export default class CanvasModule extends Module<typeof defaults> {
*/
getTargetToElementDim(target: HTMLElement, element: HTMLElement, options: any = {}) {
var opts = options || {};
var canvasPos = this.canvasView.getPosition();
var canvasPos = this.getCanvasView().getPosition();
if (!canvasPos) return;
var pos = opts.elPos || this.canvasView.getElementPos(element);
var pos = opts.elPos || this.getCanvasView().getElementPos(element);
var toRight = options.toRight || 0;
var targetHeight = opts.targetHeight || target.offsetHeight;
var targetWidth = opts.targetWidth || target.offsetWidth;
@ -442,7 +425,8 @@ export default class CanvasModule extends Module<typeof defaults> {
let top = -toolbarH;
let left = !isUndefined(opts.left) ? opts.left : pos.width - toolbarW;
left = pos.left < -left ? -pos.left : left;
left = elRight > frCvOff.width ? left - (elRight - frCvOff.width) : left;
const frCvWidth = frCvOff?.width ?? 0;
left = elRight > frCvWidth ? left - (elRight - frCvWidth) : left;
// Scroll with the window if the top edge is reached and the
// element is bigger than the canvas
@ -509,7 +493,7 @@ export default class CanvasModule extends Module<typeof defaults> {
*/
getMouseRelativeCanvas(ev: MouseEvent, opts: any) {
const zoom = this.getZoomDecimal();
const { top, left } = this.getCanvasView().getPosition(opts);
const { top = 0, left = 0 } = this.getCanvasView().getPosition(opts) ?? {};
return {
y: ev.clientY * zoom + top,
@ -670,13 +654,13 @@ export default class CanvasModule extends Module<typeof defaults> {
* });
*/
addFrame(props = {}, opts = {}) {
return this.canvas.frames.add(new Frame({ ...props }, { em: this.em }), opts);
return this.canvas.frames.add(new Frame(this, { ...props }), opts);
}
destroy() {
this.canvas.stopListening();
this.canvasView?.remove();
[this.c, this.canvas, this.canvasView].forEach(i => (i = {}));
//[this.canvas, this.canvasView].forEach(i => (i = {}));
//@ts-ignore
['model', 'droppable'].forEach(i => (this[i] = {}));
}

3
src/canvas/model/Canvas.ts

@ -8,7 +8,7 @@ export default class Canvas extends Model<CanvasModule> {
defaults() {
return {
frame: '',
frames: new Frames(),
frames: [],
rulers: false,
zoom: 100,
x: 0,
@ -24,6 +24,7 @@ export default class Canvas extends Model<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);
this.listenTo(em, evPageSelect, this._pageUpdated);

61
src/canvas/model/Frame.ts

@ -1,15 +1,16 @@
import { result, forEach, isEmpty, isString } from 'underscore';
import { Model } from '../../common';
import { Component } from '../../dom_components/model/Component';
import Components from '../../dom_components/model/Components';
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';
const keyAutoW = '__aw';
const keyAutoH = '__ah';
import { result, forEach, isEmpty, isString } from "underscore";
import CanvasModule from "..";
import { Model } from "../../abstract";
import Component from "../../dom_components/model/Component";
import Components from "../../dom_components/model/Components";
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";
const keyAutoW = "__aw";
const keyAutoH = "__ah";
/**
* @property {Object|String} component Wrapper component definition. You can also pass an HTML string as components of the default wrapper component.
@ -19,7 +20,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<CanvasModule> {
defaults() {
return {
x: 0,
@ -35,18 +36,16 @@ export default class Frame extends Model {
_undoexc: ['changesCount'],
};
}
em: EditorModel;
view?: FrameView;
constructor(props: any, opts: any) {
super(props);
const { em } = opts;
constructor(module: CanvasModule, props: any) {
super(module, props);
const { em } = this;
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)) {
@ -87,6 +86,10 @@ 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,23 +120,19 @@ export default class Frame extends Model {
}
getHead() {
const head = this.get('head') || [];
return [...head];
return [...this.head];
}
setHead(value: any) {
return this.set('head', [...value]);
setHead(value: {tag: string, attributes: any}[]) {
return this.set("head", [...value]);
}
addHeadItem(item: any) {
const head = this.getHead();
head.push(item);
this.setHead(head);
addHeadItem(item: {tag: string, attributes: any}) {
this.head.push(item);
}
getHeadByAttr(attr: string, value: any, tag: string) {
const head = this.getHead();
return head.filter(
return this.head.filter(
(item) =>
item.attributes &&
item.attributes[attr] == value &&
@ -142,13 +141,11 @@ 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 = head.indexOf(item);
const index = this.head.indexOf(item);
if (index >= 0) {
head.splice(index, 1);
this.setHead(head);
this.head.splice(index, 1);
}
}

5
src/canvas/model/Frames.ts

@ -1,4 +1,5 @@
import { bindAll } from 'underscore';
import CanvasModule from '..';
import { Collection } from '../../common';
import Page from '../../pages/model/Page';
import Frame from './Frame';
@ -7,9 +8,11 @@ export default class Frames extends Collection<Frame> {
loadedItems = 0;
itemsToLoad = 0;
page?: Page;
module: CanvasModule
constructor(models?: Frame[]) {
constructor(module: CanvasModule, models: Frame[] = []) {
super(models);
this.module = module;
bindAll(this, 'itemLoaded');
this.on('reset', this.onReset);
this.on('remove', this.onRemove);

12
src/canvas/view/CanvasView.ts

@ -4,9 +4,7 @@ import { on, off, getElement, getKeyChar, isTextNode, getElRect, getUiClass } fr
import { createEl } from '../../utils/dom';
import FramesView from './FramesView';
import Canvas from '../model/Canvas';
import Frame from '../model/Frame';
import FrameView from './FrameView';
import Components from '../../dom_components/model/Components';
import ComponentView from '../../dom_components/view/ComponentView';
import Component from '../../dom_components/model/Component';
@ -79,13 +77,13 @@ export default class CanvasView extends View<Canvas> {
_initFrames() {
const { frames, model, config, em } = this;
const collection = model.get('frames');
const collection = model.frames;
em.set('readyCanvas', 0);
collection.once('loaded:all', () => em.set('readyCanvas', 1));
frames?.remove();
this.frames = new FramesView({
collection,
config: {
this.frames = new FramesView(
{collection},
{config: {
...config,
canvasView: this,
},
@ -296,7 +294,7 @@ export default class CanvasView extends View<Canvas> {
* @public
*/
getPosition(opts: any = {}) {
const doc = this.frame?.el.contentDocument;
if (!doc) return;
const bEl = doc.body;

125
src/canvas/view/FrameView.js → src/canvas/view/FrameView.ts

@ -1,31 +1,47 @@
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 '../../common';
import { View } from '../../abstract';
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 {
tagName() {
return 'iframe';
}
export default class FrameView extends View<Frame, HTMLIFrameElement> {
attributes() {
return {
allowfullscreen: 'allowfullscreen',
};
}
//@ts-ignore
get tagName(){return 'iframe'};
//@ts-ignore
get attributes() {return { allowfullscreen: 'allowfullscreen' }};
dragging = false;
droppable?: Droppable;
rect?: DOMRect;
initialize(o) {
lastClientY?: number;
lastMaxHeight = 0;
private jsContainer?: HTMLElement;
private tools: {[key: string]: HTMLElement} = {};
private wrapper?: any;
private frameWrapView?: FrameWrapView;
constructor(model: Frame, view?: FrameWrapView) {
super({model});
bindAll(this, 'updateClientY', 'stopAutoscroll', 'autoscroll', '_emitUpdate');
const { model, el } = this;
this.tools = {};
this.config = {
...(o.config || {}),
const { el, em } = this;
//el = em.config.el
//@ts-ignore
this.module._config = {
...(this.config || {}),
//@ts-ignore
frameView: this,
//canvasView: view?.cv
};
this.ppfx = this.config.pStylePrefix || '';
this.em = this.model.em;
//console.log(this.config)
this.frameWrapView = view;
this.showGlobalTools = debounce(this.showGlobalTools.bind(this), 50);
const cvModel = this.getCanvasModel();
this.listenTo(model, 'change:head', this.updateHead);
@ -40,16 +56,16 @@ export default class FrameView extends View {
updateHead() {
const { model } = this;
const headEl = this.getHead();
const toRemove = [];
const toAdd = [];
const current = model.get('head');
const toRemove: any[] = [];
const toAdd: any[] = [];
const current = model.head;
const prev = model.previous('head');
const attrStr = (attr = {}) =>
const attrStr = (attr: any = {}) =>
Object.keys(attr)
.sort()
.map(i => `[${i}="${attr[i]}"]`)
.join('');
const find = (items, stack, res) => {
const find = (items: any[], stack: any[], res: any[]) => {
items.forEach(item => {
const { tag, attributes } = item;
const has = stack.some(s => s.tag === tag && attrStr(s.attributes) === attrStr(attributes));
@ -60,7 +76,7 @@ export default class FrameView extends View {
find(prev, current, toRemove);
toRemove.forEach(stl => {
const el = headEl.querySelector(`${stl.tag}${attrStr(stl.attributes)}`);
el && el.parentNode.removeChild(el);
el?.parentNode?.removeChild(el);
});
appendVNodes(headEl, toAdd);
}
@ -69,28 +85,28 @@ export default class FrameView extends View {
return this.el;
}
getCanvasModel() {
getCanvasModel(): Canvas {
return this.em.get('Canvas').getModel();
}
getWindow() {
return this.getEl().contentWindow;
return this.getEl().contentWindow as Window;
}
getDoc() {
return this.getEl().contentDocument;
return this.getEl().contentDocument as Document;
}
getHead() {
return this.getDoc().querySelector('head');
return this.getDoc().querySelector('head') as HTMLHeadElement;
}
getBody() {
return this.getDoc().querySelector('body');
return this.getDoc().querySelector('body') as HTMLBodyElement;
}
getWrapper() {
return this.getBody().querySelector('[data-gjs-type=wrapper]');
return this.getBody().querySelector('[data-gjs-type=wrapper]') as HTMLElement;
}
getJsContainer() {
@ -102,8 +118,7 @@ export default class FrameView extends View {
}
getToolsEl() {
const { frameWrapView } = this.config;
return frameWrapView && frameWrapView.elTools;
return this.frameWrapView?.elTools as HTMLElement;
}
getGlobalToolsEl() {
@ -151,23 +166,24 @@ export default class FrameView extends View {
};
}
_getTool(name) {
_getTool(name: string) {
const { tools } = this;
const toolsEl = this.getToolsEl();
if (!tools[name]) {
tools[name] = toolsEl.querySelector(name);
tools[name] = toolsEl.querySelector(name) as HTMLElement;
}
return tools[name];
}
remove() {
remove(...args: any) {
const wrp = this.wrapper;
this._toggleEffects();
this._toggleEffects(false);
this.tools = {};
wrp && wrp.remove();
View.prototype.remove.apply(this, arguments);
View.prototype.remove.apply(this, args);
return this;
}
startAutoscroll() {
@ -176,7 +192,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(1);
this._toggleAutoscrollFx(true);
requestAnimationFrame(this.autoscroll);
}, 0);
}
@ -217,7 +233,7 @@ export default class FrameView extends View {
}
}
updateClientY(ev) {
updateClientY(ev: Event) {
ev.preventDefault();
this.lastClientY = getPointerEvent(ev).clientY * this.em.getZoomDecimal();
}
@ -227,10 +243,10 @@ export default class FrameView extends View {
}
stopAutoscroll() {
this.dragging && this._toggleAutoscrollFx();
this.dragging && this._toggleAutoscrollFx(false);
}
_toggleAutoscrollFx(enable) {
_toggleAutoscrollFx(enable: boolean) {
this.dragging = enable;
const win = this.getWindow();
const method = enable ? 'on' : 'off';
@ -251,7 +267,7 @@ export default class FrameView extends View {
const evLoad = 'frame:load';
const evOpts = { el, model, view: this };
const canvas = this.getCanvasModel();
const appendScript = scripts => {
const appendScript = (scripts: any[]) => {
if (scripts.length > 0) {
const src = scripts.shift();
const scriptEl = createEl('script', {
@ -259,7 +275,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);
@ -279,10 +295,10 @@ export default class FrameView extends View {
};
}
renderStyles(opts = {}) {
renderStyles(opts: any = {}) {
const head = this.getHead();
const canvas = this.getCanvasModel();
const normalize = stls =>
const normalize = (stls: any[]) =>
stls.map(href => ({
tag: 'link',
attributes: {
@ -292,9 +308,9 @@ export default class FrameView extends View {
}));
const prevStyles = normalize(opts.prev || canvas.previous('styles'));
const styles = normalize(canvas.get('styles'));
const toRemove = [];
const toAdd = [];
const find = (items, stack, res) => {
const toRemove: any[] = [];
const toAdd: any[] = [];
const find = (items: any[], stack: any[], res: any[]) => {
items.forEach(item => {
const { href } = item.attributes;
const has = stack.some(s => s.attributes.href === href);
@ -305,7 +321,7 @@ export default class FrameView extends View {
find(prevStyles, styles, toRemove);
toRemove.forEach(stl => {
const el = head.querySelector(`link[href="${stl.attributes.href}"]`);
el && el.parentNode.removeChild(el);
el?.parentNode?.removeChild(el);
});
appendVNodes(head, toAdd);
}
@ -316,6 +332,7 @@ export default class FrameView extends View {
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
win._isEditor = true;
this.renderStyles({ prev: [] });
@ -398,11 +415,12 @@ 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,
@ -414,7 +432,8 @@ export default class FrameView extends View {
//this.updateOffset(); // TOFIX (check if I need it)
// Avoid some default behaviours
on(body, 'click', ev => ev && ev.target.tagName == 'A' && ev.preventDefault());
//@ts-ignore
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
@ -430,12 +449,12 @@ export default class FrameView extends View {
})
);
this._toggleEffects(1);
this.droppable = hasDnd(em) && new Droppable(em, this.wrapper.el);
this._toggleEffects(true);
this.droppable = hasDnd(em) && new Droppable(em, this.wrapper?.el);
model.trigger('loaded');
}
_toggleEffects(enable) {
_toggleEffects(enable: boolean) {
const method = enable ? on : off;
const win = this.getWindow();
win && method(win, `${motionsEv} resize`, this._emitUpdate);

66
src/canvas/view/FrameWrapView.js → src/canvas/view/FrameWrapView.ts

@ -1,34 +1,37 @@
import { bindAll, isNumber, isNull, debounce } from 'underscore';
import { View } from '../../common';
import { View } from '../../abstract';
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<Frame> {
events() {
return {
'click [data-action-remove]': 'remove',
'mousedown [data-action-move]': 'startDrag',
};
}
initialize(opts = {}, conf = {}) {
elTools?: HTMLElement;
frame: FrameView;
dragger?: Dragger;
cv: CanvasView
classAnim: string
constructor(model: Frame, canvasView: CanvasView) {
super({model});
bindAll(this, 'onScroll', 'frameLoaded', 'updateOffset', 'remove', 'startDrag');
const { model } = this;
//console.log(model.module)
const config = {
...(opts.config || conf),
...(model.config),
frameWrapView: this,
};
const { canvasView } = config;
this.cv = canvasView;
this.config = config;
this.em = this.model.em;
this.canvas = this.em?.get('Canvas');
this.ppfx = config.pStylePrefix || '';
this.frame = new FrameView({ model, config });
this.frame = new FrameView(model, this);
this.classAnim = `${this.ppfx}frame-wrapper--anim`;
this.updateOffset = debounce(this.updateOffset.bind(this));
this.updateSize = debounce(this.updateSize.bind(this));
this.updateOffset = debounce(this.updateOffset.bind(this), 0);
this.updateSize = debounce(this.updateSize.bind(this), 0);
this.listenTo(model, 'loaded', this.frameLoaded);
this.listenTo(model, 'change:x change:y', this.updatePos);
this.listenTo(model, 'change:width change:height', this.updateSize);
@ -38,10 +41,10 @@ export default class FrameWrapView extends View {
}
setupDragger() {
const { canvas, model } = this;
let dragX, dragY, zoom;
const toggleEffects = on => {
canvas.toggleFramesEvents(on);
const { module, model } = this;
let dragX: number, dragY: number, zoom: number;
const toggleEffects = (on: boolean) => {
module.toggleFramesEvents(on);
};
this.dragger = new Dragger({
@ -50,10 +53,10 @@ export default class FrameWrapView extends View {
zoom = this.em.getZoomMultiplier();
dragX = x;
dragY = y;
toggleEffects();
toggleEffects(false);
},
onEnd: () => toggleEffects(1),
setPosition: posOpts => {
onEnd: () => toggleEffects(true),
setPosition: (posOpts: any) => {
model.set({
x: dragX + posOpts.x * zoom,
y: dragY + posOpts.y * zoom,
@ -62,20 +65,21 @@ export default class FrameWrapView extends View {
});
}
startDrag(ev) {
ev && this.dragger.start(ev);
startDrag(ev?: Event) {
ev && this.dragger?.start(ev);
}
__clear(opts) {
__clear(opts?: any) {
const { frame } = this;
frame && frame.remove(opts);
removeEl(this.elTools);
}
remove(opts) {
remove(opts?: any) {
this.__clear(opts);
View.prototype.remove.apply(this, arguments);
['frame', 'dragger', 'cv', 'em', 'canvas', 'elTools'].forEach(i => (this[i] = 0));
View.prototype.remove.apply(this, opts);
//@ts-ignore
['frame', 'dragger', 'cv', 'elTools'].forEach(i => (this[i] = 0));
return this;
}
@ -87,11 +91,11 @@ export default class FrameWrapView extends View {
frame.model._emitUpdated();
}
updatePos(md) {
updatePos(md?: boolean) {
const { model, el } = this;
const { x, y } = model.attributes;
const { style } = el;
this.frame.rect = 0;
this.frame.rect = undefined;
style.left = isNaN(x) ? x : `${x}px`;
style.top = isNaN(y) ? y : `${y}px`;
md && this.updateOffset();
@ -108,7 +112,7 @@ export default class FrameWrapView extends View {
updateDim() {
const { em, el, $el, model, classAnim, frame } = this;
if (!frame) return;
frame.rect = 0;
frame.rect = undefined;
$el.addClass(classAnim);
const { noChanges, width, height } = this.__handleSize();
@ -219,7 +223,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({

21
src/canvas/view/FramesView.js

@ -1,21 +0,0 @@
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 { $el } = this;
const { em } = this.collection.first;
em && $el.attr({ class: `${em.getConfig().stylePrefix}frames` });
}
}
FramesView.prototype.itemView = FrameWrapView;

26
src/canvas/view/FramesView.ts

@ -0,0 +1,26 @@
import DomainViews from '../../abstract/DomainViews';
import Frames from '../model/Frames';
import CanvasView from './CanvasView';
import FrameWrapView from './FrameWrapView';
export default class FramesView extends DomainViews<Frames, FrameWrapView> {
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;

2
src/dom_components/view/ComponentView.js

@ -457,7 +457,7 @@ export default class ComponentView extends Backbone.View {
}
_getFrame() {
return this.config.frameView;
return this.config.em?.get('Canvas').config.frameView;
}
/**

3
src/editor/model/Editor.ts

@ -101,7 +101,6 @@ export default class EditorModel extends Model {
get selected(): Selected {
return this.get('selected');
}
constructor(conf = {}) {
super();
this._config = conf;
@ -401,7 +400,7 @@ export default class EditorModel extends Model {
* @param {Object} [opts={}] Options, optional
* @public
*/
setSelected(el: any | any[], opts: any = {}) {
setSelected(el?: any|any[], opts: any = {}) {
const { event } = opts;
const ctrlKey = event && (event.ctrlKey || event.metaKey);
const { shiftKey } = event || {};

8
src/pages/model/Page.ts

@ -25,9 +25,8 @@ export default class Page extends Model {
['component', 'styles'].map((i) => this.unset(i));
}
const frms: any[] = props.frames || [defFrame];
const frames = new Frames(
frms?.map((model) => new Frame(model, opts)),
opts
const frames = new Frames(em.get("Canvas"),
frms?.map((model) => new Frame(em.get("Canvas"), model))
);
frames.page = this;
this.set('frames', frames);
@ -37,7 +36,7 @@ export default class Page extends Model {
}
onRemove() {
this.get('frames').reset();
this.getFrames().reset();
}
getFrames(): Frames {
@ -88,7 +87,6 @@ export default class Page extends Model {
* const mainFrame = page.getMainFrame();
*/
getMainFrame(): Frame {
//@ts-ignore
return this.getFrames().at(0);
}

15
src/utils/mixins.js

@ -85,7 +85,13 @@ const shallowDiff = (objOrig, objNew) => {
return result;
};
const on = (el, ev, fn, opts) => {
/**
* @param {Object} el
* @param {string} ev
* @param {(ev: Event) => any} fn
* @param {Objec} opts
*/
const on = (el, ev, fn, opts = {}) => {
ev = ev.split(/\s+/);
el = el instanceof Array ? el : [el];
@ -216,6 +222,11 @@ 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,
@ -239,7 +250,7 @@ const getElRect = el => {
/**
* Get cross-device pointer event
* @param {Event} ev
* @return {Event}
* @return {PointerEvent}
*/
const getPointerEvent = ev => (ev.touches && ev.touches[0] ? ev.touches[0] : ev);

Loading…
Cancel
Save