Revamp insertOrderedList
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Wed, 18 May 2011 16:19:45 -0600
changeset 149 67046b930420
parent 148 130b5d8ec146
child 150 db7f8b7096f5
Revamp insertOrderedList

Now it better matches expected behavior on a bunch of tests. There's
one I'm still puzzling over, though
(<ul><li>foo</li><li>[bar</li><ul><li>baz</li></ul><li>quz]</li></ul>).
editcommands.html
implementation.js
source.html
--- a/editcommands.html	Wed May 18 15:01:29 2011 -0600
+++ b/editcommands.html	Wed May 18 16:19:45 2011 -0600
@@ -2774,15 +2774,52 @@
   child" is not well-defined, and it's not clear what the right definition
   should be.
 
-  <li>While <var title="">node list</var> is not empty:
+  <li>If every member of <var title="">node list</var> is either 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> or 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>child</a> of 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>, and no member of <var title="">node list</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> or
+  the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-ancestor title=concept-tree-ancestor>ancestor</a> of 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>, then while <var title="">node list</var> is not empty:
 
   <ol>
-    <li>Let <var title="">node</var> be the first member of <var title="">node list</var>.
-
-    <li>Remove <var title="">node</var> from <var title="">node list</var>.
-
-    <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>Let <var title="">sublist</var> be an empty list of <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a>.
+
+    <li>Remove the first member from <var title="">node list</var> and append it to
+    <var title="">sublist</var>.
+
+    <li>If the first member of <var title="">sublist</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 this loop from the beginning.
+
+    <li>While <var title="">node list</var> is not empty, and the first member of
+    <var title="">node list</var> is the <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> of the last member of
+    <var title="">sublist</var> and is not 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>, remove the first member from
+    <var title="">node list</var> and append it to <var title="">sublist</var>.
+
+    <li><a href=#split-the-parent>Split the parent</a> of <var title="">sublist</var>.
+
+    <li><a href=#fix-orphaned-list-items>Fix orphaned list items</a> in <var title="">sublist</var>.
+  </ol>
+
+  <li>Otherwise, while <var title="">node list</var> is not empty:
+
+  <ol>
+    <li>Let <var title="">sublist</var> be an empty list of <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a>.
+
+    <li>Remove the first member from <var title="">node list</var> and append it to
+    <var title="">sublist</var>.
+
+    <li>While <var title="">node list</var> is not empty, and the first member of
+    <var title="">node list</var> is the <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> of the last member of
+    <var title="">sublist</var>, and the last member of <var title="">sublist</var> and first
+    member of <var title="">node list</var> are both <a href=#inline-node title="inline node">inline
+    nodes</a>, and the last member of <var title="">sublist</var> is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>,
+    remove the first member from <var title="">node list</var> and append it to
+    <var title="">sublist</var>.
+
+    <li>If <var title="">sublist</var> contains more than one member, <a href=#wrap>wrap</a>
+    it, with <a href=#sibling-criteria>sibling criteria</a> matching nothing and with <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("li")</a></code> on the
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.  Let <var title="">node</var> be the result.
+
+    <li>Otherwise, let <var title="">node</var> be the sole member of
+    <var title="">sublist</var>.
 
     <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>:
 
@@ -2794,80 +2831,58 @@
       <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>.
+      <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.  Let <var title="">node</var> be the result.
+
+      <li>Prepend the <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 class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendants</a> of <var title="">node</var> (if any) to
+      <var title="">node list</var>.
 
       <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>.
-
-    <li>Let <var title="">sublist</var> be a list of <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a>, initially consisting of
-    <var title="">node</var>.
-
-    <li>If <var title="">original parent</var> is an <a href=#editable>editable</a> <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or
-    <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>:
-    <!-- Outdent -->
+    <li>If <var title="">node</var> is a <code class=external data-anolis-spec=html title="the p element"><a href=http://www.whatwg.org/html/#the-p-element>p</a></code> or <code class=external data-anolis-spec=html title="the div element"><a href=http://www.whatwg.org/html/#the-div-element>div</a></code>, <a href=#set-the-tag-name>set the tag name</a>
+    of <var title="">node</var> to "li", and let <var title="">node</var> be the result.
+
+    <li>If <var title="">node</var> is 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>child</a> of 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>While <var title="">node list</var> is not empty, and the first member of
-      <var title="">node list</var> is the <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> of the last member of
-      <var title="">sublist</var>, and the first member of <var title="">node list</var> is not
-      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> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, remove the first member from <var title="">node list</var>
-      and append it to <var title="">sublist</var>.
-
-      <li><a href=#split-the-parent>Split the parent</a> of <var title="">sublist</var>.
-
-      <li>If <var title="">original parent</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=#wrap>wrap</a>
-      <var title="">sublist</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 with <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
+      <li><a href=#split-the-parent>Split the parent</a> of the one-<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> list consisting of
+      <var title="">node</var>.
+
+      <li><a href=#wrap>Wrap</a> the one-<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> list consisting of
+      <var title="">node</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 with <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><a href=#fix-orphaned-list-items>Fix orphaned list items</a> in <var title="">sublist</var>.
+      <li>Prepend the <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 class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendants</a> of <var title="">node</var> (if any) to
+      <var title="">node list</var>.
 
       <li>Continue from the beginning of this loop.
     </ol>
 
