From dd8fd1d0a0bd85c8339ad5a8fd407fb4f61a30db Mon Sep 17 00:00:00 2001 From: Alex Ritter Date: Sat, 30 Apr 2022 15:24:43 +0200 Subject: [PATCH 01/15] Convert CanvasModule to ts --- src/abstract/Module.ts | 10 +-- src/canvas/{index.js => index.ts} | 127 +++++++++++++++--------------- src/canvas/model/Canvas.ts | 6 +- src/canvas/view/CanvasView.js | 36 +++++---- src/canvas/view/FrameView.js | 7 +- src/canvas/view/FrameWrapView.js | 6 +- src/canvas/view/FramesView.js | 4 +- 7 files changed, 102 insertions(+), 94 deletions(-) rename src/canvas/{index.js => index.ts} (85%) diff --git a/src/abstract/Module.ts b/src/abstract/Module.ts index 5e1a5f074..113fb2ae7 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,20 +40,18 @@ export default abstract class Module cls: any[] = []; events: any; - constructor(em: EditorModel, moduleName: string) { + constructor(em: EditorModel, moduleName: string, defaults?: T) { 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 = cfg; + this._config = {...defaults, ...cfg}; } public get em() { diff --git a/src/canvas/index.js b/src/canvas/index.ts similarity index 85% rename from src/canvas/index.js rename to src/canvas/index.ts index f71e56f55..f3e443293 100644 --- a/src/canvas/index.js +++ b/src/canvas/index.ts @@ -47,49 +47,58 @@ * @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 { +export default class CanvasModule extends Module { /** * Used inside RTE * @private */ - getCanvasView() { - return this.canvasView; + getCanvasView(): CanvasView { + return this.canvasView as any; } - name = 'Canvas'; + //name = 'Canvas'; - c = {}; - canvas; - canvasView; + c: any; + //em: EditorModel; + 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 * @param {Object} config Configurations * @private */ - init(config = {}) { + constructor(em: EditorModel) { + super(em, "Canvas", defaults) this.c = { - ...defaults, - ...config, + ...this.config, module: 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.canvas = new Canvas(this.em, this.config); this.model = this.canvas; this.startAutoscroll = this.startAutoscroll.bind(this); this.stopAutoscroll = this.stopAutoscroll.bind(this); return this; } + init(){ + + } onLoad() { this.model.init(); @@ -117,7 +126,7 @@ export default class CanvasModule { return this.canvasView.el; } - getFrame(index) { + getFrame(index?: number) { return this.getFrames()[index || 0]; } @@ -125,13 +134,13 @@ export default class CanvasModule { * Get the main frame element of the canvas * @returns {HTMLIFrameElement} */ - getFrameEl() { + getFrameEl(): HTMLIFrameElement { const { frame } = this.canvasView || {}; return frame && frame.el; } getFramesEl() { - return this.canvasView.framesArea; + return this.canvasView?.framesArea as HTMLElement; } /** @@ -148,7 +157,7 @@ export default class CanvasModule { */ getDocument() { 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; } - _getCompFrame(compView) { - return compView && compView._getFrame(); - } - - _getLocalEl(globalEl, compView, method) { + _getLocalEl(globalEl: any, compView: any, method: keyof FrameView) { let result = globalEl; - const frameView = this._getCompFrame(compView); + const frameView = compView?._getFrame(); result = frameView ? frameView[method]() : result; return result; @@ -178,7 +183,7 @@ export default class CanvasModule { * @private */ getGlobalToolsEl() { - return this.canvasView.toolsGlobEl; + return this.canvasView?.toolsGlobEl; } /** @@ -186,7 +191,7 @@ export default class CanvasModule { * @returns {HTMLElement} * @private */ - getToolsEl(compView) { + getToolsEl(compView: any) { return this._getLocalEl(this.canvasView.toolsEl, compView, 'getToolsEl'); } @@ -195,7 +200,7 @@ export default class CanvasModule { * @returns {HTMLElement} * @private */ - getHighlighter(compView) { + getHighlighter(compView: any) { return this._getLocalEl(this.canvasView.hlEl, compView, 'getHighlighter'); } @@ -204,7 +209,7 @@ export default class CanvasModule { * @returns {HTMLElement} * @private */ - getBadgeEl(compView) { + getBadgeEl(compView: any) { return this._getLocalEl(this.canvasView.badgeEl, compView, 'getBadgeEl'); } @@ -249,7 +254,7 @@ export default class CanvasModule { * @returns {HTMLElement} * @private */ - getOffsetViewerEl(compView) { + getOffsetViewerEl(compView: any) { return this._getLocalEl(this.canvasView.offsetEl, compView, 'getOffsetViewerEl'); } @@ -264,10 +269,7 @@ export default class CanvasModule { render() { this.canvasView?.remove(); - this.canvasView = new CanvasView({ - model: this.canvas, - config: this.c, - }); + this._canvasView = new CanvasView({model: this.canvas, config: this.c}); return this.canvasView.render().el; } @@ -291,8 +293,8 @@ export default class CanvasModule { * @returns {Object} * @private */ - offset(el) { - return this.canvasView.offset(el); + offset(el: HTMLElement) { + return this.canvasView?.offset(el); } /** @@ -303,7 +305,7 @@ export default class CanvasModule { * return component.getName(); * }); */ - setCustomBadgeLabel(f) { + setCustomBadgeLabel(f: Function) { this.c.customBadgeLabel = f; } @@ -313,7 +315,7 @@ export default class CanvasModule { * @returns {Object} * @private */ - getElementPos(el, opts) { + getElementPos(el: HTMLElement, opts?: any) { return this.canvasView.getElementPos(el, opts); } @@ -323,7 +325,7 @@ export default class CanvasModule { * @returns {Object} * @private */ - getElementOffsets(el) { + getElementOffsets(el: HTMLElement) { return this.canvasView.getElementOffsets(el); } @@ -356,7 +358,7 @@ export default class CanvasModule { * @return {Object} * @private */ - getTargetToElementDim(target, element, options = {}) { + getTargetToElementDim(target: HTMLElement, element: HTMLElement, options: any = {}) { var opts = options || {}; var canvasPos = this.canvasView.getPosition(); if (!canvasPos) return; @@ -391,20 +393,20 @@ export default class CanvasModule { }; // In this way I can catch data and also change the position strategy - if (eventToTrigger && this.c.em) { - this.c.em.trigger(eventToTrigger, result); + if (eventToTrigger && this.em) { + this.em.trigger(eventToTrigger, result); } return result; } - canvasRectOffset(el, pos, opts = {}) { - const getFrameElFromDoc = doc => { + canvasRectOffset(el: HTMLElement, pos: {top: number, left: number}, opts: any = {}) { + const getFrameElFromDoc = (doc: Document) => { 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 side = top ? 'top' : 'left'; 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 cvOff = opts.canvasOff || this.canvasRectOffset(el, pos); const toolbarH = elToMove.offsetHeight || 0; @@ -477,8 +479,7 @@ export default class CanvasModule { * @return {Object} * @private */ - getMouseRelativePos(e, options) { - var opts = options || {}; + getMouseRelativePos(e: any, opts: any = {}) { var addTop = 0; var addLeft = 0; var subWinOffset = opts.subWinOffset; @@ -506,9 +507,9 @@ export default class CanvasModule { * @return {Object} * @private */ - getMouseRelativeCanvas(ev, opts) { + getMouseRelativeCanvas(ev: MouseEvent, opts: any) { const zoom = this.getZoomDecimal(); - const { top, left } = this.canvasView.getPosition(opts); + const { top, left } = this.getCanvasView().getPosition(opts); return { y: ev.clientY * zoom + top, @@ -532,7 +533,8 @@ export default class CanvasModule { isInputFocused() { const doc = this.getDocument(); 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 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 * canvas.scrollTo(selected, { force: true }); */ - scrollTo(el, opts = {}) { + scrollTo(el: any, opts = {}) { const elem = getElement(el); const view = elem && getViewEl(elem); view && view.scrollIntoView(opts); @@ -564,7 +566,7 @@ export default class CanvasModule { * Start autoscroll * @private */ - startAutoscroll(frame) { + startAutoscroll(frame: Frame) { const fr = (frame && frame.view) || this.em.getCurrentFrame(); fr && fr.startAutoscroll(); } @@ -573,7 +575,7 @@ export default class CanvasModule { * Stop autoscroll * @private */ - stopAutoscroll(frame) { + stopAutoscroll(frame: Frame) { const fr = (frame && frame.view) || this.em.getCurrentFrame(); fr && fr.stopAutoscroll(); } @@ -585,7 +587,7 @@ export default class CanvasModule { * @example * canvas.setZoom(50); // set zoom to 50% */ - setZoom(value) { + setZoom(value: string) { this.canvas.set('zoom', parseFloat(value)); return this; } @@ -609,7 +611,7 @@ export default class CanvasModule { * @example * canvas.setCoords(100, 100); */ - setCoords(x, y) { + setCoords(x: string, y: string) { this.canvas.set({ x: parseFloat(x), y: parseFloat(y) }); return this; } @@ -622,7 +624,7 @@ export default class CanvasModule { * const coords = canvas.getCoords(); * // { x: 100, y: 100 } */ - getCoords() { + getCoords(): {x: number, y: number} { const { x, y } = this.canvas.attributes; return { x, y }; } @@ -636,13 +638,13 @@ export default class CanvasModule { return zoom ? 1 / zoom : 1; } - toggleFramesEvents(on) { + toggleFramesEvents(on: boolean) { const { style } = this.getFramesEl(); style.pointerEvents = on ? '' : 'none'; } 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.canvasView?.remove(); [this.c, this.canvas, this.canvasView].forEach(i => (i = {})); - ['em', 'model', 'droppable'].forEach(i => (this[i] = {})); + //@ts-ignore + ['model', 'droppable'].forEach(i => (this[i] = {})); } } diff --git a/src/canvas/model/Canvas.ts b/src/canvas/model/Canvas.ts index 6bd976a57..ec53cdce0 100644 --- a/src/canvas/model/Canvas.ts +++ b/src/canvas/model/Canvas.ts @@ -23,9 +23,9 @@ export default class Canvas extends Backbone.Model { em: EditorModel; config: any; - constructor(props: any, config: any = {}) { - super(props); - const { em } = config; + constructor(em: EditorModel, config: any = {}) { + const { scripts, styles } = config; + super({scripts, styles}); this.config = config; this.em = em; this.listenTo(this, 'change:zoom', this.onZoomChange); diff --git a/src/canvas/view/CanvasView.js b/src/canvas/view/CanvasView.js index 6d8051ca8..0fe6aa4d7 100644 --- a/src/canvas/view/CanvasView.js +++ b/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'); const { model } = this; this.config = o.config || {}; - this.em = this.config.em || {}; + this.em = this.model.em || {}; this.pfx = this.config.stylePrefix || ''; this.ppfx = this.config.pStylePrefix || ''; this.className = this.config.stylePrefix + 'canvas'; @@ -152,7 +153,7 @@ export default class CanvasView extends View { /** * Get the offset of the element * @param {HTMLElement} el - * @return {Object} + * @return { {top: number, left: number, width: number, height: number} } */ offset(el, opts = {}) { const rect = getElRect(el); @@ -178,8 +179,8 @@ export default class CanvasView extends View { /** * Return frame offset - * @return {Object} - * @private + * @return { {top: number, left: number, width: number, height: number} } + * @public */ getFrameOffset(el) { if (!this.frmOff || el) { @@ -193,8 +194,8 @@ export default class CanvasView extends View { /** * Return canvas offset - * @return {Object} - * @private + * @return { {top: number, left: number, width: number, height: number} } + * @public */ getCanvasOffset() { if (!this.cvsOff) this.cvsOff = this.offset(this.el); @@ -204,10 +205,10 @@ export default class CanvasView extends View { /** * Returns element's rect info * @param {HTMLElement} el - * @return {Object} - * @private + * @return { {top: number, left: number, width: number, height: number, zoom: number, rect: any} } + * @public */ - getElementPos(el, opts) { + getElementPos(el, opts = {}) { const zoom = this.getZoom(); const opt = opts || {}; const frameOffset = this.getFrameOffset(el); @@ -228,8 +229,15 @@ export default class CanvasView extends View { /** * Returns element's offsets like margins and paddings * @param {HTMLElement} el - * @return {Object} - * @private + * @return {{ marginTop: number, + * marginRight: number, + * marginBottom: number, + * marginLeft: number, + * paddingTop: number, + * paddingRight: number, + * paddingBottom: number, + * paddingLeft: number,}} + * @public */ getElementOffsets(el) { if (!el || isTextNode(el)) return {}; @@ -253,8 +261,8 @@ export default class CanvasView extends View { /** * Returns position data of the canvas element - * @return {Object} obj Position object - * @private + * @return { {top: number, left: number, width: number, height: number} } obj Position object + * @public */ getPosition(opts = {}) { const doc = this.frame.el.contentDocument; diff --git a/src/canvas/view/FrameView.js b/src/canvas/view/FrameView.js index dff267953..0fd2d08b8 100644 --- a/src/canvas/view/FrameView.js +++ b/src/canvas/view/FrameView.js @@ -25,7 +25,7 @@ export default class FrameView extends View { frameView: this, }; this.ppfx = this.config.pStylePrefix || ''; - this.em = this.config.em; + this.em = this.model.em; this.showGlobalTools = debounce(this.showGlobalTools.bind(this), 50); const cvModel = this.getCanvasModel(); this.listenTo(model, 'change:head', this.updateHead); @@ -311,12 +311,11 @@ export default class FrameView extends View { } renderBody() { - const { config, model, ppfx } = this; - const { em } = config; + const { config, em, model, ppfx } = this; const doc = this.getDoc(); const body = this.getBody(); const win = this.getWindow(); - const conf = em.get('Config'); + const conf = em.config; win._isEditor = true; this.renderStyles({ prev: [] }); diff --git a/src/canvas/view/FrameWrapView.js b/src/canvas/view/FrameWrapView.js index af03496a6..0bf752f8b 100644 --- a/src/canvas/view/FrameWrapView.js +++ b/src/canvas/view/FrameWrapView.js @@ -19,11 +19,11 @@ export default class FrameWrapView extends View { ...(opts.config || conf), frameWrapView: this, }; - const { canvasView, em } = config; + const { canvasView } = config; this.cv = canvasView; this.config = config; - this.em = em; - this.canvas = em && em.get('Canvas'); + this.em = this.model.em; + this.canvas = this.em?.get('Canvas'); this.ppfx = config.pStylePrefix || ''; this.frame = new FrameView({ model, config }); this.classAnim = `${this.ppfx}frame-wrapper--anim`; diff --git a/src/canvas/view/FramesView.js b/src/canvas/view/FramesView.js index 01ae1ef1b..481367399 100644 --- a/src/canvas/view/FramesView.js +++ b/src/canvas/view/FramesView.js @@ -12,8 +12,8 @@ export default class FramesView extends DomainViews { } onRender() { - const { config, $el } = this; - const { em } = config; + const { $el } = this; + const { em } = this.collection.first; em && $el.attr({ class: `${em.getConfig().stylePrefix}frames` }); } } From fda9c381140d79cb117af6f824c9c387e8414f4d Mon Sep 17 00:00:00 2001 From: Alex Ritter Date: Sat, 30 Apr 2022 15:52:26 +0200 Subject: [PATCH 02/15] Use abstract Model in Canvas --- src/abstract/Model.ts | 4 ++++ src/canvas/index.ts | 2 +- src/canvas/model/Canvas.ts | 27 ++++++++++++--------------- src/editor/index.ts | 19 ++++++++++--------- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/abstract/Model.ts b/src/abstract/Model.ts index 6a1bc3194..cc7b498ad 100644 --- a/src/abstract/Model.ts +++ b/src/abstract/Model.ts @@ -29,4 +29,8 @@ export default class Model< protected get em() { return this._module.em; } + + public get em() { + return this._module.em; + } } diff --git a/src/canvas/index.ts b/src/canvas/index.ts index f3e443293..22f087e41 100644 --- a/src/canvas/index.ts +++ b/src/canvas/index.ts @@ -90,7 +90,7 @@ export default class CanvasModule extends Module { ...this.config, module: this, }; - this.canvas = new Canvas(this.em, this.config); + this.canvas = new Canvas(this); this.model = this.canvas; this.startAutoscroll = this.startAutoscroll.bind(this); this.stopAutoscroll = this.stopAutoscroll.bind(this); diff --git a/src/canvas/model/Canvas.ts b/src/canvas/model/Canvas.ts index ec53cdce0..31b84b7df 100644 --- a/src/canvas/model/Canvas.ts +++ b/src/canvas/model/Canvas.ts @@ -1,11 +1,10 @@ -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'; +import { Model } from "../../abstract"; +import { evPageSelect } from "../../pages"; +import Frames from "./Frames"; +import Page from "../../pages/model/Page"; +import CanvasModule from ".."; -export default class Canvas extends Backbone.Model { +export default class Canvas extends Model { defaults() { return { frame: '', @@ -20,18 +19,16 @@ export default class Canvas extends Backbone.Model { styles: [], }; } - em: EditorModel; - config: any; - constructor(em: EditorModel, config: any = {}) { + constructor(module: CanvasModule) { + const { em, config } = module; const { scripts, styles } = config; - super({scripts, styles}); - this.config = config; - this.em = em; - this.listenTo(this, 'change:zoom', this.onZoomChange); - this.listenTo(em, 'change:device', this.updateDevice); + super(module, {scripts, styles}); + 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/editor/index.ts b/src/editor/index.ts index 42dfd7627..c1ca114d3 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -54,14 +54,15 @@ * ## Methods * @module Editor */ -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'; +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"; export default class EditorModule implements IBaseModule { constructor(config = {}, opts: any = {}) { @@ -112,7 +113,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'); } From 49da963dc5209cae89dc4415de3019056da4791d Mon Sep 17 00:00:00 2001 From: Alex Ritter Date: Sat, 30 Apr 2022 19:13:47 +0200 Subject: [PATCH 03/15] Convert code to using class --- src/dom_components/model/Components.js | 26 ++++---- src/dom_components/view/ComponentView.js | 80 ++++++++++++------------ 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/dom_components/model/Components.js b/src/dom_components/model/Components.js index bbf039546..0ccb91565 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 Backbone.Collection.extend({ +export default class Components extends Backbone.Collection { initialize(models, opt = {}) { this.opt = opt; this.listenTo(this, 'add', this.onAdd); @@ -50,7 +50,7 @@ export default Backbone.Collection.extend({ 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 Backbone.Collection.extend({ 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 Backbone.Collection.extend({ 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 Backbone.Collection.extend({ em.stopListening(removed); em.stopListening(removed.get('classes')); removed.__postRemove(); - }, + } model(attrs, options) { const { opt } = options.collection; @@ -155,7 +155,7 @@ export default Backbone.Collection.extend({ } return new model(attrs, options); - }, + } parseString(value, opt = {}) { const { em, domc } = this; @@ -173,7 +173,7 @@ export default Backbone.Collection.extend({ } return parsed.html; - }, + } add(models, opt = {}) { opt.keepIds = [...(opt.keepIds || []), ...getComponentIds(opt.previousModels)]; @@ -197,7 +197,7 @@ export default Backbone.Collection.extend({ const result = Backbone.Collection.prototype.add.apply(this, [models, opt]); this.__firstAdd = result; return result; - }, + } /** * Process component definition. @@ -250,7 +250,7 @@ export default Backbone.Collection.extend({ } return model; - }, + } onAdd(model, c, opts = {}) { const { domc, em } = this; @@ -267,9 +267,9 @@ export default Backbone.Collection.extend({ 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 Backbone.Collection.extend({ // }); // }; // onAll(toCheck); - }), -}); + }); +} diff --git a/src/dom_components/view/ComponentView.js b/src/dom_components/view/ComponentView.js index 3c1e3d43e..db589d255 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 Backbone.View.extend({ +export default class ComponentView extends Backbone.View { className() { return this.getClasses(); - }, + } tagName() { return this.model.get('tagName'); - }, + } initialize(opt = {}) { const model = this.model; @@ -50,13 +50,13 @@ export default Backbone.View.extend({ }; 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 Backbone.View.extend({ 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 Backbone.View.extend({ $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 Backbone.View.extend({ target: this.model, event, }); - }, + } initClasses() { const { model } = this; @@ -125,7 +125,7 @@ export default Backbone.View.extend({ 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 Backbone.View.extend({ !opts.avoidRender && this.renderChildren(); this.listenTo(...toListen); } - }, + } /** * Handle any property change @@ -155,7 +155,7 @@ export default Backbone.View.extend({ for (let prop in model.changed) { model.emitUpdate(prop); } - }, + } /** * Import, if possible, classes inside main container @@ -169,7 +169,7 @@ export default Backbone.View.extend({ clm.add(m.get('name')); }); } - }, + } /** * Update item on status change @@ -212,7 +212,7 @@ export default Backbone.View.extend({ cls = cls.trim(); cls && el.setAttribute('class', cls); - }, + } /** * Update highlight attribute @@ -223,7 +223,7 @@ export default Backbone.View.extend({ 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 Backbone.View.extend({ } else { this.setAttribute('style', model.styleToString(opts)); } - }, + } /** * Update classe attribute @@ -251,7 +251,7 @@ export default Backbone.View.extend({ // Regenerate status class this.updateStatus(); this.onAttrUpdate(); - }, + } /** * Update single attribute @@ -261,7 +261,7 @@ export default Backbone.View.extend({ 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 Backbone.View.extend({ * */ getClasses() { return this.model.getClasses().join(' '); - }, + } /** * Update attributes @@ -304,7 +304,7 @@ export default Backbone.View.extend({ keys(attr).forEach(key => attr[key] === false && delete attr[key]); $el.attr(attr); - }, + } /** * Update component content @@ -314,7 +314,7 @@ export default Backbone.View.extend({ 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 Backbone.View.extend({ */ prevDef(e) { e.preventDefault(); - }, + } /** * Render component's script @@ -333,7 +333,7 @@ export default Backbone.View.extend({ 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 Backbone.View.extend({ } return container; - }, + } /** * This returns rect informations not affected by the canvas zoom. @@ -399,7 +399,7 @@ export default Backbone.View.extend({ assignRect(target); return rect; - }, + } isInViewport({ rect } = {}) { const { el } = this; @@ -415,7 +415,7 @@ export default Backbone.View.extend({ top <= frame.scrollBottom && left <= frameElement.offsetWidth + body.scrollLeft ); - }, + } scrollIntoView(opts = {}) { const rect = this.getOffsetRect(); @@ -435,7 +435,7 @@ export default Backbone.View.extend({ }); } } - }, + } /** * Recreate the element of the view @@ -447,18 +447,18 @@ export default Backbone.View.extend({ 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.frameView; - }, + } /** * Render children components @@ -482,14 +482,14 @@ export default Backbone.View.extend({ 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 Backbone.View.extend({ this.postRender(); return this; - }, + } postRender() { if (!this.modelOpt.temporary) { this.onRender(this._clbObj()); } - }, + } - onRender() {}, -}); + onRender() {} +} From a5a939a16a13a13363fa63b4e2db0d822fe4481c Mon Sep 17 00:00:00 2001 From: Alex Ritter Date: Sat, 30 Apr 2022 19:14:32 +0200 Subject: [PATCH 04/15] Convert CanvasView to ts --- src/abstract/View.ts | 19 +- .../view/{CanvasView.js => CanvasView.ts} | 187 ++++++++++-------- src/editor/model/Editor.ts | 4 +- src/utils/dom.js | 15 +- 4 files changed, 131 insertions(+), 94 deletions(-) rename src/canvas/view/{CanvasView.js => CanvasView.ts} (68%) diff --git a/src/abstract/View.ts b/src/abstract/View.ts index f1aaa9170..a52d6ee93 100644 --- a/src/abstract/View.ts +++ b/src/abstract/View.ts @@ -1,19 +1,28 @@ -import Backbone from 'backbone'; -import Model from './Model'; +import Backbone from "backbone"; +import Model from "./Model"; +import Module, { IBaseModule } from "./Module"; export default class View< TModel extends Model = Model, TElement extends Element = HTMLElement > extends Backbone.View { protected get pfx() { - return (this.model.module.em.config as any).stylePrefix || ''; + return (this.model.em.config as any).stylePrefix || ""; } protected get ppfx() { - return this.pfx + this.model.module.config.stylePrefix || ''; + return this.pfx + this.config.stylePrefix || ""; + } + + protected get module(): TModel extends Model? M: unknown { + return this.model.module as any; } protected get em() { - return this.model.module.em; + return this.model.em; + } + + protected get config(): TModel extends Model ? (M extends IBaseModule ? C : unknown) : unknown{ + return this.module.config as any } } diff --git a/src/canvas/view/CanvasView.js b/src/canvas/view/CanvasView.ts similarity index 68% rename from src/canvas/view/CanvasView.js rename to src/canvas/view/CanvasView.ts index 0fe6aa4d7..7994e0404 100644 --- a/src/canvas/view/CanvasView.js +++ b/src/canvas/view/CanvasView.ts @@ -1,12 +1,26 @@ import { bindAll } from 'underscore'; -import { View } from '../../common'; +import { View } from '../../abstract'; import { on, off, getElement, getKeyChar, isTextNode, getElRect, getUiClass } from '../../utils/mixins'; import { createEl } from '../../utils/dom'; import FramesView from './FramesView'; - -let timerZoom; - -export default class CanvasView extends View { +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'; + +interface MarginPaddingOffsets{ + marginTop?: number, + marginRight?: number, + marginBottom?: number, + marginLeft?: number, + paddingTop?: number, + paddingRight?: number, + paddingBottom?: number, + paddingLeft?: number, + } +export default class CanvasView extends View { events() { return { wheel: 'onWheel', @@ -20,23 +34,42 @@ export default class CanvasView extends View {
`; } - - constructor(o) { - super(o); + /*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}); bindAll(this, 'clearOff', 'onKeyPress', 'onCanvasMove'); - const { model } = this; - this.config = o.config || {}; - this.em = this.model.em || {}; - this.pfx = this.config.stylePrefix || ''; - this.ppfx = this.config.pStylePrefix || ''; - this.className = this.config.stylePrefix + 'canvas'; + this.className = this.pfx + '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(1); + this.toggleListeners(true); } _onFramesUpdate() { @@ -49,7 +82,7 @@ export default class CanvasView extends View { const collection = model.get('frames'); em.set('readyCanvas', 0); collection.once('loaded:all', () => em.set('readyCanvas', 1)); - frames && frames.remove(); + frames?.remove(); this.frames = new FramesView({ collection, config: { @@ -59,38 +92,40 @@ export default class CanvasView extends View { }); } - checkSelected(component, opts = {}) { + checkSelected(component: Component, opts: any = {}) { 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() { - this.frames.remove(); - this.frames = {}; - View.prototype.remove.apply(this, arguments); - this.toggleListeners(); + remove(...args: any) { + this.frames?.remove(); + //@ts-ignore + this.frames = undefined; + View.prototype.remove.apply(this, args); + this.toggleListeners(false); + return this } - preventDefault(ev) { + preventDefault(ev: Event) { if (ev) { ev.preventDefault(); - ev._parentEvent && ev._parentEvent.preventDefault(); + //@ts-ignore + ev._parentEvent?.preventDefault(); } } - onCanvasMove(ev) { + onCanvasMove(ev: Event) { // 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) { + toggleListeners(enable: boolean) { const { el } = this; const fn = enable ? on : off; fn(document, 'keypress', this.onKeyPress); @@ -98,7 +133,7 @@ export default class CanvasView extends View { // fn(el, 'mousemove dragover', this.onCanvasMove); } - onKeyPress(ev) { + onKeyPress(ev: Event) { const { em } = this; const key = getKeyChar(ev); @@ -108,28 +143,30 @@ export default class CanvasView extends View { } } - onWheel(ev) { + onWheel(ev: KeyboardEvent) { 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) { + updateFrames(ev: Event) { 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); - timerZoom && clearTimeout(timerZoom); - timerZoom = setTimeout(() => em.runDefault(defOpts), 300); + this.timerZoom && clearTimeout(this.timerZoom); + this.timerZoom = setTimeout(() => em.runDefault(defOpts), 300) as any; } getZoom() { @@ -141,7 +178,7 @@ export default class CanvasView extends View { * @param {HTMLElement} el * @return {Boolean} */ - isElInViewport(el) { + isElInViewport(el: HTMLElement) { const elem = getElement(el); const rect = getElRect(elem); const frameRect = this.getFrameOffset(elem); @@ -155,14 +192,14 @@ export default class CanvasView extends View { * @param {HTMLElement} el * @return { {top: number, left: number, width: number, height: number} } */ - offset(el, opts = {}) { + offset(el?: HTMLElement, opts: any = {}) { 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), - left: rect.left + (noScroll ? 0 : docBody.scrollLeft), + top: rect.top + (noScroll ? 0 : docBody?.scrollTop ?? 0), + left: rect.left + (noScroll ? 0 : docBody?.scrollLeft ?? 0), width: rect.width, height: rect.height, }; @@ -173,8 +210,8 @@ export default class CanvasView extends View { * @private */ clearOff() { - this.frmOff = null; - this.cvsOff = null; + this.frmOff = undefined; + this.cvsOff = undefined; } /** @@ -182,11 +219,11 @@ export default class CanvasView extends View { * @return { {top: number, left: number, width: number, height: number} } * @public */ - getFrameOffset(el) { + getFrameOffset(el?: HTMLElement) { if (!this.frmOff || el) { - const frame = this.frame.el; - const winEl = el && el.ownerDocument.defaultView; - const frEl = winEl ? winEl.frameElement : frame; + const frame = this.frame?.el; + const winEl = el?.ownerDocument.defaultView; + const frEl = winEl ? winEl.frameElement as HTMLElement : frame; this.frmOff = this.offset(frEl || frame); } return this.frmOff; @@ -208,7 +245,7 @@ export default class CanvasView extends View { * @return { {top: number, left: number, width: number, height: number, zoom: number, rect: any} } * @public */ - getElementPos(el, opts = {}) { + getElementPos(el: HTMLElement, opts: any = {}) { const zoom = this.getZoom(); const opt = opts || {}; const frameOffset = this.getFrameOffset(el); @@ -229,21 +266,14 @@ export default class CanvasView extends View { /** * Returns element's offsets like margins and paddings * @param {HTMLElement} el - * @return {{ marginTop: number, - * marginRight: number, - * marginBottom: number, - * marginLeft: number, - * paddingTop: number, - * paddingRight: number, - * paddingBottom: number, - * paddingLeft: number,}} + * @return { MarginPaddingOffsets } * @public */ - getElementOffsets(el) { + getElementOffsets(el: HTMLElement) { if (!el || isTextNode(el)) return {}; - const result = {}; + const result: MarginPaddingOffsets = {} ; const styles = window.getComputedStyle(el); - [ + const marginPaddingOffsets: (keyof MarginPaddingOffsets)[] =[ 'marginTop', 'marginRight', 'marginBottom', @@ -252,7 +282,8 @@ export default class CanvasView extends View { 'paddingRight', 'paddingBottom', 'paddingLeft', - ].forEach(offset => { + ] + marginPaddingOffsets.forEach(offset => { result[offset] = parseFloat(styles[offset]) * this.getZoom(); }); @@ -264,8 +295,9 @@ export default class CanvasView extends View { * @return { {top: number, left: number, width: number, height: number} } obj Position object * @public */ - getPosition(opts = {}) { - const doc = this.frame.el.contentDocument; + getPosition(opts: any = {}) { + + const doc = this.frame?.el.contentDocument; if (!doc) return; const bEl = doc.body; const zoom = this.getZoom(); @@ -286,7 +318,8 @@ export default class CanvasView extends View { * @param {View} view Component's View * @private */ - updateScript(view) { + //TODO change type after the ComponentView was updated to ts + updateScript(view: any) { const model = view.model; const id = model.getId(); @@ -321,25 +354,25 @@ export default class CanvasView extends View { * Get javascript container * @private */ - getJsContainer(view) { + getJsContainer(view?: ComponentView) { const frameView = this.getFrameView(view); return frameView && frameView.getJsContainer(); } - getFrameView(view) { - return (view && view._getFrame()) || this.em.get('currentFrame'); + getFrameView(view?: ComponentView) { + return view?._getFrame() || this.em.get('currentFrame'); } _renderFrames() { if (!this.ready) return; const { model, frames, em, framesArea } = this; - const frms = model.get('frames'); + const frms = model.frames; frms.listenToLoad(); frames.render(); const mainFrame = frms.at(0); - const currFrame = mainFrame && mainFrame.view; + const currFrame = mainFrame?.view; em.setCurrentFrame(currFrame); - framesArea && framesArea.appendChild(frames.el); + framesArea?.appendChild(frames.el); this.frame = currFrame; } @@ -368,18 +401,18 @@ export default class CanvasView extends View { `); const toolsEl = el.querySelector(`#${ppfx}tools`); - 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.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.el.className = getUiClass(em, this.className); - this.ready = 1; + this.ready = true; this._renderFrames(); return this; diff --git a/src/editor/model/Editor.ts b/src/editor/model/Editor.ts index 30008da67..4c192ea0c 100644 --- a/src/editor/model/Editor.ts +++ b/src/editor/model/Editor.ts @@ -822,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/utils/dom.js b/src/utils/dom.js index 01d718649..2e5b5f993 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -5,8 +5,7 @@ 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; @@ -18,14 +17,10 @@ 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 => { @@ -56,7 +51,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)); @@ -90,7 +85,7 @@ export const createCustomEvent = (e, cls) => { Object.defineProperty(oEvent, prop, { get() { return this.keyCodeVal; - } + }, }); }); } From d775f56e06b9ffff50931597191b75590ec08f29 Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Mon, 9 May 2022 09:29:40 -0400 Subject: [PATCH 05/15] Link to English Wikipedia Given that the README is in English, it makes sense to link to English Wikipedia instead of Italian. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 592fa389f..f6d86f30b 100644 --- a/README.md +++ b/README.md @@ -210,4 +210,4 @@ BSD 3-clause [Documentation]: [API-Reference]: -[CMS]: +[CMS]: From dbb19b0204b0e2a41785125b1fd85af3451386ae Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Mon, 9 May 2022 09:51:59 -0400 Subject: [PATCH 06/15] Small edits to getting-started.md Copy editing to fix typo and punctuation --- docs/getting-started.md | 46 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index f0f1af10c..c0555e60b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -8,11 +8,11 @@ meta: # Getting Started -This is a step-by-step guide for anyone who wants to create their own builder with GrapesJS. This is not a comprehensive guide, just a concise overview of most common modules. Follow along to create a page builder from scratch. Skip to the end of this page to see the [final result](#final-result) +This is a step-by-step guide for anyone who wants to create their own builder with GrapesJS. This is not a comprehensive guide, just a concise overview of most common modules. Follow along to create a page builder from scratch. Skip to the end of this page to see the [final result](#final-result). ## Import the library -Before you start using GrapesJS, you'll have to import it. Let's import the latest version +Before you start using GrapesJS, you'll have to import it. Let's import the latest version: ```html @@ -100,7 +100,7 @@ const editor = grapesjs.init({ -As you can see we add our blocks via the initial configuration. Obviously there might be a case in which you would like to add them dynamically, in this case you have to use the [Block Manager API](api/block_manager.html) +As you can see we add our blocks via the initial configuration. Obviously there might be a case in which you would like to add them dynamically, in this case you have to use the [Block Manager API](api/block_manager.html): ```js editor.BlockManager.add('my-block-id', { @@ -110,16 +110,16 @@ editor.BlockManager.add('my-block-id', { }) ``` ::: tip -If you want to learn more about blocks we suggest to read its dedicated article: [Block Manager Module](modules/Blocks.html) +If you want to learn more about blocks we suggest to read its dedicated article: [Block Manager Module](modules/Blocks.html). ::: ## Define Components Technically, once you drop your HTML block inside the canvas each element of the content is transformed into a GrapesJS Component. A GrapesJS Component is an object containing information about how the element is rendered in the canvas (managed in the View) and how it might look its final code (created by the properties in the Model). Generally, all Model properties are reflected in the View. Therefore, if you add a new attribute to the model, it will be available in the export code (which we will learn more about later), and the element you see in the canvas will be updated with new attributes. This isn't totally out of the ordinary, but the unique thing about Components that you can create a totally decoupled View. This means you can show the user whatever you desire regardless of what is in the Model. For example, by dragging a placeholder text you can fetch and show instead a dynamic content. If you want to learn more about Custom Components, you should check out [Component Manager Module](modules/Components.html). -GrapesJS comes with a few [built-in Components](modules/Components.html#built-in-component-types) that enable different features once rendered in the canvas. For example, by double clicking on an image component you will see the default [Asset Manager](modules/Assets.html), which you can customize or integrate you own. By double clicking on the text component you're able to edit it via the built-in Rich Text Editor, which is also customization and [replaceable](guides/Replace-Rich-Text-Editor.html). +GrapesJS comes with a few [built-in Components](modules/Components.html#built-in-component-types) that enable different features once rendered in the canvas. For example, by double clicking on an image component you will see the default [Asset Manager](modules/Assets.html), which you can customize or integrate you own. By double clicking on the text component you're able to edit it via the built-in Rich Text Editor, which is also customizable and [replaceable](guides/Replace-Rich-Text-Editor.html). -As we have seen before you can create Blocks directly as Components +As we have seen before you can create Blocks directly as Components: ```js editor.BlockManager.add('my-block-id', { // ... @@ -142,10 +142,10 @@ editor.BlockManager.add('my-block-id', { }) ``` ::: tip -Check out the [Components API](api/components.html) to learn how to interact with components dynamically +Check out the [Components API](api/components.html) to learn how to interact with components dynamically. ::: -An example on how to select some inner component and replace its children with new contents +An example of how to select some inner component and replace its children with new contents: ```js // The wrapper is the root Component @@ -239,12 +239,12 @@ editor.on('abort:export-template', () => console.log('Command aborted')); ``` ::: tip -Check out the [Panels API](api/panels.html) to see all the available methods +Check out the [Panels API](api/panels.html) to see all the available methods. ::: ## Layers -Another utility tool you might find useful when working with web elements is the layer manger. It's a tree overview of the structure nodes and enables you to manage it easier. To enable it you just have to specify where you want to render it +Another utility tool you might find useful when working with web elements is the layer manger. It's a tree overview of the structure nodes and enables you to manage it easier. To enable it you just have to specify where you want to render it. ```html{4,5,6,7,8,9,10,11}
@@ -296,7 +296,7 @@ const editor = grapesjs.init({ ## Style Manager Once you have defined the structure of the template the next step is the ability to style it. To meet this need GrapesJS includes the Style Manager module which is composed by CSS style properties and sectors. To make it more clear, let's see how to define a basic set. -Let's start by adding one more panel inside the `panel__right` and another one in `panel__top` which will contain a Layer/Style Manager switcher +Let's start by adding one more panel inside the `panel__right` and another one in `panel__top` which will contain a Layer/Style Manager switcher: ```html{3,8}
@@ -424,10 +424,10 @@ editor.Commands.add('show-styles', { -Inside Style Manager definition we use `buildProps` which helps us create common properties from [available built-in objects](modules/Style-manager.html#built-in-properties) then in `properties` we can override same objects (eg. passing another `name` to change the label) identified by `property` name. As you can see from `custom-prop` example it's a matter of defining the CSS `property` and the input `type`. We suggest to check a more complete example of Style Manager properties usage from the [webpage preset demo](https://github.com/artf/grapesjs/blob/gh-pages/demo.html#L1000) +Inside Style Manager definition we use `buildProps` which helps us create common properties from [available built-in objects](modules/Style-manager.html#built-in-properties) then in `properties` we can override same objects (eg. passing another `name` to change the label) identified by `property` name. As you can see from `custom-prop` example it's a matter of defining the CSS `property` and the input `type`. We suggest to check a more complete example of Style Manager properties usage from the [webpage preset demo](https://github.com/artf/grapesjs/blob/gh-pages/demo.html#L1000). ::: tip -Check the [Style Manager API](api/panels.html) to see how to update sectors and properties dynamically +Check the [Style Manager API](api/panels.html) to see how to update sectors and properties dynamically. :::