Browse Source

Update mode

pull/4128/head
Artur Arseniev 5 years ago
parent
commit
bdc3df7802
  1. 43
      src/rich_text_editor/model/RichTextEditor.js
  2. 17
      src/utils/Sorter.js

43
src/rich_text_editor/model/RichTextEditor.js

@ -1,6 +1,7 @@
// The initial version of this RTE was borrowed from https://github.com/jaredreich/pell // The initial version of this RTE was borrowed from https://github.com/jaredreich/pell
// and adapted to the GrapesJS's need // and adapted to the GrapesJS's need
import { isString } from 'underscore';
import { on, off } from 'utils/mixins'; import { on, off } from 'utils/mixins';
const RTE_KEY = '_rte'; const RTE_KEY = '_rte';
@ -8,48 +9,45 @@ const RTE_KEY = '_rte';
const btnState = { const btnState = {
ACTIVE: 1, ACTIVE: 1,
INACTIVE: 0, INACTIVE: 0,
DISABLED: -1 DISABLED: -1,
}; };
const isValidAnchor = rte => { const isValidAnchor = rte => {
const anchor = rte.selection().anchorNode; const anchor = rte.selection().anchorNode;
const parentNode = anchor && anchor.parentNode; const parentNode = anchor && anchor.parentNode;
const nextSibling = anchor && anchor.nextSibling; const nextSibling = anchor && anchor.nextSibling;
return ( return (parentNode && parentNode.nodeName == 'A') || (nextSibling && nextSibling.nodeName == 'A');
(parentNode && parentNode.nodeName == 'A') ||
(nextSibling && nextSibling.nodeName == 'A')
);
}; };
const defActions = { const defActions = {
bold: { bold: {
name: 'bold', name: 'bold',
icon: '<b>B</b>', icon: '<b>B</b>',
attributes: { title: 'Bold' }, attributes: { title: 'Bold' },
result: rte => rte.exec('bold') result: rte => rte.exec('bold'),
}, },
italic: { italic: {
name: 'italic', name: 'italic',
icon: '<i>I</i>', icon: '<i>I</i>',
attributes: { title: 'Italic' }, attributes: { title: 'Italic' },
result: rte => rte.exec('italic') result: rte => rte.exec('italic'),
}, },
underline: { underline: {
name: 'underline', name: 'underline',
icon: '<u>U</u>', icon: '<u>U</u>',
attributes: { title: 'Underline' }, attributes: { title: 'Underline' },
result: rte => rte.exec('underline') result: rte => rte.exec('underline'),
}, },
strikethrough: { strikethrough: {
name: 'strikethrough', name: 'strikethrough',
icon: '<s>S</s>', icon: '<s>S</s>',
attributes: { title: 'Strike-through' }, attributes: { title: 'Strike-through' },
result: rte => rte.exec('strikeThrough') result: rte => rte.exec('strikeThrough'),
}, },
link: { link: {
icon: `<span style="transform:rotate(45deg)">&supdsub;</span>`, icon: `<span style="transform:rotate(45deg)">&supdsub;</span>`,
name: 'link', name: 'link',
attributes: { attributes: {
style: 'font-size:1.4rem;padding:0 4px 2px;', style: 'font-size:1.4rem;padding:0 4px 2px;',
title: 'Link' title: 'Link',
}, },
state: (rte, doc) => { state: (rte, doc) => {
if (rte && rte.selection()) { if (rte && rte.selection()) {
@ -64,8 +62,8 @@ const defActions = {
} else { } else {
rte.insertHTML(`<a class="link" href="">${rte.selection()}</a>`); rte.insertHTML(`<a class="link" href="">${rte.selection()}</a>`);
} }
} },
} },
}; };
export default class RichTextEditor { export default class RichTextEditor {
@ -89,9 +87,7 @@ export default class RichTextEditor {
} }
return result; return result;
}); });
const actions = acts.length const actions = acts.length ? acts : Object.keys(defActions).map(a => defActions[a]);
? acts
: Object.keys(defActions).map(a => defActions[a]);
settings.classes = { settings.classes = {
...{ ...{
@ -99,9 +95,9 @@ export default class RichTextEditor {
button: 'action', button: 'action',
active: 'active', active: 'active',
disabled: 'disabled', disabled: 'disabled',
inactive: 'inactive' inactive: 'inactive',
}, },
...settings.classes ...settings.classes,
}; };
const classes = settings.classes; const classes = settings.classes;
@ -205,10 +201,7 @@ export default class RichTextEditor {
syncActions() { syncActions() {
this.getActions().forEach(action => { this.getActions().forEach(action => {
if (this.settings.actionbar) { if (this.settings.actionbar) {
if ( if (!action.state || (action.state && action.state(this, this.doc) >= 0)) {
!action.state ||
(action.state && action.state(this, this.doc) >= 0)
) {
const event = action.event || 'click'; const event = action.event || 'click';
action.btn[`on${event}`] = e => { action.btn[`on${event}`] = e => {
action.result(this, action); action.result(this, action);
@ -289,7 +282,6 @@ export default class RichTextEditor {
* @param {string} value HTML string * @param {string} value HTML string
*/ */
insertHTML(value) { insertHTML(value) {
let lastNode;
const doc = this.doc; const doc = this.doc;
const sel = doc.getSelection(); const sel = doc.getSelection();
@ -297,10 +289,13 @@ export default class RichTextEditor {
const node = doc.createElement('div'); const node = doc.createElement('div');
const range = sel.getRangeAt(0); const range = sel.getRangeAt(0);
range.deleteContents(); range.deleteContents();
node.innerHTML = value; if (isString(value)) {
node.innerHTML = value;
} else if (value) {
node.appendChild(value);
}
Array.prototype.slice.call(node.childNodes).forEach(nd => { Array.prototype.slice.call(node.childNodes).forEach(nd => {
range.insertNode(nd); range.insertNode(nd);
lastNode = nd;
}); });
sel.removeAllRanges(); sel.removeAllRanges();

17
src/utils/Sorter.js

@ -1051,7 +1051,7 @@ export default Backbone.View.extend({
* @param {Object} pos Object with position coordinates * @param {Object} pos Object with position coordinates
* */ * */
move(dst, src, pos) { move(dst, src, pos) {
const { em, activeTextModel, dropContent } = this; const { em, dropContent } = this;
const srcEl = getElement(src); const srcEl = getElement(src);
const warns = []; const warns = [];
const index = pos.method === 'after' ? pos.indexEl + 1 : pos.indexEl; const index = pos.method === 'after' ? pos.indexEl + 1 : pos.indexEl;
@ -1059,7 +1059,6 @@ export default Backbone.View.extend({
const targetCollection = $(dst).data('collection'); const targetCollection = $(dst).data('collection');
const { trgModel, srcModel, draggable } = validResult; const { trgModel, srcModel, draggable } = validResult;
const droppable = trgModel instanceof Backbone.Collection ? 1 : validResult.droppable; const droppable = trgModel instanceof Backbone.Collection ? 1 : validResult.droppable;
const isTextableActive = this.isTextableActive(srcModel, trgModel);
let modelToDrop, modelTemp, created; let modelToDrop, modelTemp, created;
if (targetCollection && droppable && draggable) { if (targetCollection && droppable && draggable) {
@ -1079,18 +1078,16 @@ export default Backbone.View.extend({
opts.avoidUpdateStyle = 1; opts.avoidUpdateStyle = 1;
} }
if (isTextableActive) { if (this.isTextableActive(srcModel, trgModel)) {
const viewActive = activeTextModel.getView(); trgModel.trigger('active');
activeTextModel.trigger('active');
const modelEl = srcModel.getEl(); const modelEl = srcModel.getEl();
delete srcModel.opt.temporary; delete srcModel.opt.temporary;
srcModel.getView().render(); srcModel.getView().render();
modelEl.setAttribute('data-gjs-textable', 'true'); modelEl.setAttribute('data-gjs-textable', 'true');
const { outerHTML } = modelEl; trgModel.once('rte:enable', () => {
activeTextModel.once('rte:enable', () => { const trgView = trgModel.getView();
const rte = viewActive.activeRte; trgView.activeRte?.insertHTML(modelEl);
rte.insertHTML && rte.insertHTML(outerHTML); trgView.disableEditing({ keepIds: getComponentIds(srcModel) });
viewActive.disableEditing({ keepIds: getComponentIds(srcModel) });
}); });
created = srcModel; created = srcModel;
} else { } else {

Loading…
Cancel
Save