Browse Source

Merge branch 'fix-leaks' into test-fix-leaks

pull/2732/head
Artur Arseniev 7 years ago
parent
commit
a7b4e642a7
  1. 41
      package-lock.json
  2. 3
      src/commands/view/OpenStyleManager.js
  3. 1
      src/commands/view/SelectComponent.js
  4. 21
      src/css_composer/model/CssRules.js
  5. 55
      src/dom_components/model/Components.js
  6. 33
      src/dom_components/view/ComponentView.js
  7. 37
      src/dom_components/view/ComponentsView.js
  8. 7
      src/editor/model/Editor.js
  9. 2
      src/index.js
  10. 3
      src/navigator/view/ItemsView.js
  11. 3
      src/style_manager/index.js
  12. 2
      src/utils/Sorter.js

41
package-lock.json

@ -9935,8 +9935,7 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -9957,14 +9956,12 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -9979,20 +9976,17 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -10109,8 +10103,7 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -10122,7 +10115,6 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -10137,7 +10129,6 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -10145,14 +10136,12 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -10171,7 +10160,6 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -10252,8 +10240,7 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -10265,7 +10252,6 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -10351,8 +10337,7 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -10388,7 +10373,6 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -10408,7 +10392,6 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -10452,14 +10435,12 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
} }
} }
}, },

3
src/commands/view/OpenStyleManager.js

@ -1,6 +1,4 @@
import Backbone from 'backbone'; import Backbone from 'backbone';
import StyleManager from 'style_manager';
const $ = Backbone.$; const $ = Backbone.$;
export default { export default {
@ -27,7 +25,6 @@ export default {
// Class Manager container // Class Manager container
var clm = em.SelectorManager; var clm = em.SelectorManager;
if (clm) this.$cn2.append(clm.render([])); if (clm) this.$cn2.append(clm.render([]));
this.$cn2.append(em.StyleManager.render()); this.$cn2.append(em.StyleManager.render());
var smConfig = em.StyleManager.getConfig(); var smConfig = em.StyleManager.getConfig();
const pfx = smConfig.stylePrefix; const pfx = smConfig.stylePrefix;

1
src/commands/view/SelectComponent.js

@ -780,5 +780,6 @@ export default {
this.onOut(); this.onOut();
this.toggleToolsEl(); this.toggleToolsEl();
editor && editor.stopCommand('resize'); editor && editor.stopCommand('resize');
this.editor = 0;
} }
}; };

21
src/css_composer/model/CssRules.js

