From 9741aa8bff4618cc8bc92cae85ab4da64278d9e3 Mon Sep 17 00:00:00 2001 From: Nate Mielnik Date: Mon, 17 Aug 2015 22:58:56 -0400 Subject: [PATCH] Fix issue with insertHTMLCommand which deletes editor --- spec/util.spec.js | 27 +++++++++++++++++++++++++++ src/js/util.js | 15 +++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/spec/util.spec.js b/spec/util.spec.js index 550c9a753..ad9dd5df1 100644 --- a/spec/util.spec.js +++ b/spec/util.spec.js @@ -378,4 +378,31 @@ describe('MediumEditor.util', function () { MediumEditor.util.isIE = origIsIE; }); }); + + describe('insertHTMLCommand', function () { + it('should not remove the contenteditable element when calling insert into an empty contenteditable element', function () { + var el = this.createElement('div', 'editable', ''), + origQCS = document.queryCommandSupported; + // Force our custom implementation to run + spyOn(document, 'queryCommandSupported').and.callFake(function (command) { + if (command === 'insertHTML') { + return false; + } + return origQCS.apply(document, arguments); + }); + // Mimic an editor element + el.setAttribute('contenteditable', true); + el.setAttribute('data-medium-editor-element', true); + + // Make sure the element has 0 child nodes + while (el.firstChild) { + el.remove(el.firstChild); + } + selectElementContents(el); + MediumEditor.util.insertHTMLCommand(document, '

some pasted html

', true); + + expect(el.innerHTML).toBe('

some pasted html

'); + expect(document.body.contains(el)).toBe(true, 'The editor element has been removed from the page'); + }); + }); }); diff --git a/src/js/util.js b/src/js/util.js index afc10e93c..d56212feb 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -341,11 +341,18 @@ if (selection.rangeCount) { range = selection.getRangeAt(0); toReplace = range.commonAncestorContainer; - // Ensure range covers maximum amount of nodes as possible - // By moving up the DOM and selecting ancestors whose only child is the range - if ((toReplace.nodeType === 3 && range.startOffset === 0 && range.endOffset === toReplace.nodeValue.length) || + + // https://github.com/yabwe/medium-editor/issues/748 + // If the selection is an empty editor element, create a temporary text node inside of the editor + // and select it so that we don't delete the editor element + if (Util.isMediumEditorElement(toReplace) && !toReplace.firstChild) { + range.selectNode(toReplace.appendChild(doc.createTextNode(''))); + } else if ((toReplace.nodeType === 3 && range.startOffset === 0 && range.endOffset === toReplace.nodeValue.length) || (toReplace.nodeType !== 3 && toReplace.innerHTML === range.toString())) { - while (toReplace.parentNode && + // Ensure range covers maximum amount of nodes as possible + // By moving up the DOM and selecting ancestors whose only child is the range + while (!Util.isMediumEditorElement(toReplace) && + toReplace.parentNode && toReplace.parentNode.childNodes.length === 1 && !Util.isMediumEditorElement(toReplace.parentNode)) { toReplace = toReplace.parentNode;