Improve algorithms some more
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Wed, 18 May 2011 14:30:57 -0600
changeset 147 027f0c99dcdd
parent 146 afbc714d572b
child 148 130b5d8ec146
Improve algorithms some more
autoimplementation.html
editcommands.html
implementation.js
source.html
--- a/autoimplementation.html	Wed May 18 14:14:44 2011 -0600
+++ b/autoimplementation.html	Wed May 18 14:30:57 2011 -0600
@@ -536,6 +536,10 @@
 		'<blockquote><p>foo[bar</p></blockquote><p>b]az</p><p>extra',
 		'<p>[foo]<blockquote><p>bar</blockquote><p>extra',
 		'<p>[foo<blockquote><p>b]ar</blockquote><p>extra',
+		'<p>foo<blockquote><p>bar</blockquote><p>[baz]<p>extra',
+		'<p>foo<blockquote><p>[bar</blockquote><p>baz]<p>extra',
+		'<p>[foo<blockquote><p>bar</blockquote><p>baz]<p>extra',
+		'<blockquote><p>foo</blockquote><p>[bar]<blockquote><p>baz</blockquote><p>extra',
 
 		// IE:
 		'<blockquote style="margin-right: 0" dir="ltr"><p>foo[bar]</p><p>baz</p></blockquote><p>extra',
@@ -544,6 +548,10 @@
 		'<blockquote style="margin-right: 0" dir="ltr"><p>foo[bar</p></blockquote><p>b]az</p><p>extra',
 		'<p>[foo]<blockquote style="margin-right: 0" dir="ltr"><p>bar</blockquote><p>extra',
 		'<p>[foo<blockquote style="margin-right: 0" dir="ltr"><p>b]ar</blockquote><p>extra',
+		'<p>foo<blockquote style="margin-right: 0" dir="ltr"><p>bar</blockquote><p>[baz]<p>extra',
+		'<p>foo<blockquote style="margin-right: 0" dir="ltr"><p>[bar</blockquote><p>baz]<p>extra',
+		'<p>[foo<blockquote style="margin-right: 0" dir="ltr"><p>bar</blockquote><p>baz]<p>extra',
+		'<blockquote style="margin-right: 0" dir="ltr"><p>foo</blockquote><p>[bar]<blockquote style="margin-right: 0" dir="ltr"><p>baz</blockquote><p>extra',
 
 		// Firefox CSS mode:
 		'<p style="margin-left: 40px">foo[bar]</p><p style="margin-left: 40px">baz</p><p>extra',
@@ -552,6 +560,10 @@
 		'<p style="margin-left: 40px">foo[bar</p><p>b]az</p><p>extra',
 		'<p>[foo]<p style="margin-left: 40px">bar<p>extra',
 		'<p>[foo<p style="margin-left: 40px">b]ar<p>extra',
+		'<p>foo<p style="margin-left: 40px">bar<p>[baz]<p>extra',
+		'<p>foo<p style="margin-left: 40px">[bar<p>baz]<p>extra',
+		'<p>[foo<p style="margin-left: 40px">bar<p>baz]<p>extra',
+		'<p style="margin-left: 40px">foo<p>[bar]<p style="margin-left: 40px">baz<p>extra',
 
 		// WebKit:
 		'<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo[bar]</p><p>baz</p></blockquote><p>extra',
@@ -560,6 +572,10 @@
 		'<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo[bar</p></blockquote><p>b]az</p><p>extra',
 		'<p>[foo]<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>bar</blockquote><p>extra',
 		'<p>[foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>b]ar</blockquote><p>extra',
+		'<p>foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>bar</blockquote><p>[baz]<p>extra',
+		'<p>foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>[bar</blockquote><p>baz]<p>extra',
+		'<p>[foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>bar</blockquote><p>baz]<p>extra',
+		'<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo</blockquote><p>[bar]<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>baz</blockquote><p>extra',
 
 		// MDC says "In Firefox, if the selection spans multiple lines at
 		// different levels of indentation, only the least indented lines in
@@ -668,6 +684,8 @@
 		'<ol><li>foo<li>[bar]<li>baz</ol>',
 		'<ol data-start=1 data-end=2><li>foo<li>bar<li>baz</ol>',
 		'<ol><li>foo</ol>[bar]',