@ -2,23 +2,20 @@ import Backbone from 'backbone';
import CssRule from './CssRule'; import CssRule from './CssRule';
export default Backbone.Collection.extend({ export default Backbone.Collection.extend({
model: CssRule,
initialize(models, opt) { initialize(models, opt) {
// Inject editor // Inject editor
if (opt && opt.em) this.editor = opt.em; if (opt && opt.em) this.editor = opt.em;
// Not used // This will put the listener post CssComposer.postLoad
this.model = (attrs, options) => { setTimeout(() => this.on('remove', this.onRemove));
var model; },
if (!options.em && opt && opt.em) options.em = opt.em;
switch (1) {
default:
model = new CssRule(attrs, options);
}
return model; onRemove(removed) {
}; const em = this.editor;
em.stopListening(removed);
em.get('UndoManager').remove(removed);
}, },
add(models, opt = {}) { add(models, opt = {}) {

55
src/dom_components/model/Components.js

@ -9,37 +9,38 @@ export default Backbone.Collection.extend({
this.listenTo(this, 'add', this.onAdd); this.listenTo(this, 'add', this.onAdd);
this.config = opt.config; this.config = opt.config;
this.em = opt.em; this.em = opt.em;
const { em } = this; },
this.model = (attrs, options) => { model(attrs, options) {
var model; const { opt } = options.collection;
const df = opt.em.get('DomComponents').componentTypes; const { em } = opt;
options.em = opt.em; let model;
options.config = opt.config; const df = em.get('DomComponents').componentTypes;
options.componentTypes = df; options.em = em;
options.domc = opt.domc; options.config = opt.config;
options.componentTypes = df;
for (var it = 0; it < df.length; it++) { options.domc = opt.domc;
var dfId = df[it].id;
if (dfId == attrs.type) { for (let it = 0; it < df.length; it++) {
model = df[it].model; const dfId = df[it].id;
break; if (dfId == attrs.type) {
} model = df[it].model;
break;
} }
}
if (!model) { // If no model found, get the default one
// get the last one if (!model) {
model = df[df.length - 1].model; model = df[df.length - 1].model;
em && em &&
attrs.type && attrs.type &&
em.logWarning(`Component type '${attrs.type}' not found`, { em.logWarning(`Component type '${attrs.type}' not found`, {
attrs, attrs,
options options
}); });
} }
return new model(attrs, options); return new model(attrs, options);
};
}, },
parseString(value, opt = {}) { parseString(value, opt = {}) {

33
src/dom_components/view/ComponentView.js

@ -87,18 +87,27 @@ export default Backbone.View.extend({
onDisable() {}, onDisable() {},
remove() { remove() {
Backbone.View.prototype.remove.apply(this, arguments); const view = this;
const { model } = this; Backbone.View.prototype.remove.apply(view, arguments);
const frame = this._getFrame() || {}; const { model } = view;
const frame = view._getFrame() || {};
const frameM = frame.model; const frameM = frame.model;
model.components().forEach(comp => { model.components().forEach(comp => {
const view = comp.getView(frameM); const view = comp.getView(frameM);
view && view.remove(); view && view.remove();
}); });
const { views } = model; const { views } = model;
views.splice(views.indexOf(this), 1); views.splice(views.indexOf(view), 1);
this.removed(this._clbObj()); view.removed(view._clbObj());
return this; 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) { handleDragStart(event) {
@ -474,11 +483,13 @@ export default Backbone.View.extend({
renderChildren() { renderChildren() {
this.updateContent(); this.updateContent();
const container = this.getChildrenContainer(); const container = this.getChildrenContainer();
const view = new ComponentsView({ const view =
collection: this.model.get('components'), this.childrenView ||
config: this.config, new ComponentsView({
componentTypes: this.opts.componentTypes collection: this.model.get('components'),
}); config: this.config,
componentTypes: this.opts.componentTypes
});
view.render(container); view.render(container);
this.childrenView = view; this.childrenView = view;

37
src/dom_components/view/ComponentsView.js

@ -18,28 +18,31 @@ export default Backbone.View.extend({
removed.views.forEach(view => { removed.views.forEach(view => {
if (!view) return; if (!view) return;
view.remove.apply(view);
const { childrenView, scriptContainer } = view; const { childrenView, scriptContainer } = view;
childrenView && childrenView.stopListening(); childrenView && childrenView.stopListening();
scriptContainer && scriptContainer.remove(); 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) { if (em && !tempRemove) {
// Remove the component from the global list // Remove the component from the global list
const id = removed.getId(); const id = removed.getId();
const domc = em.get('DomComponents'); const domc = em.get('DomComponents');
const sels = em.get('SelectorManager').getAll();
delete domc.componentsById[id]; delete domc.componentsById[id];
// Remove all related CSS rules // Remove all related CSS rules
// TODO: remove from the frame container // TODO: remove from the frame container
const allRules = em.get('CssComposer').getAll(); const allRules = em.get('CssComposer').getAll();
allRules.remove( const rulesRemoved = allRules.remove(
allRules.filter( allRules.filter(
rule => rule.getSelectors().getFullString() === `#${id}` rule => rule.getSelectors().getFullString() === `#${id}`
) )
); );
sels.remove(rulesRemoved.map(rule => rule.getSelectors().at(0)));
if (!removed.opt.temporary) { if (!removed.opt.temporary) {
const cm = em.get('Commands'); const cm = em.get('Commands');
@ -50,6 +53,14 @@ export default Backbone.View.extend({
em.trigger('component:remove', removed); 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);
}, },
/** /**
@ -86,6 +97,8 @@ export default Backbone.View.extend({
if (!this.compView) this.compView = require('./ComponentView').default; if (!this.compView) this.compView = require('./ComponentView').default;
const { config, opts, em } = this; const { config, opts, em } = this;
const fragment = fragmentEl || null; const fragment = fragmentEl || null;
const { frameView = {} } = config;
const sameFrameView = frameView.model && model.getView(frameView.model);
const dt = const dt =
opts.componentTypes || (em && em.get('DomComponents').getTypes()); opts.componentTypes || (em && em.get('DomComponents').getTypes());
const type = model.get('type'); const type = model.get('type');
@ -97,12 +110,13 @@ export default Backbone.View.extend({
break; break;
} }
} }
const view =
const view = new viewObject({ sameFrameView ||
model, new viewObject({
config, model,
componentTypes: dt config,
}); componentTypes: dt
});
let rendered = view.render().el; let rendered = view.render().el;
if (fragment) { if (fragment) {
@ -134,9 +148,10 @@ export default Backbone.View.extend({
return rendered; return rendered;
}, },
resetChildren() { resetChildren(models, { previousModels = [] } = {}) {
this.parentEl.innerHTML = ''; 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) { render(parent) {

7
src/editor/model/Editor.js

@ -688,6 +688,8 @@ export default Backbone.Model.extend({
* Destroy editor * Destroy editor
*/ */
destroyAll() { destroyAll() {
const editor = this.getEditor();
const { editors } = this.config.grapesjs;
const { const {
DomComponents, DomComponents,
CssComposer, CssComposer,
@ -697,6 +699,7 @@ export default Backbone.Model.extend({
Keymaps, Keymaps,
RichTextEditor RichTextEditor
} = this.attributes; } = this.attributes;
this.stopDefault();
DomComponents.clear(); DomComponents.clear();
CssComposer.clear(); CssComposer.clear();
UndoManager.clear().removeAll(); UndoManager.clear().removeAll();
@ -706,6 +709,10 @@ export default Backbone.Model.extend({
RichTextEditor.destroy(); RichTextEditor.destroy();
this.view.remove(); this.view.remove();
this.stopListening(); this.stopListening();
this.clear({ silent: true });
this._previousAttributes = {};
this.attributes = {};
editors.splice(editors.indexOf(editor), 1);
$(this.config.el) $(this.config.el)
.empty() .empty()
.attr(this.attrsOrig); .attr(this.attrsOrig);

2
src/index.js

@ -47,7 +47,7 @@ export default {
init(config = {}) { init(config = {}) {
const els = config.container; const els = config.container;
if (!els) throw new Error("'container' is required"); if (!els) throw new Error("'container' is required");
config = { ...defaultConfig, ...config }; config = { ...defaultConfig, ...config, grapesjs: this };
config.el = isElement(els) ? els : document.querySelector(els); config.el = isElement(els) ? els : document.querySelector(els);
const editor = new Editor(config).init(); const editor = new Editor(config).init();

3
src/navigator/view/ItemsView.js

@ -52,7 +52,8 @@ export default Backbone.View.extend({
removeChildren(removed) { removeChildren(removed) {
const view = removed.viewLayer; const view = removed.viewLayer;
if (!view) return; if (!view) return;
view.remove.apply(view); view.remove();
removed.viewLayer = 0;
}, },
/** /**

3
src/style_manager/index.js

@ -82,7 +82,8 @@ export default () => {
}, },
onLoad() { 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() { postRender() {

2
src/utils/Sorter.js

@ -1055,6 +1055,8 @@ export default Backbone.View.extend({
this.toggleSortCursor(); this.toggleSortCursor();
this.toMove = null; this.toMove = null;
this.eventMove = 0;
this.dropModel = null;
if (isFunction(onEndMove)) { if (isFunction(onEndMove)) {
const data = { const data = {

Loading…
Cancel
Save