From 9c24108dadf2ded39e8805b6c4a5f00c626c468b Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 20 Feb 2020 09:37:55 +0100 Subject: [PATCH 1/5] Inital cleanup --- src/css_composer/model/CssRules.js | 21 ++--- src/dom_components/model/Components.js | 55 ++++++------ src/dom_components/view/ComponentView.js | 21 +++-- src/dom_components/view/ComponentsView.js | 22 +++-- src/navigator/view/ItemsView.js | 3 +- src/utils/Sorter.js | 2 + src/utils/extender.js | 105 +++++++++++----------- 7 files changed, 127 insertions(+), 102 deletions(-) diff --git a/src/css_composer/model/CssRules.js b/src/css_composer/model/CssRules.js index 873a37ade..f4fe209b9 100644 --- a/src/css_composer/model/CssRules.js +++ b/src/css_composer/model/CssRules.js @@ -2,23 +2,20 @@ import Backbone from 'backbone'; import CssRule from './CssRule'; export default Backbone.Collection.extend({ + model: CssRule, + initialize(models, opt) { // Inject editor if (opt && opt.em) this.editor = opt.em; - // Not used - this.model = (attrs, options) => { - var model; - - if (!options.em && opt && opt.em) options.em = opt.em; - - switch (1) { - default: - model = new CssRule(attrs, options); - } + // This will put the listener post CssComposer.postLoad + setTimeout(() => this.on('remove', this.onRemove)); + }, - return model; - }; + onRemove(removed) { + const em = this.editor; + em.stopListening(removed); + em.get('UndoManager').remove(removed); }, add(models, opt = {}) { diff --git a/src/dom_components/model/Components.js b/src/dom_components/model/Components.js index f491d0941..d7ddcac31 100644 --- a/src/dom_components/model/Components.js +++ b/src/dom_components/model/Components.js @@ -9,37 +9,38 @@ export default Backbone.Collection.extend({ this.listenTo(this, 'add', this.onAdd); this.config = opt.config; this.em = opt.em; - const { em } = this; + }, - this.model = (attrs, options) => { - var model; - const df = opt.em.get('DomComponents').componentTypes; - options.em = opt.em; - options.config = opt.config; - options.componentTypes = df; - options.domc = opt.domc; - - for (var it = 0; it < df.length; it++) { - var dfId = df[it].id; - if (dfId == attrs.type) { - model = df[it].model; - break; - } + model(attrs, options) { + const { opt } = options.collection; + const { em } = opt; + let model; + const df = em.get('DomComponents').componentTypes; + options.em = em; + options.config = opt.config; + options.componentTypes = df; + options.domc = opt.domc; + + for (let it = 0; it < df.length; it++) { + const dfId = df[it].id; + if (dfId == attrs.type) { + model = df[it].model; + break; } + } - if (!model) { - // get the last one - model = df[df.length - 1].model; - em && - attrs.type && - em.logWarning(`Component type '${attrs.type}' not found`, { - attrs, - options - }); - } + // If no model found, get the default one + if (!model) { + model = df[df.length - 1].model; + em && + attrs.type && + em.logWarning(`Component type '${attrs.type}' not found`, { + attrs, + options + }); + } - return new model(attrs, options); - }; + return new model(attrs, options); }, parseString(value, opt = {}) { diff --git a/src/dom_components/view/ComponentView.js b/src/dom_components/view/ComponentView.js index fdf5de18f..8b6c0c618 100644 --- a/src/dom_components/view/ComponentView.js +++ b/src/dom_components/view/ComponentView.js @@ -87,18 +87,27 @@ export default Backbone.View.extend({ onDisable() {}, remove() { - Backbone.View.prototype.remove.apply(this, arguments); - const { model } = this; - const frame = this._getFrame() || {}; + const view = this; + Backbone.View.prototype.remove.apply(view, arguments); + const { model } = view; + const frame = view._getFrame() || {}; const frameM = frame.model; model.components().forEach(comp => { const view = comp.getView(frameM); view && view.remove(); }); const { views } = model; - views.splice(views.indexOf(this), 1); - this.removed(this._clbObj()); - return this; + views.splice(views.indexOf(view), 1); + view.removed(view._clbObj()); + view.$el.data({ model: '', collection: '', view: '' }); + delete view.model; + delete view.$el; + delete view.el.__gjsv; + delete view.childrenView; + delete view.scriptContainer; + delete view.opts; + // delete view.el; + return view; }, handleDragStart(event) { diff --git a/src/dom_components/view/ComponentsView.js b/src/dom_components/view/ComponentsView.js index 5f22a1ba5..7032a7400 100644 --- a/src/dom_components/view/ComponentsView.js +++ b/src/dom_components/view/ComponentsView.js @@ -18,28 +18,31 @@ export default Backbone.View.extend({ removed.views.forEach(view => { if (!view) return; - view.remove.apply(view); const { childrenView, scriptContainer } = view; childrenView && childrenView.stopListening(); scriptContainer && scriptContainer.remove(); + view.remove.apply(view); }); - removed.components().forEach(it => this.removeChildren(it, coll, opts)); + const inner = removed.components(); + inner.forEach(it => this.removeChildren(it, coll, opts)); if (em && !tempRemove) { // Remove the component from the global list const id = removed.getId(); const domc = em.get('DomComponents'); + const sels = em.get('SelectorManager').getAll(); delete domc.componentsById[id]; // Remove all related CSS rules // TODO: remove from the frame container const allRules = em.get('CssComposer').getAll(); - allRules.remove( + const rulesRemoved = allRules.remove( allRules.filter( rule => rule.getSelectors().getFullString() === `#${id}` ) ); + sels.remove(rulesRemoved.map(rule => rule.getSelectors().at(0))); if (!removed.opt.temporary) { const cm = em.get('Commands'); @@ -50,6 +53,14 @@ export default Backbone.View.extend({ em.trigger('component:remove', removed); } } + + // Remove stuff registered in DomComponents.handleChanges + em.stopListening(inner); + em.stopListening(removed); + em.stopListening(removed.get('classes')); + const um = em.get('UndoManager'); + um.remove(removed); + um.remove(inner); }, /** @@ -134,9 +145,10 @@ export default Backbone.View.extend({ return rendered; }, - resetChildren() { + resetChildren(models, { previousModels = [] } = {}) { this.parentEl.innerHTML = ''; - this.collection.each(model => this.addToCollection(model)); + previousModels.forEach(md => this.removeChildren(md, this.collection)); + models.each(model => this.addToCollection(model)); }, render(parent) { diff --git a/src/navigator/view/ItemsView.js b/src/navigator/view/ItemsView.js index 313e524e1..7197d03d4 100644 --- a/src/navigator/view/ItemsView.js +++ b/src/navigator/view/ItemsView.js @@ -52,7 +52,8 @@ export default Backbone.View.extend({ removeChildren(removed) { const view = removed.viewLayer; if (!view) return; - view.remove.apply(view); + view.remove(); + removed.viewLayer = 0; }, /** diff --git a/src/utils/Sorter.js b/src/utils/Sorter.js index 604cb381b..242025c2e 100644 --- a/src/utils/Sorter.js +++ b/src/utils/Sorter.js @@ -1055,6 +1055,8 @@ export default Backbone.View.extend({ this.toggleSortCursor(); this.toMove = null; + this.eventMove = 0; + this.dropModel = null; if (isFunction(onEndMove)) { const data = { diff --git a/src/utils/extender.js b/src/utils/extender.js index 5e90b5e90..a4df3682b 100644 --- a/src/utils/extender.js +++ b/src/utils/extender.js @@ -1,57 +1,60 @@ import { isObject, isString, each, isUndefined } from 'underscore'; export default ({ $, Backbone }) => { - if (Backbone) { - const ViewProt = Backbone.View.prototype; - const eventNsMap = {}; - ViewProt.eventNsMap = eventNsMap; - - ViewProt.delegate = function(eventName, selector, listener) { - const vid = '.delegateEvents' + this.cid; - this.$el.on(eventName, selector, listener); - //return this; - let eventMap = eventNsMap[vid]; - - if (!eventMap) { - eventMap = []; - eventNsMap[vid] = eventMap; - } - - eventMap.push({ eventName, selector, listener }); - return this; - }; - - ViewProt.undelegateEvents = function() { - const vid = '.delegateEvents' + this.cid; - if (this.$el) { - //this.$el.off(); return this; - let eventMap = eventNsMap[vid]; - - if (eventMap) { - eventMap.forEach(({ eventName, selector, listener }) => { - this.$el.off(eventName); - }); - } - } - return this; - }; - - ViewProt.undelegate = function(ev, sel, list) { - const vid = '.delegateEvents' + this.cid; - //this.$el.off(ev, sel, list); return this; - let eventMap = eventNsMap[vid]; - - if (eventMap) { - eventMap.forEach(({ eventName, selector, listener }) => { - if (eventName == ev && selector == sel) { - this.$el.off(eventName); - } - }); - } - - return this; - }; - } + // if (Backbone) { + // const ViewProt = Backbone.View.prototype; + // const eventNsMap = {}; + // ViewProt.eventNsMap = eventNsMap; + + // ViewProt.delegate = function(eventName, selector, listener) { + // const vid = '.delegateEvents' + this.cid; + // this.$el.on(eventName, selector, listener); + // //return this; + // let eventMap = eventNsMap[vid]; + + // if (!eventMap) { + // eventMap = []; + // eventNsMap[vid] = eventMap; + // } + + // eventMap.push({ eventName, selector, listener }); + // return this; + // }; + + // ViewProt.undelegateEvents = function() { + // const vid = '.delegateEvents' + this.cid; + // if (this.$el) { + // //this.$el.off(); return this; + // let eventMap = eventNsMap[vid]; + + // if (eventMap) { + // eventMap.forEach(({ eventName, selector, listener }) => { + // this.$el.off(eventName); + // }); + // } + + // delete eventNsMap[vid]; + // } + // return this; + // }; + + // ViewProt.undelegate = function(ev, sel, list) { + // const vid = '.delegateEvents' + this.cid; + // //this.$el.off(ev, sel, list); return this; + // let eventMap = eventNsMap[vid]; + + // if (eventMap) { + // eventMap.forEach(({ eventName, selector, listener }) => { + // if (eventName == ev && selector == sel) { + // this.$el.off(eventName); + // } + // }); + // delete eventNsMap[vid]; + // } + + // return this; + // }; + // } if ($ && $.prototype.constructor.name !== 'jQuery') { const fn = $.fn; From 3544531e94610d95ac9bbff50ffcf813f5de0dfe Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 20 Feb 2020 14:11:28 +0100 Subject: [PATCH 2/5] Add sectors silently --- src/commands/view/OpenStyleManager.js | 3 --- src/style_manager/index.js | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/commands/view/OpenStyleManager.js b/src/commands/view/OpenStyleManager.js index 895a1206f..d79327860 100644 --- a/src/commands/view/OpenStyleManager.js +++ b/src/commands/view/OpenStyleManager.js @@ -1,6 +1,4 @@ import Backbone from 'backbone'; -import StyleManager from 'style_manager'; - const $ = Backbone.$; export default { @@ -27,7 +25,6 @@ export default { // Class Manager container var clm = em.SelectorManager; if (clm) this.$cn2.append(clm.render([])); - this.$cn2.append(em.StyleManager.render()); var smConfig = em.StyleManager.getConfig(); const pfx = smConfig.stylePrefix; diff --git a/src/style_manager/index.js b/src/style_manager/index.js index 338809a37..9cbe74428 100644 --- a/src/style_manager/index.js +++ b/src/style_manager/index.js @@ -82,7 +82,8 @@ export default () => { }, onLoad() { - sectors.add(c.sectors); + // Use silent as sectors' view will be created and rendered on StyleManager.render + sectors.add(c.sectors, { silent: true }); }, postRender() { From 7817945b9592bc79b9fe10049ef2dff7aeb88153 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Fri, 21 Feb 2020 13:22:54 +0100 Subject: [PATCH 3/5] Update cash-dom and cleanup extender --- package-lock.json | 47 ++---- package.json | 2 +- src/editor/model/Editor.js | 3 +- src/utils/ColorPicker.js | 2 +- src/utils/extender.js | 283 +++++++++++++++++++------------------ 5 files changed, 162 insertions(+), 175 deletions(-) diff --git a/package-lock.json b/package-lock.json index b2d9e45d1..27b0d7d51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6903,9 +6903,9 @@ "dev": true }, "cash-dom": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/cash-dom/-/cash-dom-1.3.7.tgz", - "integrity": "sha512-cWqx3b+8Vh5hvRd87voSW7hxHVhUekGiOUd7iix8fP29cl6TBIInkAqYVSKaL2xeVewS3/kfPnIIC+Xl3nVe/A==" + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/cash-dom/-/cash-dom-2.3.9.tgz", + "integrity": "sha512-2a4/LSFQPMbLhBYiJ5Z5rEz5Pic8jMVUqkqZ42w01gkopVUnxnaJcvZifcx6QFykJyWDsUWfISt4xRSyjAaK9w==" }, "ccount": { "version": "1.0.4", @@ -9935,8 +9935,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -9957,14 +9956,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9979,20 +9976,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -10109,8 +10103,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -10122,7 +10115,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -10137,7 +10129,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -10145,14 +10136,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -10171,7 +10160,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -10252,8 +10240,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -10265,7 +10252,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -10351,8 +10337,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -10388,7 +10373,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -10408,7 +10392,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -10452,14 +10435,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 80a010952..fe8da370b 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "@babel/runtime": "^7.7.1", "backbone": "1.3.3", "backbone-undo": "^0.2.5", - "cash-dom": "^1.3.7", + "cash-dom": "^2.3.9", "codemirror": "^5.49.2", "codemirror-formatting": "^1.0.0", "keymaster": "^1.6.2", diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index ac63496fb..2daf71a38 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -6,10 +6,12 @@ import { toArray, keys } from 'underscore'; +import $ from 'cash-dom'; import Backbone from 'backbone'; import Extender from 'utils/extender'; import { getModel } from 'utils/mixins'; +Backbone.$ = $; const deps = [ require('utils'), require('i18n'), @@ -43,7 +45,6 @@ Extender({ $: Backbone.$ }); -const $ = Backbone.$; const logs = { debug: console.log, info: console.info, diff --git a/src/utils/ColorPicker.js b/src/utils/ColorPicker.js index f8fd6210f..62d8ef097 100644 --- a/src/utils/ColorPicker.js +++ b/src/utils/ColorPicker.js @@ -694,7 +694,7 @@ export default function($, undefined) { return; } - boundElement.trigger(event, [get()]); + boundElement.trigger('beforeShow.spectrum', [get()]); if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) { return; diff --git a/src/utils/extender.js b/src/utils/extender.js index a4df3682b..3de7a2d78 100644 --- a/src/utils/extender.js +++ b/src/utils/extender.js @@ -59,112 +59,114 @@ export default ({ $, Backbone }) => { if ($ && $.prototype.constructor.name !== 'jQuery') { const fn = $.fn; - const splitNamespace = function(name) { - const namespaceArray = name.split('.'); - return name.indexOf('.') !== 0 - ? [namespaceArray[0], namespaceArray.slice(1)] - : [null, namespaceArray]; - }; - - const on = $.prototype.on; - const off = $.prototype.off; - const trigger = $.prototype.trigger; - const offset = $.prototype.offset; - const getEvents = eventName => eventName.split(/[,\s]+/g); - const getNamespaces = eventName => eventName.split('.'); - - fn.on = function(eventName, delegate, callback, runOnce) { - if (typeof eventName == 'string') { - const events = getEvents(eventName); - - if (events.length == 1) { - eventName = events[0]; - let namespaces = getNamespaces(eventName); - - if (eventName.indexOf('.') !== 0) { - eventName = namespaces[0]; - } - - namespaces = namespaces.slice(1); - - if (namespaces.length) { - //console.log('Found event with namespaces', namespaces, eventName, delegate, this); - const cashNs = this.data('_cashNs') || []; - // cashNs[namespace] - this.data('_cashNs', namespaces); // for each ns need to store '.store' => eventName, delegate, callback - } - - return on.call(this, eventName, delegate, callback, runOnce); - } else { - events.forEach(eventName => - this.on(eventName, delegate, callback, runOnce) - ); - return this; - } - } else { - return on.call(this, eventName, delegate, callback, runOnce); - } - }; - - fn.off = function(eventName, callback) { - if (typeof eventName == 'string') { - const events = getEvents(eventName); - - if (events.length == 1) { - eventName = events[0]; - let namespaces = getNamespaces(eventName); - - if (eventName.indexOf('.') !== 0) { - eventName = namespaces[0]; - } - - namespaces = namespaces.slice(1); - - if (namespaces.length) { - // Have to off only with the same namespace - } - - return off.call(this, eventName, callback); - } else { - events.forEach(eventName => this.off(eventName, callback)); - return this; - } - } else { - return off.call(this, eventName, callback); - } - }; - - fn.trigger = function(eventName, data) { - if (eventName instanceof $.Event) { - return this.trigger(eventName.type, data); - } - - if (typeof eventName == 'string') { - const events = getEvents(eventName); - - if (events.length == 1) { - eventName = events[0]; - let namespaces = getNamespaces(eventName); - - if (eventName.indexOf('.') !== 0) { - eventName = namespaces[0]; - } - - namespaces = namespaces.slice(1); - - if (namespaces.length) { - // have to trigger with same namespaces and eventName - } - - return trigger.call(this, eventName, data); - } else { - events.forEach(eventName => this.trigger(eventName, data)); - return this; - } - } else { - return trigger.call(this, eventName, data); - } - }; + // const splitNamespace = function(name) { + // const namespaceArray = name.split('.'); + // return name.indexOf('.') !== 0 + // ? [namespaceArray[0], namespaceArray.slice(1)] + // : [null, namespaceArray]; + // }; + + // const on = $.prototype.on; + // const off = $.prototype.off; + // const trigger = $.prototype.trigger; + // const offset = $.prototype.offset; + // const getEvents = eventName => eventName.split(/[,\s]+/g); + // const getNamespaces = eventName => eventName.split('.'); + + // fn.on = function(eventName, delegate, callback, runOnce) { + // if (typeof eventName == 'string') { + // const events = getEvents(eventName); + + // if (events.length == 1) { + // eventName = events[0]; + // let namespaces = getNamespaces(eventName); + + // if (eventName.indexOf('.') !== 0) { + // eventName = namespaces[0]; + // } + + // namespaces = namespaces.slice(1); + + // if (namespaces.length) { + // //console.log('Found event with namespaces', namespaces, eventName, delegate, this); + // const cashNs = this.data('_cashNs') || []; + // // cashNs[namespace] + // this.data('_cashNs', namespaces); // for each ns need to store '.store' => eventName, delegate, callback + // } + + // return on.call(this, eventName, delegate, callback, runOnce); + // } else { + // events.forEach(eventName => + // this.on(eventName, delegate, callback, runOnce) + // ); + // return this; + // } + // } else { + // return on.call(this, eventName, delegate, callback, runOnce); + // } + // }; + + // fn.off = function(eventName, callback) { + // if (typeof eventName == 'string') { + // const events = getEvents(eventName); + + // if (events.length == 1) { + // eventName = events[0]; + // let namespaces = getNamespaces(eventName); + + // if (eventName.indexOf('.') !== 0) { + // eventName = namespaces[0]; + // } + + // namespaces = namespaces.slice(1); + + // if (namespaces.length) { + // // Have to off only with the same namespace + // } + + // return off.call(this, eventName, callback); + // } else { + // events.forEach(eventName => this.off(eventName, callback)); + // return this; + // } + // } else { + // return off.call(this, eventName, callback); + // } + // }; + + // fn.trigger = function(eventName, data) { + // if (eventName instanceof $.Event) { + // return this.trigger(eventName.type, data); + // } + + // if (typeof eventName == 'string') { + // const events = getEvents(eventName); + + // if (events.length == 1) { + // eventName = events[0]; + // let namespaces = getNamespaces(eventName); + + // if (eventName.indexOf('.') !== 0) { + // eventName = namespaces[0]; + // } + + // namespaces = namespaces.slice(1); + + // if (namespaces.length) { + // // have to trigger with same namespaces and eventName + // } + + // return trigger.call(this, eventName, data); + // } else { + // events.forEach(eventName => this.trigger(eventName, data)); + // return this; + // } + // } else { + // return trigger.call(this, eventName, data); + // } + // }; + + // Additional helpers fn.hide = function() { return this.css('display', 'none'); @@ -181,39 +183,41 @@ export default ({ $, Backbone }) => { }; // For SVGs in IE - (fn.removeClass = function(c) { - if (!arguments.length) { - return this.attr('class', ''); - } - const classes = isString(c) && c.match(/\S+/g); - return classes - ? this.each(function(el) { - each(classes, function(c) { - if (el.classList) { - el.classList.remove(c); - } else { - const val = el.className; - const bval = el.className.baseVal; - - if (!isUndefined(bval)) { - val.baseVal = bval.replace(c, ''); - } else { - el.className = val.replace(c, ''); - } - } - }); - }) - : this; - }), - (fn.remove = function() { - return this.each(node => { - return node.parentNode && node.parentNode.removeChild(node); - }); - }), - // For spectrum compatibility - (fn.bind = function(ev, h) { - return this.on(ev, h); - }); + // (fn.removeClass = function(c) { + // if (!arguments.length) { + // return this.attr('class', ''); + // } + // const classes = isString(c) && c.match(/\S+/g); + // return classes + // ? this.each(function(el) { + // each(classes, function(c) { + // if (el.classList) { + // el.classList.remove(c); + // } else { + // const val = el.className; + // const bval = el.className.baseVal; + + // if (!isUndefined(bval)) { + // val.baseVal = bval.replace(c, ''); + // } else { + // el.className = val.replace(c, ''); + // } + // } + // }); + // }) + // : this; + // }), + // (fn.remove = function() { + // return this.each(node => { + // return node.parentNode && node.parentNode.removeChild(node); + // }); + // }), + + // For spectrum compatibility + + fn.bind = function(ev, h) { + return this.on(ev, h); + }; fn.unbind = function(ev, h) { if (isObject(ev)) { @@ -264,6 +268,7 @@ export default ({ $, Backbone }) => { return win ? win.pageYOffset : el.scrollTop || 0; }; + const offset = $.prototype.offset; fn.offset = function(coords) { let top, left; From 0d4a2d4a4eb2cb010573b7088a874688954e5ecc Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Mon, 24 Feb 2020 19:58:52 +0100 Subject: [PATCH 4/5] Fix get current JS container from CanvasView --- src/canvas/view/CanvasView.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/canvas/view/CanvasView.js b/src/canvas/view/CanvasView.js index 9426918f3..58fb57f5c 100644 --- a/src/canvas/view/CanvasView.js +++ b/src/canvas/view/CanvasView.js @@ -298,11 +298,13 @@ export default Backbone.View.extend({ * Get javascript container * @private */ - getJsContainer() { - if (!this.jsContainer) { - this.jsContainer = $(`
`).get(0); - } - return this.jsContainer; + getJsContainer(view) { + const frameView = this.getFrameView(view); + return frameView && frameView.getJsContainer(); + }, + + getFrameView(view) { + return (view && view._getFrame()) || this.em.get('currentFrame'); }, render() { From 1b6d489e3da337502a9451d623d23d06080e31c4 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Tue, 25 Feb 2020 00:50:23 +0100 Subject: [PATCH 5/5] Better clear on destroy --- src/commands/view/SelectComponent.js | 1 + src/editor/model/Editor.js | 7 +++++++ src/index.js | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/commands/view/SelectComponent.js b/src/commands/view/SelectComponent.js index a12837cec..22d4ada77 100644 --- a/src/commands/view/SelectComponent.js +++ b/src/commands/view/SelectComponent.js @@ -790,5 +790,6 @@ export default { this.onOut(); this.toggleToolsEl(); editor && editor.stopCommand('resize'); + this.editor = 0; } }; diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index 2daf71a38..9ee9bb75a 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -686,6 +686,8 @@ export default Backbone.Model.extend({ * Destroy editor */ destroyAll() { + const editor = this.getEditor(); + const { editors } = this.config.grapesjs; const { DomComponents, CssComposer, @@ -695,6 +697,7 @@ export default Backbone.Model.extend({ Keymaps, RichTextEditor } = this.attributes; + this.stopDefault(); DomComponents.clear(); CssComposer.clear(); UndoManager.clear().removeAll(); @@ -704,6 +707,10 @@ export default Backbone.Model.extend({ RichTextEditor.destroy(); this.view.remove(); this.stopListening(); + this.clear({ silent: true }); + this._previousAttributes = {}; + this.attributes = {}; + editors.splice(editors.indexOf(editor), 1); $(this.config.el) .empty() .attr(this.attrsOrig); diff --git a/src/index.js b/src/index.js index 306a6739f..47a03c8c2 100644 --- a/src/index.js +++ b/src/index.js @@ -47,7 +47,7 @@ export default { init(config = {}) { const els = config.container; if (!els) throw new Error("'container' is required"); - config = { ...defaultConfig, ...config }; + config = { ...defaultConfig, ...config, grapesjs: this }; config.el = isElement(els) ? els : document.querySelector(els); const editor = new Editor(config).init();