-    <!-- General case.  Add an ol wrapper for each line.  <br> breaks apart
-    <li>'s, and multiple consecutive <br>s or trailing <br>s become empty
-    <li>s. -->
-
-    <li>If <var title="">node</var> is a <code class=external data-anolis-spec=html title="the p element"><a href=http://www.whatwg.org/html/#the-p-element>p</a></code> or <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> or <code class=external data-anolis-spec=html title="the div element"><a href=http://www.whatwg.org/html/#the-div-element>div</a></code>, <a href=#set-the-tag-name>set the tag
-    name</a> of <var title="">node</var> to "li", and let <var title="">li</var> be the
-    result.
-
-    <li>Otherwise:
-
-    <ol>
-      <li>While <var title="">node list</var> is not empty, and the first member of
-      <var title="">node list</var> is the <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> of the last member of
-      <var title="">sublist</var>, and the last member of <var title="">sublist</var> and first
-      member of <var title="">node list</var> are both <a href=#inline-node title="inline node">inline
-      nodes</a>, and the last member of <var title="">sublist</var> is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>,
-      remove the first member from <var title="">node list</var> and append it to
-      <var title="">sublist</var>.
-
-      <li><a href=#wrap>Wrap</a> <var title="">sublist</var>, with <a href=#sibling-criteria>sibling
-      criteria</a> matching nothing and with <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("li")</a></code> on the
-      <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.  Let <var title="">li</var> be the result.
-    </ol>
-
-    <li>If <var title="">li</var> is null, continue from the beginning of this loop.
-
-    <li><a href=#wrap>Wrap</a> the one-<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> list consisting of <var title="">li</var>,
+    <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> or 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>child</a> of 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>, prepend
+    the <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 class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendants</a> of <var title="">node</var> (if any) to <var title="">node
+    list</var> and continue from the beginning of this loop.
+
+    <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code>, <a href=#wrap>wrap</a> the one-<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a>
+    list consisting of <var title="">node</var>, with the <a href=#sibling-criteria>sibling criteria</a>
+    matching nothing, and the <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("li")</a></code> on the
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.  Let <var title="">node</var> be the result.
+
+    <li><a href=#wrap>Wrap</a> the one-<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> list consisting of <var title="">node</var>,
     with the <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 the
     <a href=#new-parent-instructions>new parent instructions</a> being the following:
 
     <ol>
-      <li>If <var title="">original parent</var> is not an <a href=#editable>editable</a>
-      <a href=#indentation-element>indentation element</a>, or the <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> of
-      <var title="">original parent</var> is not an <a href=#editable>editable</a> <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code>, 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("ol")</a></code> on the
+      <li>If 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> is not an <a href=#editable>editable</a>
+      <a href=#indentation-element>indentation element</a>, or the <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> of 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> is not an <a href=#editable>editable</a> <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code>,
+      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("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> and return the result.  Otherwise:
 
-      <li>Let <var title="">ol</var> be the <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> of <var title="">original
-      parent</var>.
+      <li>Let <var title="">ol</var> be the <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> of 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>.
 
       <li><a href=#normalize-sublists>Normalize sublists</a> of <var title="">ol</var>'s 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>.
 
--- a/implementation.js	Wed May 18 15:01:29 2011 -0600
+++ b/implementation.js	Wed May 18 16:19:45 2011 -0600
@@ -2643,85 +2643,53 @@
 			}
 		}
 