+		'[foo]<ol><li>bar</ol>',
+		'<ol><li>foo</ol>[bar]<ol><li>baz</ol>',
 		'<ol><li>[foo]<br>bar<li>baz</ol>',
 		'<ol><li>foo<br>[bar]<li>baz</ol>',
 		'<ol><li><div>[foo]</div>bar<li>baz</ol>',
@@ -707,6 +725,8 @@
 		'<ul><li>foo<li>[bar]<li>baz</ul>',
 		'<ol data-start=1 data-end=2><li>foo<li>bar<li>baz</ul>',
 		'<ul><li>foo</ul>[bar]',
+		'[foo]<ul><li>bar</ul>',
+		'<ul><li>foo</ul>[bar]<ul><li>baz</ul>',
 		'<ul><li>[foo]<br>bar<li>baz</ul>',
 		'<ul><li>foo<br>[bar]<li>baz</ul>',
 		'<ul><li><div>[foo]</div>bar<li>baz</ul>',
@@ -727,6 +747,12 @@
 		'<ul><li>foo<ul><li>bar<li>baz</ul><li>[quz]</ul>',
 		'<ul><li>foo</li><ul><li>bar<li>baz</ul><li>[quz]</ul>',
 
+		// Mix of <ol> and <ul>
+		'foo<ol><li>bar</ol><ul><li>[baz]</ul>quz',
+		'foo<ol><li>bar</ol><ul><li>[baz</ul>quz]',
+		'foo<ul><li>[bar]</ul><ol><li>baz</ol>quz',
+		'[foo<ul><li>bar]</ul><ol><li>baz</ol>quz',
+
 		// Multiple items at once.
 		'<ul><li>foo<li>b[ar<li>baz]</ul>',
 		'<ul><li>[foo<ul><li>bar]</ul><li>baz</ul>',
--- a/editcommands.html	Wed May 18 14:14:44 2011 -0600
+++ b/editcommands.html	Wed May 18 14:30:57 2011 -0600
@@ -396,13 +396,26 @@
   reverse order</em>, insert <var title="">node</var> as the first <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="">new
   parent</var>, <a href=#preserving-ranges>preserving ranges</a>.
 
-  <li><a href=#remove-extraneous-line-breaks-from>Remove extraneous line breaks from</a> <var title="">new parent</var>.
-
   <li>If <var title="">original parent</var> is <a href=#editable>editable</a> and 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>, 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>.
   <!-- This could happen if the new parent instructions returned a node whose
   parent wasn't null. -->
 
+  <li>If <var title="">new parent</var>'s <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> is <a href=#editable>editable</a> and
+  meets the <a href=#sibling-criteria>sibling criteria</a>:
+  <!-- Probably because both the previous and next sibling met them.  We want
+  to merge them in this case. -->
+
+  <ol>
+    <li>While <var title="">new parent</var>'s <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> has <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>, append
+    its first <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> as the last <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="">new parent</var>,
+    <a href=#preserving-ranges>preserving ranges</a>.
+
+    <li>Remove <var title="">new parent</var>'s <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> 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>.
+  </ol>
+
+  <li><a href=#remove-extraneous-line-breaks-from>Remove extraneous line breaks from</a> <var title="">new parent</var>.
+
   <li>Return <var title="">new parent</var>.
 </ol>
 
@@ -2771,8 +2784,20 @@
     <li>If <var title="">node</var> is an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code>, <a href=#outdent>outdent</a> it and continue
     from the beginning of this loop.
 
-    <li>If <var title="">node</var> is a <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, <a href=#set-the-tag-name>set the tag name</a> of
-    <var title="">node</var> to "ol" and continue from the beginning of this loop.
+    <li>If <var title="">node</var> is a <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>:
+
+    <ol>
+      <li>Let <var title="">children</var> be the <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> of <var title="">node</var>.
+
+      <li>Remove <var title="">node</var>, <a href=#preserving-its-descendants>preserving its descendants</a>.
+
+      <li><a href=#wrap>Wrap</a> <var title="">children</var>, with <a href=#sibling-criteria>sibling
+      criteria</a> matching any <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> and <a href=#new-parent-instructions>new parent
+      instructions</a> returning the result of calling <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("ol")</a></code> on the
+      <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.
+
+      <li>Continue from the beginning of this loop.
+    </ol>
 
     <li>Let <var title="">original parent</var> be the <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> of <var title="">node</var>.
 
--- a/implementation.js	Wed May 18 14:14:44 2011 -0600
+++ b/implementation.js	Wed May 18 14:30:57 2011 -0600
@@ -556,15 +556,29 @@
 		}
 	}
 
