Browse Source

Convert CanvasModule to ts

pull/4316/head
Alex Ritter 4 years ago
parent
commit
dd8fd1d0a0
  1. 10
      src/abstract/Module.ts
  2. 127
      src/canvas/index.ts
  3. 6
      src/canvas/model/Canvas.ts
  4. 36
      src/canvas/view/CanvasView.js
  5. 7
      src/canvas/view/FrameView.js
  6. 6
      src/canvas/view/FrameWrapView.js
  7. 4
      src/canvas/view/FramesView.js

10
src/abstract/Module.ts

@ -20,7 +20,7 @@ export interface IBaseModule<TConfig extends any> {
} }
export interface ModuleConfig { export interface ModuleConfig {
name: string; //name: string;
stylePrefix?: string; stylePrefix?: string;
} }
@ -40,20 +40,18 @@ export default abstract class Module<T extends ModuleConfig = ModuleConfig>
cls: any[] = []; cls: any[] = [];
events: any; events: any;
constructor(em: EditorModel, moduleName: string) { constructor(em: EditorModel, moduleName: string, defaults?: T) {
this._em = em; this._em = em;
this._name = moduleName; this._name = moduleName;
const name = this.name.charAt(0).toLowerCase() + this.name.slice(1); const name = this.name.charAt(0).toLowerCase() + this.name.slice(1);
const cfgParent = !isUndefined(em.config[name]) const cfgParent = !isUndefined(em.config[name]) ? em.config[name] : em.config[this.name];
? em.config[name]
: em.config[this.name];
const cfg = cfgParent === true ? {} : cfgParent || {}; const cfg = cfgParent === true ? {} : cfgParent || {};
cfg.pStylePrefix = em.config.pStylePrefix || ''; cfg.pStylePrefix = em.config.pStylePrefix || '';
if (!isUndefined(cfgParent) && !cfgParent) { if (!isUndefined(cfgParent) && !cfgParent) {
cfg._disable = 1; cfg._disable = 1;
} }
this._config = cfg; this._config = {...defaults, ...cfg};
} }
public get em() { public get em() {

127
src/canvas/index.js → src/canvas/index.ts

@ -47,49 +47,58 @@
* @module Canvas * @module Canvas
*/ */
import { AddOptions } from 'backbone';
import { isUndefined } from 'underscore'; 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 { getElement, getViewEl } from '../utils/mixins';
import defaults from './config/config'; import defaults from './config/config';
import Canvas from './model/Canvas'; import Canvas from './model/Canvas';
import Frame from './model/Frame'; import Frame from './model/Frame';
import CanvasView from './view/CanvasView'; import CanvasView from './view/CanvasView';
import FrameView from './view/FrameView';
export default class CanvasModule { export default class CanvasModule extends Module<typeof defaults> {
/** /**
* Used inside RTE * Used inside RTE
* @private * @private
*/ */
getCanvasView() { getCanvasView(): CanvasView {
return this.canvasView; return this.canvasView as any;
} }
name = 'Canvas'; //name = 'Canvas';
c = {}; c: any;
canvas; //em: EditorModel;
canvasView; canvas: Canvas;
model: Canvas;
private _canvasView?: CanvasView;
get canvasView(): CanvasView{
return this._canvasView as any
}
/** /**
* Initialize module. Automatically called with a new instance of the editor * Initialize module. Automatically called with a new instance of the editor
* @param {Object} config Configurations * @param {Object} config Configurations
* @private * @private
*/ */
init(config = {}) { constructor(em: EditorModel) {
super(em, "Canvas", defaults)
this.c = { this.c = {
...defaults, ...this.config,
...config,
module: this, module: this,
}; };
this.canvas = new Canvas(this.em, this.config);
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.model = this.canvas;
this.startAutoscroll = this.startAutoscroll.bind(this); this.startAutoscroll = this.startAutoscroll.bind(this);
this.stopAutoscroll = this.stopAutoscroll.bind(this); this.stopAutoscroll = this.stopAutoscroll.bind(this);
return this; return this;
} }
init(){
}
onLoad() { onLoad() {
this.model.init(); this.model.init();
@ -117,7 +126,7 @@ export default class CanvasModule {
return this.canvasView.el; return this.canvasView.el;
} }
getFrame(index) { getFrame(index?: number) {
return this.getFrames()[index || 0]; return this.getFrames()[index || 0];
} }
@ -125,13 +134,13 @@ export default class CanvasModule {
* Get the main frame element of the canvas * Get the main frame element of the canvas
* @returns {HTMLIFrameElement} * @returns {HTMLIFrameElement}
*/ */
getFrameEl() { getFrameEl(): HTMLIFrameElement {
const { frame } = this.canvasView || {}; const { frame } = this.canvasView || {};
return frame && frame.el; return frame && frame.el;
} }
getFramesEl() { getFramesEl() {
return this.canvasView.framesArea; return this.canvasView?.framesArea as HTMLElement;
} }
/** /**
@ -148,7 +157,7 @@ export default class CanvasModule {
*/ */
getDocument() { getDocument() {
const frame = this.getFrameEl(); const frame = this.getFrameEl();
return frame && frame.contentDocument; return frame && frame.contentDocument as Document;
} }
/** /**
@ -160,13 +169,9 @@ export default class CanvasModule {
return doc && doc.body; return doc && doc.body;
} }
_getCompFrame(compView) { _getLocalEl(globalEl: any, compView: any, method: keyof FrameView) {
return compView && compView._getFrame();
}
_getLocalEl(globalEl, compView, method) {
let result = globalEl; let result = globalEl;
const frameView = this._getCompFrame(compView); const frameView = compView?._getFrame();
result = frameView ? frameView[method]() : result; result = frameView ? frameView[method]() : result;
return result; return result;
@ -178,7 +183,7 @@ export default class CanvasModule {
* @private * @private
*/ */
getGlobalToolsEl() { getGlobalToolsEl() {
return this.canvasView.toolsGlobEl; return this.canvasView?.toolsGlobEl;
} }
/** /**
@ -186,7 +191,7 @@ export default class CanvasModule {
* @returns {HTMLElement} * @returns {HTMLElement}
* @private * @private
*/ */
getToolsEl(compView) { getToolsEl(compView: any) {
return this._getLocalEl(this.canvasView.toolsEl, compView, 'getToolsEl'); return this._getLocalEl(this.canvasView.toolsEl, compView, 'getToolsEl');
} }
@ -195,7 +200,7 @@ export default class CanvasModule {
* @returns {HTMLElement} * @returns {HTMLElement}
* @private * @private
*/ */
getHighlighter(compView) { getHighlighter(compView: any) {
return this._getLocalEl(this.canvasView.hlEl, compView, 'getHighlighter'); return this._getLocalEl(this.canvasView.hlEl, compView, 'getHighlighter');
} }
@ -204,7 +209,7 @@ export default class CanvasModule {
* @returns {HTMLElement} * @returns {HTMLElement}
* @private * @private
*/ */
getBadgeEl(compView) { getBadgeEl(compView: any) {
return this._getLocalEl(this.canvasView.badgeEl, compView, 'getBadgeEl'); return this._getLocalEl(this.canvasView.badgeEl, compView, 'getBadgeEl');
} }
@ -249,7 +254,7 @@ export default class CanvasModule {
* @returns {HTMLElement} * @returns {HTMLElement}
* @private * @private
*/ */
getOffsetViewerEl(compView) { getOffsetViewerEl(compView: any) {
return this._getLocalEl(this.canvasView.offsetEl, compView, 'getOffsetViewerEl'); return this._getLocalEl(this.canvasView.offsetEl, compView, 'getOffsetViewerEl');
} }
@ -264,10 +269,7 @@ export default class CanvasModule {
render() { render() {
this.canvasView?.remove(); this.canvasView?.remove();
this.canvasView = new CanvasView({ this._canvasView = new CanvasView({model: this.canvas, config: this.c});
model: this.canvas,
config: this.c,
});
return this.canvasView.render().el; return this.canvasView.render().el;
} }
@ -291,8 +293,8 @@ export default class CanvasModule {
* @returns {Object} * @returns {Object}
* @private * @private
*/ */
offset(el) { offset(el: HTMLElement) {
return this.canvasView.offset(el); return this.canvasView?.offset(el);
} }
/** /**
@ -303,7 +305,7 @@ export default class CanvasModule {
* return component.getName(); * return component.getName();
* }); * });
*/ */
setCustomBadgeLabel(f) { setCustomBadgeLabel(f: Function) {
this.c.customBadgeLabel = f; this.c.customBadgeLabel = f;
} }
@ -313,7 +315,7 @@ export default class CanvasModule {
* @returns {Object} * @returns {Object}
* @private * @private
*/ */
getElementPos(el, opts) { getElementPos(el: HTMLElement, opts?: any) {
return this.canvasView.getElementPos(el, opts); return this.canvasView.getElementPos(el, opts);
} }
@ -323,7 +325,7 @@ export default class CanvasModule {
* @returns {Object} * @returns {Object}
* @private * @private
*/ */
getElementOffsets(el) { getElementOffsets(el: HTMLElement) {
return this.canvasView.getElementOffsets(el); return this.canvasView.getElementOffsets(el);
} }
@ -356,7 +358,7 @@ export default class CanvasModule {
* @return {Object} * @return {Object}
* @private * @private
*/ */
getTargetToElementDim(target, element, options = {}) { getTargetToElementDim(target: HTMLElement, element: HTMLElement, options: any = {}) {
var opts = options || {}; var opts = options || {};
var canvasPos = this.canvasView.getPosition(); var canvasPos = this.canvasView.getPosition();
if (!canvasPos) return; if (!canvasPos) return;
@ -391,20 +393,20 @@ export default class CanvasModule {
}; };
// In this way I can catch data and also change the position strategy // In this way I can catch data and also change the position strategy
if (eventToTrigger && this.c.em) { if (eventToTrigger && this.em) {
this.c.em.trigger(eventToTrigger, result); this.em.trigger(eventToTrigger, result);
} }
return result; return result;
} }
canvasRectOffset(el, pos, opts = {}) { canvasRectOffset(el: HTMLElement, pos: {top: number, left: number}, opts: any = {}) {
const getFrameElFromDoc = doc => { const getFrameElFromDoc = (doc: Document) => {
const { defaultView } = doc; const { defaultView } = doc;
return defaultView && defaultView.frameElement; return defaultView?.frameElement as HTMLElement;
}; };
const rectOff = (el, top = 1, pos) => { const rectOff = (el: HTMLElement, top = 1, pos: {top: number, left: number}) => {
const zoom = this.em.getZoomDecimal(); const zoom = this.em.getZoomDecimal();
const side = top ? 'top' : 'left'; const side = top ? 'top' : 'left';
const doc = el.ownerDocument; const doc = el.ownerDocument;
@ -426,7 +428,7 @@ export default class CanvasModule {
}; };
} }
getTargetToElementFixed(el, elToMove, opts = {}) { getTargetToElementFixed(el: any, elToMove: any, opts: any = {}) {
const pos = opts.pos || this.getElementPos(el); const pos = opts.pos || this.getElementPos(el);
const cvOff = opts.canvasOff || this.canvasRectOffset(el, pos); const cvOff = opts.canvasOff || this.canvasRectOffset(el, pos);
const toolbarH = elToMove.offsetHeight || 0; const toolbarH = elToMove.offsetHeight || 0;
@ -477,8 +479,7 @@ export default class CanvasModule {
* @return {Object} * @return {Object}
* @private * @private
*/ */
getMouseRelativePos(e, options) { getMouseRelativePos(e: any, opts: any = {}) {
var opts = options || {};
var addTop = 0; var addTop = 0;
var addLeft = 0; var addLeft = 0;
var subWinOffset = opts.subWinOffset; var subWinOffset = opts.subWinOffset;
@ -506,9 +507,9 @@ export default class CanvasModule {
* @return {Object} * @return {Object}
* @private * @private
*/ */
getMouseRelativeCanvas(ev, opts) { getMouseRelativeCanvas(ev: MouseEvent, opts: any) {
const zoom = this.getZoomDecimal(); const zoom = this.getZoomDecimal();
const { top, left } = this.canvasView.getPosition(opts); const { top, left } = this.getCanvasView().getPosition(opts);
return { return {
y: ev.clientY * zoom + top, y: ev.clientY * zoom + top,
@ -532,7 +533,8 @@ export default class CanvasModule {
isInputFocused() { isInputFocused() {
const doc = this.getDocument(); const doc = this.getDocument();
const frame = this.getFrameEl(); const frame = this.getFrameEl();
const toIgnore = ['body', ...this.getConfig().notTextable]; //console.log(this.config)
const toIgnore = ['body', ...this.config.notTextable];
const docActive = frame && document.activeElement === frame; const docActive = frame && document.activeElement === frame;
const focused = docActive ? doc && doc.activeElement : document.activeElement; const focused = docActive ? doc && doc.activeElement : document.activeElement;
@ -554,7 +556,7 @@ export default class CanvasModule {
* // Force the scroll, even if the element is alredy visible * // Force the scroll, even if the element is alredy visible
* canvas.scrollTo(selected, { force: true }); * canvas.scrollTo(selected, { force: true });
*/ */
scrollTo(el, opts = {}) { scrollTo(el: any, opts = {}) {
const elem = getElement(el); const elem = getElement(el);
const view = elem && getViewEl(elem); const view = elem && getViewEl(elem);
view && view.scrollIntoView(opts); view && view.scrollIntoView(opts);
@ -564,7 +566,7 @@ export default class CanvasModule {
* Start autoscroll * Start autoscroll
* @private * @private
*/ */
startAutoscroll(frame) { startAutoscroll(frame: Frame) {
const fr = (frame && frame.view) || this.em.getCurrentFrame(); const fr = (frame && frame.view) || this.em.getCurrentFrame();
fr && fr.startAutoscroll(); fr && fr.startAutoscroll();
} }
@ -573,7 +575,7 @@ export default class CanvasModule {
* Stop autoscroll * Stop autoscroll
* @private * @private
*/ */
stopAutoscroll(frame) { stopAutoscroll(frame: Frame) {
const fr = (frame && frame.view) || this.em.getCurrentFrame(); const fr = (frame && frame.view) || this.em.getCurrentFrame();
fr && fr.stopAutoscroll(); fr && fr.stopAutoscroll();
} }
@ -585,7 +587,7 @@ export default class CanvasModule {
* @example * @example
* canvas.setZoom(50); // set zoom to 50% * canvas.setZoom(50); // set zoom to 50%
*/ */
setZoom(value) { setZoom(value: string) {
this.canvas.set('zoom', parseFloat(value)); this.canvas.set('zoom', parseFloat(value));
return this; return this;
} }
@ -609,7 +611,7 @@ export default class CanvasModule {
* @example * @example
* canvas.setCoords(100, 100); * canvas.setCoords(100, 100);
*/ */
setCoords(x, y) { setCoords(x: string, y: string) {
this.canvas.set({ x: parseFloat(x), y: parseFloat(y) }); this.canvas.set({ x: parseFloat(x), y: parseFloat(y) });
return this; return this;
} }
@ -622,7 +624,7 @@ export default class CanvasModule {
* const coords = canvas.getCoords(); * const coords = canvas.getCoords();
* // { x: 100, y: 100 } * // { x: 100, y: 100 }
*/ */
getCoords() { getCoords(): {x: number, y: number} {
const { x, y } = this.canvas.attributes; const { x, y } = this.canvas.attributes;
return { x, y }; return { x, y };
} }
@ -636,13 +638,13 @@ export default class CanvasModule {
return zoom ? 1 / zoom : 1; return zoom ? 1 / zoom : 1;
} }
toggleFramesEvents(on) { toggleFramesEvents(on: boolean) {
const { style } = this.getFramesEl(); const { style } = this.getFramesEl();
style.pointerEvents = on ? '' : 'none'; style.pointerEvents = on ? '' : 'none';
} }
getFrames() { getFrames() {
return this.canvas.get('frames').map(item => item); return this.canvas.frames.map(item => item);
} }
/** /**
@ -675,6 +677,7 @@ export default class CanvasModule {
this.canvas.stopListening(); this.canvas.stopListening();
this.canvasView?.remove(); this.canvasView?.remove();
[this.c, this.canvas, this.canvasView].forEach(i => (i = {})); [this.c, this.canvas, this.canvasView].forEach(i => (i = {}));
['em', 'model', 'droppable'].forEach(i => (this[i] = {})); //@ts-ignore
['model', 'droppable'].forEach(i => (this[i] = {}));
} }
} }

6
src/canvas/model/Canvas.ts

@ -23,9 +23,9 @@ export default class Canvas extends Backbone.Model {
em: EditorModel; em: EditorModel;
config: any; config: any;
constructor(props: any, config: any = {}) { constructor(em: EditorModel, config: any = {}) {
super(props); const { scripts, styles } = config;
const { em } = config; super({scripts, styles});
this.config = config; this.config = config;
this.em = em; this.em = em;
this.listenTo(this, 'change:zoom', this.onZoomChange); this.listenTo(this, 'change:zoom', this.onZoomChange);

36
src/canvas/view/CanvasView.js

@ -21,11 +21,12 @@ export default class CanvasView extends View {
`; `;
} }
initialize(o) { constructor(o) {
super(o);
bindAll(this, 'clearOff', 'onKeyPress', 'onCanvasMove'); bindAll(this, 'clearOff', 'onKeyPress', 'onCanvasMove');
const { model } = this; const { model } = this;
this.config = o.config || {}; this.config = o.config || {};
this.em = this.config.em || {}; this.em = this.model.em || {};
this.pfx = this.config.stylePrefix || ''; this.pfx = this.config.stylePrefix || '';
this.ppfx = this.config.pStylePrefix || ''; this.ppfx = this.config.pStylePrefix || '';
this.className = this.config.stylePrefix + 'canvas'; this.className = this.config.stylePrefix + 'canvas';
@ -152,7 +153,7 @@ export default class CanvasView extends View {
/** /**
* Get the offset of the element * Get the offset of the element
* @param {HTMLElement} el * @param {HTMLElement} el
* @return {Object} * @return { {top: number, left: number, width: number, height: number} }
*/ */
offset(el, opts = {}) { offset(el, opts = {}) {
const rect = getElRect(el); const rect = getElRect(el);
@ -178,8 +179,8 @@ export default class CanvasView extends View {
/** /**
* Return frame offset * Return frame offset
* @return {Object} * @return { {top: number, left: number, width: number, height: number} }
* @private * @public
*/ */
getFrameOffset(el) { getFrameOffset(el) {
if (!this.frmOff || el) { if (!this.frmOff || el) {
@ -193,8 +194,8 @@ export default class CanvasView extends View {
/** /**
* Return canvas offset * Return canvas offset
* @return {Object} * @return { {top: number, left: number, width: number, height: number} }
* @private * @public
*/ */
getCanvasOffset() { getCanvasOffset() {
if (!this.cvsOff) this.cvsOff = this.offset(this.el); if (!this.cvsOff) this.cvsOff = this.offset(this.el);
@ -204,10 +205,10 @@ export default class CanvasView extends View {
/** /**
* Returns element's rect info * Returns element's rect info
* @param {HTMLElement} el * @param {HTMLElement} el
* @return {Object} * @return { {top: number, left: number, width: number, height: number, zoom: number, rect: any} }
* @private * @public
*/ */
getElementPos(el, opts) { getElementPos(el, opts = {}) {
const zoom = this.getZoom(); const zoom = this.getZoom();
const opt = opts || {}; const opt = opts || {};
const frameOffset = this.getFrameOffset(el); const frameOffset = this.getFrameOffset(el);
@ -228,8 +229,15 @@ export default class CanvasView extends View {
/** /**
* Returns element's offsets like margins and paddings * Returns element's offsets like margins and paddings
* @param {HTMLElement} el * @param {HTMLElement} el
* @return {Object} * @return {{ marginTop: number,
* @private * marginRight: number,
* marginBottom: number,
* marginLeft: number,
* paddingTop: number,
* paddingRight: number,
* paddingBottom: number,
* paddingLeft: number,}}
* @public
*/ */
getElementOffsets(el) { getElementOffsets(el) {
if (!el || isTextNode(el)) return {}; if (!el || isTextNode(el)) return {};
@ -253,8 +261,8 @@ export default class CanvasView extends View {
/** /**
* Returns position data of the canvas element * Returns position data of the canvas element
* @return {Object} obj Position object * @return { {top: number, left: number, width: number, height: number} } obj Position object
* @private * @public
*/ */
getPosition(opts = {}) { getPosition(opts = {}) {
const doc = this.frame.el.contentDocument; const doc = this.frame.el.contentDocument;

7
src/canvas/view/FrameView.js

@ -25,7 +25,7 @@ export default class FrameView extends View {
frameView: this, frameView: this,
}; };
this.ppfx = this.config.pStylePrefix || ''; this.ppfx = this.config.pStylePrefix || '';
this.em = this.config.em; this.em = this.model.em;
this.showGlobalTools = debounce(this.showGlobalTools.bind(this), 50); this.showGlobalTools = debounce(this.showGlobalTools.bind(this), 50);
const cvModel = this.getCanvasModel(); const cvModel = this.getCanvasModel();
this.listenTo(model, 'change:head', this.updateHead); this.listenTo(model, 'change:head', this.updateHead);
@ -311,12 +311,11 @@ export default class FrameView extends View {
} }
renderBody() { renderBody() {
const { config, model, ppfx } = this; const { config, em, model, ppfx } = this;
const { em } = config;
const doc = this.getDoc(); const doc = this.getDoc();
const body = this.getBody(); const body = this.getBody();
const win = this.getWindow(); const win = this.getWindow();
const conf = em.get('Config'); const conf = em.config;
win._isEditor = true; win._isEditor = true;
this.renderStyles({ prev: [] }); this.renderStyles({ prev: [] });

6
src/canvas/view/FrameWrapView.js

@ -19,11 +19,11 @@ export default class FrameWrapView extends View {
...(opts.config || conf), ...(opts.config || conf),
frameWrapView: this, frameWrapView: this,
}; };
const { canvasView, em } = config; const { canvasView } = config;
this.cv = canvasView; this.cv = canvasView;
this.config = config; this.config = config;
this.em = em; this.em = this.model.em;
this.canvas = em && em.get('Canvas'); this.canvas = this.em?.get('Canvas');
this.ppfx = config.pStylePrefix || ''; this.ppfx = config.pStylePrefix || '';
this.frame = new FrameView({ model, config }); this.frame = new FrameView({ model, config });
this.classAnim = `${this.ppfx}frame-wrapper--anim`; this.classAnim = `${this.ppfx}frame-wrapper--anim`;

4
src/canvas/view/FramesView.js

@ -12,8 +12,8 @@ export default class FramesView extends DomainViews {
} }
onRender() { onRender() {
const { config, $el } = this; const { $el } = this;
const { em } = config; const { em } = this.collection.first;
em && $el.attr({ class: `${em.getConfig().stylePrefix}frames` }); em && $el.attr({ class: `${em.getConfig().stylePrefix}frames` });
} }
} }

Loading…
Cancel
Save