diff --git a/src/dom_components/model/Components.js b/src/dom_components/model/Components.js index 69861c2fb..b6de490e9 100644 --- a/src/dom_components/model/Components.js +++ b/src/dom_components/model/Components.js @@ -1,20 +1,13 @@ import Backbone from 'backbone'; -import { isEmpty, isArray, isString, each, includes, extend, flatten, debounce } from 'underscore'; +import { isEmpty, isArray, isString, isFunction, each, includes, extend, flatten, debounce } from 'underscore'; import Component, { keySymbol, keySymbols } from './Component'; -const getIdsToKeep = (prev, res = []) => { - const pr = prev || []; - pr.forEach(comp => { - res.push(comp.getId()); - getIdsToKeep(comp.components(), res); - }); - return res; -}; - -const getNewIds = (items, res = []) => { - items.map(item => { - res.push(item.getId()); - getNewIds(item.components(), res); +export const getComponentIds = (cmp, res = []) => { + if (!cmp) return []; + const cmps = isArray(cmp) || isFunction(cmp.map) ? cmp : [cmp]; + cmps.map(cmp => { + res.push(cmp.getId()); + getComponentIds(cmp.components().models, res); }); return res; }; @@ -50,26 +43,18 @@ export default Backbone.Collection.extend({ const coll = this; const prev = opts.previousModels || []; const toRemove = prev.filter(prev => !models.get(prev.cid)); - const newIds = getNewIds(models); - opts.keepIds = getIdsToKeep(prev).filter(pr => newIds.indexOf(pr) >= 0); + const newIds = getComponentIds(models); + 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 = getIdsToKeep(this); + opts.keepIds = getComponentIds(this); const { domc } = this; const allByID = domc ? domc.allById() : {}; const parsed = this.parseString(input, opts); const cmps = isArray(parsed) ? parsed : [parsed]; - console.log({ - len: this.length, - input, - cmps, - allByID, - newCmp: getComponentsFromDefs(cmps, allByID), - keepIds: opts.keepIds, - }); this.reset(cmps, opts); }, @@ -177,8 +162,7 @@ export default Backbone.Collection.extend({ }, add(models, opt = {}) { - const { parent } = this; - opt.keepIds = getIdsToKeep(opt.previousModels); + opt.keepIds = [...(opt.keepIds || []), ...getComponentIds(opt.previousModels)]; if (isString(models)) { models = this.parseString(models, opt); diff --git a/src/dom_components/view/ComponentTextView.js b/src/dom_components/view/ComponentTextView.js index 7e4fdd7bd..e3cc6fbdd 100644 --- a/src/dom_components/view/ComponentTextView.js +++ b/src/dom_components/view/ComponentTextView.js @@ -1,5 +1,6 @@ import { on, off } from 'utils/mixins'; import ComponentView from './ComponentView'; +import { bindAll } from 'underscore'; const compProt = ComponentView.prototype; @@ -11,7 +12,7 @@ export default ComponentView.extend({ initialize(o) { compProt.initialize.apply(this, arguments); - this.disableEditing = this.disableEditing.bind(this); + bindAll(this, 'disableEditing', 'onDisable'); const model = this.model; const em = this.em; this.listenTo(model, 'focus', this.onActive); @@ -59,7 +60,7 @@ export default ComponentView.extend({ * Disable element content editing * @private * */ - async disableEditing() { + async disableEditing(opts = {}) { const { model, rte, activeRte, em } = this; // There are rare cases when disableEditing is called when the view is already removed // so, we have to check for the model, this will avoid breaking stuff. @@ -73,7 +74,7 @@ export default ComponentView.extend({ } if (editable && this.getContent() !== this.lastContent) { - this.syncContent(); + this.syncContent(opts); this.lastContent = ''; } } @@ -170,11 +171,11 @@ export default ComponentView.extend({ // The ownerDocument is from the frame var elDocs = [this.el.ownerDocument, document]; - mixins.off(elDocs, 'mousedown', this.disableEditing); - mixins[method](elDocs, 'mousedown', this.disableEditing); - em[method]('toolbar:run:before', this.disableEditing); + mixins.off(elDocs, 'mousedown', this.onDisable); + mixins[method](elDocs, 'mousedown', this.onDisable); + em[method]('toolbar:run:before', this.onDisable); if (model) { - model[method]('removed', this.disableEditing); + model[method]('removed', this.onDisable); model.trigger(`rte:${enable ? 'enable' : 'disable'}`); } diff --git a/src/utils/Sorter.js b/src/utils/Sorter.js index 7efc183e8..93a56d4ed 100644 --- a/src/utils/Sorter.js +++ b/src/utils/Sorter.js @@ -1,6 +1,8 @@ import Backbone from 'backbone'; import { isString, isFunction, isArray, result, each, bindAll } from 'underscore'; import { on, off, matches, getElement, getPointerEvent, isTextNode, getModel } from 'utils/mixins'; +import { getComponentIds } from '../dom_components/model/Components'; + const $ = Backbone.$; const noop = () => {}; @@ -1088,7 +1090,7 @@ export default Backbone.View.extend({ activeTextModel.once('rte:enable', () => { const rte = viewActive.activeRte; rte.insertHTML && rte.insertHTML(outerHTML); - activeTextModel.trigger('disable'); + viewActive.disableEditing({ keepIds: getComponentIds(srcModel) }); }); created = srcModel; } else {