diff --git a/spec/content.spec.js b/spec/content.spec.js
index 56f584c09..c5f1b8ac7 100644
--- a/spec/content.spec.js
+++ b/spec/content.spec.js
@@ -50,6 +50,21 @@ describe('Content TestCase', function () {
}
});
+ it('should cleanup after list is removed', function () {
+ this.el.innerHTML = '
';
+ var editor = this.newMediumEditor('.editor', {
+ toolbar: {
+ buttons: ['unorderedlist']
+ }
+ }),
+ target = editor.elements[0].querySelector('li'),
+ toolbar = editor.getExtensionByName('toolbar');
+
+ selectElementContentsAndFire(target);
+ fireEvent(toolbar.getToolbarElement().querySelector('[data-action="insertunorderedlist"]'), 'click');
+ expect(this.el.innerHTML).toBe('lorem
');
+ });
+
describe('when the tab key is pressed', function () {
it('should indent when within an ', function () {
this.el.innerHTML = '- lorem
- ipsum
';
diff --git a/src/js/core.js b/src/js/core.js
index 9def0f452..d2b3a01a1 100644
--- a/src/js/core.js
+++ b/src/js/core.js
@@ -939,7 +939,7 @@
// do some DOM clean-up for known browser issues after the action
if (action === 'insertunorderedlist' || action === 'insertorderedlist') {
- MediumEditor.util.cleanListDOM(this.options.ownerDocument, this.getSelectedParentElement());
+ MediumEditor.util.cleanListDOM(this.options.contentWindow, this.options.ownerDocument, this.getSelectedParentElement());
}
this.checkSelection();
diff --git a/src/js/util.js b/src/js/util.js
index c2bf06c45..92af85d1e 100644
--- a/src/js/util.js
+++ b/src/js/util.js
@@ -673,19 +673,58 @@
return false;
},
- cleanListDOM: function (ownerDocument, element) {
+ cleanListDOM: function (contentWindow, ownerDocument, element) {
if (element.nodeName.toLowerCase() !== 'li') {
- return;
- }
+ var selection = contentWindow.getSelection(),
+ newRange = ownerDocument.createRange(),
+ oldRange = selection.getRangeAt(0),
+ startContainer = oldRange.startContainer,
+ startOffset = oldRange.startOffset,
+ endContainer = oldRange.endContainer,
+ endOffset = oldRange.endOffset,
+ node, newNode, nextNode;
+
+ if (element.nodeName.toLowerCase() === 'span') {
+ // Chrome unwraps removed li elements into a span
+ node = element;
+ } else {
+ // FF leaves them as text nodes
+ node = startContainer;
+ }
+
+ while (node) {
+ if (node.nodeName.toLowerCase() !== 'span' && node.nodeName.toLowerCase() !== '#text') {
+ break;
+ }
+
+ if (node.nextSibling && node.nextSibling.nodeName.toLowerCase() === 'br') {
+ node.nextSibling.remove();
+ }
+
+ nextNode = node.nextSibling;
- var list = element.parentElement;
+ newNode = ownerDocument.createElement('p');
+ node.parentNode.replaceChild(newNode, node);
+ newNode.appendChild(node);
- if (list.parentElement.nodeName.toLowerCase() === 'p') { // yes we need to clean up
- Util.unwrap(list.parentElement, ownerDocument);
+ node = nextNode;
+ }
- // move cursor at the end of the text inside the list
- // for some unknown reason, the cursor is moved to end of the "visual" line
- MediumEditor.selection.moveCursor(ownerDocument, element.firstChild, element.firstChild.textContent.length);
+ // Restore selection
+ newRange.setStart(startContainer, startOffset);
+ newRange.setEnd(endContainer, endOffset);
+ selection.removeAllRanges();
+ selection.addRange(newRange);
+ } else {
+ var list = element.parentElement;
+
+ if (list.parentElement.nodeName.toLowerCase() === 'p') { // yes we need to clean up
+ Util.unwrap(list.parentElement, ownerDocument);
+
+ // move cursor at the end of the text inside the list
+ // for some unknown reason, the cursor is moved to end of the "visual" line
+ MediumEditor.selection.moveCursor(ownerDocument, element.firstChild, element.firstChild.textContent.length);
+ }
}
},