Browse Source

Merge element content in text components before toHTML. Closes #1767

pull/1874/head
Artur Arseniev 7 years ago
parent
commit
2ab410dc58
  1. 5
      src/dom_components/model/ComponentText.js
  2. 82
      src/dom_components/view/ComponentTextView.js

5
src/dom_components/model/ComponentText.js

@ -6,5 +6,10 @@ module.exports = Component.extend({
type: 'text',
droppable: false,
editable: true
},
toHTML() {
this.trigger('sync:content', { silent: 1 });
return Component.prototype.toHTML.apply(this, arguments);
}
});

82
src/dom_components/view/ComponentTextView.js

@ -15,6 +15,7 @@ module.exports = ComponentView.extend({
const em = this.em;
this.listenTo(model, 'focus', this.onActive);
this.listenTo(model, 'change:content', this.updateContentText);
this.listenTo(model, 'sync:content', this.syncContent);
this.rte = em && em.get('RichTextEditor');
},
@ -52,57 +53,66 @@ module.exports = ComponentView.extend({
* @private
* */
disableEditing() {
const model = this.model;
const { model, rte, activeRte } = this;
const editable = model.get('editable');
const rte = this.rte;
const contentOpt = { fromDisable: 1 };
if (rte && editable) {
try {
rte.disable(this, this.activeRte);
rte.disable(this, activeRte);
} catch (err) {
console.error(err);
}
const content = this.getChildrenContainer().innerHTML;
const comps = model.get('components');
comps.length && comps.reset();
model.set('content', '', contentOpt);
// If there is a custom RTE the content is just baked staticly
// inside 'content'
if (rte.customRte) {
// Avoid double content by removing its children components
// and force to trigger change
model.set('content', content, contentOpt);
} else {
const clean = model => {
const selectable = !['text', 'default', ''].some(type =>
model.is(type)
);
model.set({
this.syncContent();
}
this.rteEnabled = 0;
this.toggleEvents();
},
/**
* Merge content from the DOM to the model
*/
syncContent(opts = {}) {
const { model, rte, rteEnabled } = this;
if (!rteEnabled && !opts.force) return;
const content = this.getChildrenContainer().innerHTML;
const comps = model.components();
const contentOpt = { fromDisable: 1, ...opts };
comps.length && comps.reset(null, opts);
model.set('content', '', contentOpt);
// If there is a custom RTE the content is just baked staticly
// inside 'content'
if (rte.customRte) {
model.set('content', content, contentOpt);
} else {
const clean = model => {
const selectable = !['text', 'default', ''].some(type =>
model.is(type)
);
model.set(
{
editable: selectable && model.get('editable'),
selectable: selectable,
hoverable: selectable,
highlightable: 0,
removable: 0,
draggable: 0,
copyable: 0,
selectable: selectable,
hoverable: selectable,
toolbar: ''
});
model.get('components').each(model => clean(model));
};
// Avoid re-render on reset with silent option
model.trigger('change:content', model, '', contentOpt);
comps.add(content);
comps.each(model => clean(model));
comps.trigger('resetNavigator');
}
},
opts
);
model.get('components').each(model => clean(model));
};
// Avoid re-render on reset with silent option
!opts.silent && model.trigger('change:content', model, '', contentOpt);
comps.add(content, opts);
comps.each(model => clean(model));
comps.trigger('resetNavigator');
}
this.rteEnabled = 0;
this.toggleEvents();
},
/**

Loading…
Cancel
Save