-	// "Remove extraneous line breaks from new parent."
-	removeExtraneousLineBreaksFrom(newParent);
-
 	// "If original parent is editable and has no children, remove it from its
 	// parent."
 	if (isEditable(originalParent) && !originalParent.hasChildNodes()) {
 		originalParent.parentNode.removeChild(originalParent);
 	}
 
+	// "If new parent's nextSibling is editable and meets the sibling
+	// criteria:"
+	if (isEditable(newParent.nextSibling)
+	&& siblingCriteria(newParent.nextSibling)) {
+		// "While new parent's nextSibling has children, append its first child
+		// as the last child of new parent, preserving ranges."
+		while (newParent.nextSibling.hasChildNodes()) {
+			movePreservingRanges(newParent.nextSibling.firstChild, newParent, -1);
+		}
+
+		// "Remove new parent's nextSibling from its parent."
+		newParent.parentNode.removeChild(newParent.nextSibling);
+	}
+
+	// "Remove extraneous line breaks from new parent."
+	removeExtraneousLineBreaksFrom(newParent);
+
 	// "Return new parent."
 	return newParent;
 }
@@ -2642,10 +2656,22 @@
 				continue;
 			}
 
-			// "If node is a ul, set the tag name of node to "ol" and continue
-			// from the beginning of this loop."
+			// "If node is a ul:"
 			if (isHtmlElement(node, "UL")) {
-				setTagName(node, "ol");
+				// "Let children be the children of node."
+				var children = [].slice.call(node.childNodes);
+
+				// "Remove node, preserving its descendants."
+				removePreservingDescendants(node);
+
+				// "Wrap children, with sibling criteria matching any ol and
+				// new parent instructions returning the result of calling
+				// createElement("ol") on the context object."
+				wrap(children,
+					function(node) { return isHtmlElement(node, "OL") },
+					function() { return document.createElement("ol") });
+
+				// "Continue from the beginning of this loop."
 				continue;
 			}
 
--- a/source.html	Wed May 18 14:14:44 2011 -0600
+++ b/source.html	Wed May 18 14:30:57 2011 -0600
@@ -389,13 +389,26 @@
   reverse order</em>, insert <var>node</var> as the first [[child]] of <var>new
   parent</var>, <span>preserving ranges</span>.
 
-  <li><span>Remove extraneous line breaks from</span> <var>new parent</var>.
-
   <li>If <var>original parent</var> is <span>editable</span> and has no
   [[children]], remove it from its [[parent]].
   <!-- This could happen if the new parent instructions returned a node whose
   parent wasn't null. -->
 
+  <li>If <var>new parent</var>'s [[nextsibling]] is <span>editable</span> and
+  meets the <span>sibling criteria</span>:
+  <!-- Probably because both the previous and next sibling met them.  We want
+  to merge them in this case. -->
+
+  <ol>
+    <li>While <var>new parent</var>'s [[nextsibling]] has [[children]], append
+    its first [[child]] as the last [[child]] of <var>new parent</var>,
+    <span>preserving ranges</span>.
+
+    <li>Remove <var>new parent</var>'s [[nextsibling]] from its [[parent]].
+  </ol>
+
+  <li><span>Remove extraneous line breaks from</span> <var>new parent</var>.
+
   <li>Return <var>new parent</var>.
 </ol>
 
@@ -2810,8 +2823,22 @@
     <li>If <var>node</var> is an [[ol]], <span>outdent</span> it and continue
     from the beginning of this loop.
 
-    <li>If <var>node</var> is a [[ul]], <span>set the tag name</span> of
-    <var>node</var> to "ol" and continue from the beginning of this loop.
+    <li>If <var>node</var> is a [[ul]]:
+
+    <ol>
+      <li>Let <var>children</var> be the [[children]] of <var>node</var>.
+
+      <li>Remove <var>node</var>, <span>preserving its descendants</span>.
+
+      <li><span>Wrap</span> <var>children</var>, with <span>sibling
+      criteria</span> matching any [[ol]] and <span>new parent
+      instructions</span> returning the result of calling <code
+      data-anolis-spec=domcore
+      title=dom-Document-createElement>createElement("ol")</code> on the
+      [[contextobject]].
+
+      <li>Continue from the beginning of this loop.
+    </ol>
 
     <li>Let <var>original parent</var> be the [[parent]] of <var>node</var>.