diff --git a/bower.json b/bower.json index bb10fc8a..788ba7f3 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,8 @@ { "name": "scribe", "dependencies": { - "lodash-amd": "2.4.1" + "lodash-amd": "2.4.1", + "scribe-common": "0.0.4" }, "devDependencies": { "requirejs": "~2.1.9", diff --git a/src/dom-observer.js b/src/dom-observer.js index 95eebbb9..a3d38f18 100644 --- a/src/dom-observer.js +++ b/src/dom-observer.js @@ -1,20 +1,16 @@ define([ 'lodash-amd/modern/arrays/flatten', - 'lodash-amd/modern/collections/toArray' + 'lodash-amd/modern/collections/toArray', + 'scribe-common/element', + 'scribe-common/node' ], function ( flatten, - toArray + toArray, + elementHelpers, + nodeHelpers ) { function observeDomChanges(el, callback) { - function notEmptyTextNode(node) { - return ! (node.nodeType === Node.TEXT_NODE && node.textContent === ''); - } - - function notSelectionMarkerNode(node) { - return ! (node.nodeType === Node.ELEMENT_NODE && node.className === 'scribe-marker'); - } - function includeRealMutations(mutations) { var allChangedNodes = flatten(mutations.map(function(mutation) { var added = toArray(mutation.addedNodes); @@ -23,13 +19,12 @@ define([ })); var realChangedNodes = allChangedNodes. - filter(notEmptyTextNode). - filter(notSelectionMarkerNode); + filter(function(n) { return ! nodeHelpers.isEmptyTextNode(n); }). + filter(function(n) { return ! elementHelpers.isSelectionMarkerNode(n); }); return realChangedNodes.length > 0; } - // Flag to avoid running recursively var runningPostMutation = false; var observer = new MutationObserver(function(mutations) { diff --git a/src/plugins/core/patches/commands/insert-list.js b/src/plugins/core/patches/commands/insert-list.js index 18a72b5e..d6ce0f97 100644 --- a/src/plugins/core/patches/commands/insert-list.js +++ b/src/plugins/core/patches/commands/insert-list.js @@ -1,4 +1,5 @@ -define(['../../../../api/element'], function (element) { +define(['../../../../api/element', + 'scribe-common/node'], function (element, nodeHelpers) { 'use strict'; @@ -31,7 +32,7 @@ define(['../../../../api/element'], function (element) { if (listElement.nextElementSibling && listElement.nextElementSibling.childNodes.length === 0) { - listElement.parentNode.removeChild(listElement.nextElementSibling); + nodeHelpers.removeNode(listElement.nextElementSibling); } /** @@ -46,13 +47,20 @@ define(['../../../../api/element'], function (element) { if (listParentNode && /^(H[1-6]|P)$/.test(listParentNode.nodeName)) { selection.placeMarkers(); // Move listElement out of the block - listParentNode.parentNode.insertBefore(listElement, listParentNode.nextElementSibling); + nodeHelpers.insertAfter(listElement, listParentNode); selection.selectMarkers(); + + /** + * Chrome 27-34: An empty text node is inserted. + */ + if (listParentNode.childNodes.length === 2 && + nodeHelpers.isEmptyTextNode(listParentNode.firstChild)) { + nodeHelpers.removeNode(listParentNode); + } + // Remove the block if it's empty - if (listParentNode.childNodes.length === 0 - || (listParentNode.childNodes.length === 1 && listParentNode.firstChild.nodeName === 'BR') - || (listParentNode.firstChild.nodeType === Node.TEXT_NODE && listParentNode.firstChild.textContent === '')) { - listParentNode.parentNode.removeChild(listParentNode); + if (listParentNode.childNodes.length === 0) { + nodeHelpers.removeNode(listParentNode); } } }