diff --git a/src/rich_text_editor/view/RichTextEditor.js b/src/rich_text_editor/view/RichTextEditor.js index a5a212aa2..cf2313e2f 100644 --- a/src/rich_text_editor/view/RichTextEditor.js +++ b/src/rich_text_editor/view/RichTextEditor.js @@ -1,6 +1,8 @@ // The initial version of this RTE was borrowed from https://github.com/jaredreich/pell // and adapted to the GrapesJS's need +const RTE_KEY = '_rte'; + const actions = { bold: { icon: 'B', @@ -37,8 +39,8 @@ export default class RichTextEditor { constructor(settings = {}) { const el = settings.element; - if (el.rte) { - return el.rte; + if (el[RTE_KEY]) { + return el[RTE_KEY]; } settings.actions = settings.actions @@ -71,7 +73,7 @@ export default class RichTextEditor { el.oninput = e => settings.onChange(e.target.innerHTML) el.onkeydown = e => (e.which === 9 && e.preventDefault()); - el.rte = this; + el[RTE_KEY] = this; this.el = el; this.doc = el.ownerDocument; @@ -83,8 +85,19 @@ export default class RichTextEditor { return this; } + enable() { + this.actionbar().style.display = ''; + this.el.contentEditable = true; + this.syncActions(); + } + + disable() { + this.actionbar().style.display = 'none'; + this.el.contentEditable = false; + } + /** - * Sync actions with a current rte + * Sync actions with the current RTE */ syncActions() { this.actions().forEach(action => { @@ -99,40 +112,58 @@ export default class RichTextEditor { */ addAction(action) { const btn = document.createElement('span'); + const icon = action.icon; btn.className = this.classes.button; - btn.insertAdjacentHTML('afterbegin', action.icon); btn.title = action.title; action.btn = btn; - this.actionbar().appendChild(btn); - } - enable() { - this.actionbar().style.display = ''; - el.contentEditable = true; - this.syncActions(); - } + if (typeof icon == 'string') { + btn.innerHTML = icon; + } else { + btn.appendChild(icon); + } - disable() { - this.actionbar().style.display = 'none'; - el.contentEditable = false; + this.actionbar().appendChild(btn); } + /** + * Get the array of current actions + * @return {Array} + */ actions() { return this.settings.actions; } + /** + * Returns the Selection instance + * @return {Selection} + */ selection() { this.doc.getSelection() } + /** + * Execute the command + * @param {string} command Command name + * @param {any} [value=null Command's arguments + */ exec(command, value = null) { this.doc.execCommand(command, false, value); } + /** + * Get the actionbar element + * @return {HTMLElement} + */ actionbar() { return this.actionbar; } + /** + * Set custom HTML to the selection, useful as the default 'insertHTML' command + * doesn't work in the same way on all browsers + * @param {string} value HTML string + */ insertHTML(value) { const doc = this.doc; const sel = doc.getSelection();