-		// "While node list is not empty:"
-		while (nodeList.length) {
-			// "Let node be the first member of node list."
-			// "Remove node from node list."
-			var node = nodeList.shift();
-
-			// "If node is an ol, outdent it and continue from the beginning of
-			// this loop."
-			if (isHtmlElement(node, "OL")) {
-				outdentNode(node);
-				continue;
-			}
-
-			// "If node is a ul:"
-			if (isHtmlElement(node, "UL")) {
-				// "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;
-			}
-
-			// "Let original parent be the parent of node."
-			var originalParent = node.parentNode;
-
-			// "Let sublist be a list of nodes, initially consisting of node."
-			var sublist = [node];
-
-			// "If original parent is an editable ol or ul:"
-			if (isHtmlElement(originalParent, ["OL", "UL"])
-			&& isEditable(originalParent)) {
+		// "If every member of node list is either an ol or the child of an ol,
+		// and no member of node list is a ul or the ancestor of a ul, then
+		// while node list is not empty:"
+		if (nodeList.every(function(node) { return isHtmlElement(node, "OL") || isHtmlElement(node.parentNode, "OL") })
+		&& !nodeList.some(function(node) { return isHtmlElement(node, "UL") || node.querySelector("ul") })) {
+			while (nodeList.length) {
+				// "Let sublist be an empty list of nodes."
+				var sublist = [];
+
+				// "Remove the first member from node list and append it to
+				// sublist."
+				sublist.push(nodeList.shift());
+
+				// "If the first member of sublist is an ol, outdent it and
+				// continue this loop from the beginning."
+				if (isHtmlElement(sublist[0], "OL")) {
+					outdentNode(sublist[0]);
+					continue;
+				}
+
 				// "While node list is not empty, and the first member of node
-				// list is the nextSibling of the last member of sublist, and
-				// the first member of node list is not an ol or ul, remove the
-				// first member from node list and append it to sublist."
+				// list is the nextSibling of the last member of sublist and is
+				// not an ol, remove the first member from node list and append
+				// it to sublist."
 				while (nodeList.length
 				&& nodeList[0] == sublist[sublist.length - 1].nextSibling
-				&& !isHtmlElement(nodeList[0], ["OL", "UL"])) {
+				&& !isHtmlElement(nodeList[0], "OL")) {
 					sublist.push(nodeList.shift());
 				}
 
 				// "Split the parent of sublist."
 				splitParent(sublist);
 
-				// "If original parent is a ul, wrap sublist, with sibling
-				// criteria matching any ol, and with new parent instructions
-				// returning the result of calling createElement("ol") on the
-				// context object."
-				if (isHtmlElement(originalParent, "UL")) {
-					wrap(sublist,
-						function(node) { return isHtmlElement(node, "OL") },
-						function() { return document.createElement("ol") });
-				}
-
 				// "Fix orphaned list items in sublist."
 				fixOrphanedListItems(sublist);
-
-				// "Continue from the beginning of this loop."
-				continue;
 			}
 
-			// "If node is a p or li or div, set the tag name of node to "li",
-			// and let li be the result."
-			var li;
-			if (isHtmlElement(node, ["P", "LI", "DIV"])) {
-				li = setTagName(node, "li");
-
-			// "Otherwise:"
-			} else {
+		// "Otherwise, while node list is not empty:"
+		} else {
+			while (nodeList.length) {
+				// "Let sublist be an empty list of nodes."
+				var sublist = [];
+
+				// "Remove the first member from node list and append it to
+				// sublist."
+				sublist.push(nodeList.shift());
+
 				// "While node list is not empty, and the first member of node
 				// list is the nextSibling of the last member of sublist, and
 				// the last member of sublist and first member of node list are
@@ -2736,54 +2704,131 @@
 					sublist.push(nodeList.shift());
 				}
 
-				// "Wrap sublist, with sibling criteria matching nothing and
-				// with new parent instructions returning the result of calling
-				// createElement("li") on the context object. Let li be the
+				// "If sublist contains more than one member, wrap it, with
+				// sibling criteria matching nothing and with new parent
+				// instructions returning the result of calling
+				// createElement("li") on the context object. Let node be the
 				// result."
-				li = wrap(sublist,
-					function(node) { return false },
-					function() { return document.createElement("li") });
-			}
-
-			// "If li is null, continue from the beginning of this loop."
-			if (!li) {
-				continue;
+				var node;
+				if (sublist.length > 1) {
+					node = wrap(sublist,
+						function() { return false },
+						function() { return document.createElement("li") });
+
+				// "Otherwise, let node be the sole member of sublist."
+				} else {
+					node = sublist[0];
+				}
+
+				// "If node is a ul:"
+				if (isHtmlElement(node, "UL")) {
+					// "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. Let
+					// node be the result."
+					node = wrap(children,
+						function(node) { return isHtmlElement(node, "OL") },
+						function() { return document.createElement("ol") });
+
+					// "Prepend the ul descendants of node (if any) to node
+					// list."
+					nodeList = [].slice.call(node.querySelectorAll("ul")).concat(nodeList);
+
+					// "Continue from the beginning of this loop."
+					continue;
+				}
+
+				// "If node is a p or div, set the tag name of node to "li",
+				// and let node be the result."
+				if (isHtmlElement(node, ["P", "DIV"])) {
+					node = setTagName(node, "li");
+				}
+
+				// "If node is the child of a ul:"
+				if (isHtmlElement(node.parentNode, "UL")) {
+					// "Split the parent of the one-node list consisting of
+					// node."
+					splitParent([node]);
+
+					// "Wrap the one-node list consisting of node, with sibling
+					// criteria matching any ol, and with new parent
+					// instructions returning the result of calling
+					// createElement("ol") on the context object."
+					wrap([node],
+						function(node) { return isHtmlElement(node, "OL") },
+						function() { return document.createElement("ol") });
+
+					// "Prepend the ul descendants of node (if any) to node
+					// list."
+					nodeList = [].slice.call(node.querySelectorAll("ul")).concat(nodeList);
+
+					// "Continue from the beginning of this loop."
+					continue;
+				}
+
+				// "If node is an ol or the child of an ol, prepend the
+				// ul descendants of node (if any) to node list and continue
+				// from the beginning of this loop."
+				if (isHtmlElement(node, "OL")
+				|| isHtmlElement(node.parentNode, "OL")) {
+					nodeList = [].slice.call(node.querySelectorAll("ul")).concat(nodeList);
+					continue;
+				}
+
+				// "If node is not an li, wrap the one-node list consisting of
+				// node, with the sibling criteria matching nothing, and the
+				// new parent instructions returning the result of calling
+				// createElement("li") on the context object. Let node be the
+				// result."
+				if (!isHtmlElement(node, "LI")) {
+					node = wrap([node],
+						function() { return false },
+						function() { return document.createElement("li") });
+				}
+
+				// "Wrap the one-node list consisting of node, with the sibling
+				// criteria matching any ol, and the new parent instructions
+				// being the following:"
+				wrap([node],
+					function(node) { return isHtmlElement(node, "OL") },
+					function() {
+						// "If the parent of node is not an editable
+						// indentation element, or the previousSibling of the
+						// parent of node is not an editable ol, call
+						// createElement("ol") on the context object and return
+						// the result. Otherwise:"
+						if (!isEditable(node.parentNode)
+						|| !isIndentationElement(node.parentNode)
+						|| !isEditable(node.parentNode.previousSibling)
+						|| !isHtmlElement(node.parentNode.previousSibling, "OL")) {
+							return document.createElement("ol");
+						}
+
+						// "Let ol be the previousSibling of the parent of
+						// node."
+						var ol = node.parentNode.previousSibling;
+
+						// "Normalize sublists of ol's last child."
+						normalizeSublists(ol.lastChild);
+
+						// "If ol's last child is not an editable ol, call
+						// createElement("ol") on the context object, and
+						// append the result as the last child of ol."
+						if (!isEditable(ol.lastChild)
+						|| !isHtmlElement(ol.lastChild, "OL")) {
+							ol.appendChild(document.createElement("ol"));
+						}
+
+						// "Return the last child of ol."
+						return ol.lastChild;
+					});
 			}
-
-			// "Wrap the one-node list consisting of li, with the sibling
-			// criteria matching any ol, and the new parent instructions being
-			// the following:"
-			wrap([li],
-				function(node) { return isHtmlElement(node, "OL") },
-				function() {
-					// "If original parent is not an editable indentation
-					// element, or the previousSibling of original parent is
-					// not an editable ol, call createElement("ol") on the
-					// context object and return the result. Otherwise:"
-					if (!isEditable(originalParent)
-					|| !isIndentationElement(originalParent)
-					|| !isEditable(originalParent.previousSibling)
-					|| !isHtmlElement(originalParent.previousSibling, "OL")) {
-						return document.createElement("ol");
-					}
-
-					// "Let ol be the previousSibling of original parent."
-					var ol = originalParent.previousSibling;
-
-					// "Normalize sublists of ol's last child."
-					normalizeSublists(ol.lastChild);
-
-					// "If ol's last child is not an editable ol, call
-					// createElement("ol") on the context object, and append
-					// the result as the last child of ol."
-					if (!isEditable(ol.lastChild)
-					|| !isHtmlElement(ol.lastChild, "OL")) {
-						ol.appendChild(document.createElement("ol"));
-					}
-
-					// "Return the last child of ol."
-					return ol.lastChild;
-				});
 		}
 		break;
 
--- a/source.html	Wed May 18 15:01:29 2011 -0600
+++ b/source.html	Wed May 18 16:19:45 2011 -0600
@@ -2813,15 +2813,54 @@
   child" is not well-defined, and it's not clear what the right definition
   should be.
 
-  <li>While <var>node list</var> is not empty:
+  <li>If every member of <var>node list</var> is either an [[ol]] or the
+  [[child]] of an [[ol]], and no member of <var>node list</var> is a [[ul]] or
+  the [[ancestor]] of a [[ul]], then while <var>node list</var> is not empty:
 
   <ol>
-    <li>Let <var>node</var> be the first member of <var>node list</var>.
-
-    <li>Remove <var>node</var> from <var>node list</var>.
-
-    <li>If <var>node</var> is an [[ol]], <span>outdent</span> it and continue
-    from the beginning of this loop.
+    <li>Let <var>sublist</var> be an empty list of [[nodes]].
+
+    <li>Remove the first member from <var>node list</var> and append it to
+    <var>sublist</var>.
+
+    <li>If the first member of <var>sublist</var> is an [[ol]],
+    <span>outdent</span> it and continue this loop from the beginning.
+
+    <li>While <var>node list</var> is not empty, and the first member of
+    <var>node list</var> is the [[nextsibling]] of the last member of
+    <var>sublist</var> and is not an [[ol]], remove the first member from
+    <var>node list</var> and append it to <var>sublist</var>.
+
+    <li><span>Split the parent</span> of <var>sublist</var>.
+
+    <li><span>Fix orphaned list items</span> in <var>sublist</var>.
+  </ol>
+
+  <li>Otherwise, while <var>node list</var> is not empty:
+
+  <ol>
+    <li>Let <var>sublist</var> be an empty list of [[nodes]].
+
+    <li>Remove the first member from <var>node list</var> and append it to
+    <var>sublist</var>.
+
+    <li>While <var>node list</var> is not empty, and the first member of
+    <var>node list</var> is the [[nextsibling]] of the last member of
+    <var>sublist</var>, and the last member of <var>sublist</var> and first
+    member of <var>node list</var> are both <span title="inline node">inline
+    nodes</span>, and the last member of <var>sublist</var> is not a [[br]],
+    remove the first member from <var>node list</var> and append it to
+    <var>sublist</var>.
+
+    <li>If <var>sublist</var> contains more than one member, <span>wrap</span>
+    it, with <span>sibling criteria</span> matching nothing and with <span>new
+    parent instructions</span> returning the result of calling <code
+    data-anolis-spec=domcore
+    title=dom-Document-createElement>createElement("li")</code> on the
+    [[contextobject]].  Let <var>node</var> be the result.
+
+    <li>Otherwise, let <var>node</var> be the sole member of
+    <var>sublist</var>.
 
     <li>If <var>node</var> is a [[ul]]:
 
@@ -2835,84 +2874,61 @@
       instructions</span> returning the result of calling <code
       data-anolis-spec=domcore
       title=dom-Document-createElement>createElement("ol")</code> on the
-      [[contextobject]].
+      [[contextobject]].  Let <var>node</var> be the result.
+
+      <li>Prepend the [[ul]] [[descendants]] of <var>node</var> (if any) to
+      <var>node list</var>.
 
       <li>Continue from the beginning of this loop.
     </ol>
 
-    <li>Let <var>original parent</var> be the [[parent]] of <var>node</var>.
-
-    <li>Let <var>sublist</var> be a list of [[nodes]], initially consisting of
-    <var>node</var>.
-
-    <li>If <var>original parent</var> is an <span>editable</span> [[ol]] or
-    [[ul]]:
-    <!-- Outdent -->
+    <li>If <var>node</var> is a [[p]] or [[div]], <span>set the tag name</span>
+    of <var>node</var> to "li", and let <var>node</var> be the result.
+
+    <li>If <var>node</var> is the [[child]] of a [[ul]]:
 
     <ol>
-      <li>While <var>node list</var> is not empty, and the first member of
-      <var>node list</var> is the [[nextsibling]] of the last member of
-      <var>sublist</var>, and the first member of <var>node list</var> is not
-      an [[ol]] or [[ul]], remove the first member from <var>node list</var>
-      and append it to <var>sublist</var>.
-
-      <li><span>Split the parent</span> of <var>sublist</var>.
-
-      <li>If <var>original parent</var> is a [[ul]], <span>wrap</span>
-      <var>sublist</var>, with <span>sibling criteria</span> matching any
-      [[ol]], and with <span>new parent instructions</span> returning the
-      result of calling <code data-anolis-spec=domcore
+      <li><span>Split the parent</span> of the one-[[node]] list consisting of
+      <var>node</var>.
+
+      <li><span>Wrap</span> the one-[[node]] list consisting of
+      <var>node</var>, with <span>sibling criteria</span> matching any [[ol]],
+      and with <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><span>Fix orphaned list items</span> in <var>sublist</var>.
+      <li>Prepend the [[ul]] [[descendants]] of <var>node</var> (if any) to
+      <var>node list</var>.
 
       <li>Continue from the beginning of this loop.
     </ol>
 
-    <!-- General case.  Add an ol wrapper for each line.  <br> breaks apart
-    <li>'s, and multiple consecutive <br>s or trailing <br>s become empty
-    <li>s. -->
-
-    <li>If <var>node</var> is a [[p]] or [[li]] or [[div]], <span>set the tag
-    name</span> of <var>node</var> to "li", and let <var>li</var> be the
-    result.
-
-    <li>Otherwise:
-
-    <ol>
-      <li>While <var>node list</var> is not empty, and the first member of
-      <var>node list</var> is the [[nextsibling]] of the last member of
-      <var>sublist</var>, and the last member of <var>sublist</var> and first
-      member of <var>node list</var> are both <span title="inline node">inline
-      nodes</span>, and the last member of <var>sublist</var> is not a [[br]],
-      remove the first member from <var>node list</var> and append it to
-      <var>sublist</var>.
-
-      <li><span>Wrap</span> <var>sublist</var>, with <span>sibling
-      criteria</span> matching nothing and with <span>new parent
-      instructions</span> returning the result of calling <code
-      data-anolis-spec=domcore
-      title=dom-Document-createElement>createElement("li")</code> on the
-      [[contextobject]].  Let <var>li</var> be the result.
-    </ol>
-
-    <li>If <var>li</var> is null, continue from the beginning of this loop.
-
-    <li><span>Wrap</span> the one-[[node]] list consisting of <var>li</var>,
+    <li>If <var>node</var> is an [[ol]] or the [[child]] of an [[ol]], prepend
+    the [[ul]] [[descendants]] of <var>node</var> (if any) to <var>node
+    list</var> and continue from the beginning of this loop.
+
+    <li>If <var>node</var> is not an [[li]], <span>wrap</span> the one-[[node]]
+    list consisting of <var>node</var>, with the <span>sibling criteria</span>
+    matching nothing, and the <span>new parent instructions</span> returning
+    the result of calling <code data-anolis-spec=domcore
+    title=dom-Document-createElement>createElement("li")</code> on the
+    [[contextobject]].  Let <var>node</var> be the result.
+
+    <li><span>Wrap</span> the one-[[node]] list consisting of <var>node</var>,
     with the <span>sibling criteria</span> matching any [[ol]], and the
     <span>new parent instructions</span> being the following:
 
     <ol>
-      <li>If <var>original parent</var> is not an <span>editable</span>
-      <span>indentation element</span>, or the [[previoussibling]] of
-      <var>original parent</var> is not an <span>editable</span> [[ol]], call
-      <code data-anolis-spec=domcore
+      <li>If the [[parent]] of <var>node</var> is not an <span>editable</span>
+      <span>indentation element</span>, or the [[previoussibling]] of the
+      [[parent]] of <var>node</var> is not an <span>editable</span> [[ol]],
+      call <code data-anolis-spec=domcore
       title=dom-Document-createElement>createElement("ol")</code> on the
       [[contextobject]] and return the result.  Otherwise:
 
-      <li>Let <var>ol</var> be the [[previoussibling]] of <var>original
-      parent</var>.
+      <li>Let <var>ol</var> be the [[previoussibling]] of the [[parent]] of
+      <var>node</var>.
 
       <li><span>Normalize sublists</span> of <var>ol</var>'s last [[child]].