Further refinement of delete
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 07 Jun 2011 11:31:08 -0600
changeset 241 caf93d645904
parent 240 00d6df816fc3
child 242 30cea2fff059
Further refinement of delete

This is a corner case, but it was pretty tricky to get right. I don't
quite agree with any browser, but it makes enough sense that I'm okay
sticking with it, given that it shouldn't come up much.
autoimplementation.html
editcommands.html
implementation.js
source.html
--- a/autoimplementation.html	Tue Jun 07 10:52:46 2011 -0600
+++ b/autoimplementation.html	Tue Jun 07 11:31:08 2011 -0600
@@ -367,6 +367,9 @@
 		'foo{<p>}bar</p>',
 		'foo[<p>]bar<br>baz</p>',
 		'foo[<p>]bar</p>baz',
+		'foo{<p>bar</p>}baz',
+		'foo<p>{bar</p>}baz',
+		'foo{<p>bar}</p>baz',
 		'<p>foo[</p>]bar',
 		'<p>foo{</p>}bar',
 		'<p>foo[</p>]bar<br>baz',
--- a/editcommands.html	Tue Jun 07 10:52:46 2011 -0600
+++ b/editcommands.html	Tue Jun 07 11:31:08 2011 -0600
@@ -1251,6 +1251,27 @@
     <li>Set the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> of <var title="">range</var> to
     (<var title="">start block</var>, <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <var title="">reference node</var>).
 
+    <li>If <var title="">end block</var> has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>:
+
+    <ol>
+      <li>While <var title="">end block</var> is <a href=#editable>editable</a> and is the only
+      <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> and is not a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">start
+      block</var>, let <var title="">parent</var> equal <var title="">end block</var>, then
+      remove <var title="">end block</var> from <var title="">parent</var>, then set <var title="">end
+      block</var> to <var title="">parent</var>.
+
+      <li>If <var title="">end block</var> is <a href=#editable>editable</a> and is not an
+      <a href=#inline-node>inline node</a>, and its <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> and <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code>
+      are both <a href=#inline-node title="inline node">inline nodes</a>, call
+      <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and insert it into
+      <var title="">end block</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> immediately after <var title="">end block</var>.
+
+      <li>If <var title="">end block</var> is <a href=#editable>editable</a>, remove it from its
+      <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+      <li>Abort these steps.
+    </ol>
+
     <li>If <var title="">end block</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-firstChild><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-firstchild>firstChild</a></code> is not an <a href=#inline-node>inline
     node</a>, abort these steps.
 
--- a/implementation.js	Tue Jun 07 10:52:46 2011 -0600
+++ b/implementation.js	Tue Jun 07 11:31:08 2011 -0600
@@ -1051,6 +1051,40 @@
 		range.setStart(startBlock, getNodeIndex(referenceNode));
 		range.setEnd(startBlock, getNodeIndex(referenceNode));
 
+		// "If end block has no children:"
+		if (!endBlock.hasChildNodes()) {
+			// "While end block is editable and is the only child of its parent
+			// and is not a child of start block, let parent equal end block,
+			// then remove end block from parent, then set end block to
+			// parent."
+			while (isEditable(endBlock)
+			&& endBlock.parentNode.childNodes.length == 1
+			&& endBlock.parentNode != startBlock) {
+				var parent_ = endBlock;
+				parent_.removeChild(endBlock);
+				endBlock = parent_;
+			}
+
+			// "If end block is editable and is not an inline node, and its
+			// previousSibling and nextSibling are both inline nodes, call
+			// createElement("br") on the context object and insert it into end
+			// block's parent immediately after end block."
+			if (isEditable(endBlock)
+			&& !isInlineNode(endBlock)
+			&& isInlineNode(endBlock.previousSibling)
+			&& isInlineNode(endBlock.nextSibling)) {
+				endBlock.parentNode.insertBefore(document.createElement("br"), endBlock.nextSibling);
+			}
+
+			// "If end block is editable, remove it from its parent."
+			if (isEditable(endBlock)) {
+				endBlock.parentNode.removeChild(endBlock);
+			}
+
+			// "Abort these steps."
+			return;
+		}
+
 		// "If end block's firstChild is not an inline node, abort these
 		// steps."
 		if (!isInlineNode(endBlock.firstChild)) {
--- a/source.html	Tue Jun 07 10:52:46 2011 -0600
+++ b/source.html	Tue Jun 07 11:31:08 2011 -0600
@@ -1208,6 +1208,27 @@
     <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
     (<var>start block</var>, [[index]] of <var>reference node</var>).
 
+    <li>If <var>end block</var> has no [[children]]:
+
+    <ol>
+      <li>While <var>end block</var> is <span>editable</span> and is the only
+      [[child]] of its [[parent]] and is not a [[child]] of <var>start
+      block</var>, let <var>parent</var> equal <var>end block</var>, then
+      remove <var>end block</var> from <var>parent</var>, then set <var>end
+      block</var> to <var>parent</var>.
+
+      <li>If <var>end block</var> is <span>editable</span> and is not an
+      <span>inline node</span>, and its [[previoussibling]] and [[nextsibling]]
+      are both <span title="inline node">inline nodes</span>, call
+      [[createelement|"br"]] on the [[contextobject]] and insert it into
+      <var>end block</var>'s [[parent]] immediately after <var>end block</var>.
+
+      <li>If <var>end block</var> is <span>editable</span>, remove it from its
+      [[parent]].
+
+      <li>Abort these steps.
+    </ol>
+
     <li>If <var>end block</var>'s [[firstchild]] is not an <span>inline
     node</span>, abort these steps.