Adjust insertOrderedList behavior a bunch
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 10 May 2011 14:13:28 -0600
changeset 102 babf18ca1062
parent 101 95523848c7f8
child 103 4dd2566c6c51
Adjust insertOrderedList behavior a bunch

Still lots of changes to come.
autoimplementation.html
editcommands.html
implementation.js
source.html
--- a/autoimplementation.html	Tue May 10 12:58:59 2011 -0600
+++ b/autoimplementation.html	Tue May 10 14:13:28 2011 -0600
@@ -717,6 +717,44 @@
 		'<ul><li>foo<ul><li>[bar]</ul>baz</ul>',
 		'<ul><li>foo<ul><li>bar</ul>[baz]</ul>',
 		'<ul><li>[foo<ul><li>bar]</ul>baz</ul>',
+
+		// Interaction with indentation
+		'[foo]<blockquote>bar</blockquote>baz',
+		'foo<blockquote>[bar]</blockquote>baz',
+		'[foo<blockquote>bar]</blockquote>baz',
+		'<ol><li>foo</ol><blockquote>[bar]</blockquote>baz',
+		'[foo]<blockquote><ol><li>bar</ol></blockquote>baz',
+		'foo<blockquote>[bar]<br>baz</blockquote>',
+		'[foo<blockquote>bar]<br>baz</blockquote>',
+		'<ol><li>foo</ol><blockquote>[bar]<br>baz</blockquote>',
+
+		'<p>[foo]<blockquote><p>bar</blockquote><p>baz',
+		'<p>foo<blockquote><p>[bar]</blockquote><p>baz',
+		'<p>[foo<blockquote><p>bar]</blockquote><p>baz',
+		'<ol><li>foo</ol><blockquote><p>[bar]</blockquote><p>baz',
+		'<p>[foo]<blockquote><ol><li><p>bar</ol></blockquote><p>baz',
+		'<p>foo<blockquote><p>[bar]<p>baz</blockquote>',
+		'<p>[foo<blockquote><p>bar]<p>baz</blockquote>',
+		'<ol><li>foo</ol><blockquote><p>[bar]<p>baz</blockquote>',
+
+		'[foo]<div style="margin: 0 40px">bar</div>baz',
+		'foo<div style="margin: 0 40px">[bar]</div>baz',
+		'[foo<div style="margin: 0 40px">bar]</div>baz',
+		'<ol><li>foo</ol><div style="margin: 0 40px">[bar]</div>baz',
+		'[foo]<div style="margin: 0 40px"><ol><li>bar</ol></div>baz',
+		'foo<div style="margin: 0 40px">[bar]<br>baz</div>',
+		'[foo<div style="margin: 0 40px">bar]<br>baz</div>',
+		'<ol><li>foo</ol><div style="margin: 0 40px">[bar]<br>baz</div>',
+
+		'<p>[foo]<div style="margin: 0 40px"><p>bar</div><p>baz',
+		'<p>foo<div style="margin: 0 40px"><p>[bar]</div><p>baz',
+		'<p>[foo<div style="margin: 0 40px"><p>bar]</div><p>baz',
+		'<ol><li>foo</ol><div style="margin: 0 40px"><p>[bar]</div><p>baz',
+		'<p>[foo]<div style="margin: 0 40px"><ol><li><p>bar</ol></div><p>baz',
+		'<p>foo<div style="margin: 0 40px"><p>[bar]<p>baz</div>',
+		'<p>[foo<div style="margin: 0 40px"><p>bar]<p>baz</div>',
+		'<ol><li>foo</ol><div style="margin: 0 40px"><p>[bar]<p>baz</div>',
+
 	],
 	insertunorderedlist: [
 	],
--- a/editcommands.html	Tue May 10 12:58:59 2011 -0600
+++ b/editcommands.html	Tue May 10 14:13:28 2011 -0600
@@ -27,7 +27,7 @@
 <body class=draft>
 <div class=head id=head>
 <h1>HTML Editing Commands</h1>
-<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-9-may-2011>Work in Progress &mdash; Last Update 9 May 2011</h2>
+<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-10-may-2011>Work in Progress &mdash; Last Update 10 May 2011</h2>
 <dl>
  <dt>Editor
  <dd>Aryeh Gregor &lt;ayg+spec@aryeh.name&gt;
@@ -2498,6 +2498,62 @@
   * Does not appear to be possible in Word or OO.
   * Also might be impossible to actually make such a list using execCommand() in browsers.
   * Suffice it to say that there's a lot of variation.
+* In an existing indented region equivalent to foo<blockquote>bar</blockquote>baz:
+  * Select "bar", do "ol":
+    * Word/OO/Firefox/Chrome: Increase indent, add "1".
+    * IE: Increase indent, add "a".
+    * Opera: Add "1" (but do not increase indent).
+  * Select "foobar", do "ol":
+    * Word/IE: Increase indent of both, add "1" before "foo" and "a" before
+      "bar".
+    * OO: Increase indent of "bar" one step, increase indent of "foo" two steps
+      so it's aligned with "bar", add "1" before "foo" and "2" before "bar".
+    * Firefox: Increase indent of both, add "1" before foo", add "2" before
+      "bar" aligned with the "1" of "foo" (so large gap between "2" and "bar").
+    * Chrome: Increase indent of "foo", add "1" before "foo" and "2" before
+      "bar".
+    * Opera: Mash everything together on one line.  But if you do
+      <p>foo</p><blockquote>bar</blockquote><p>baz</p> instead, same as Chrome.
+  * Select "foo" and do "ol", then select "bar" and do "ol":
+    * Word/OO/Firefox/Opera: Different than doing both at once (often in
+      exciting ways).
+    * IE/Chrome: Same as doing both at once.
+* In an existing multi-line indented region equivalent to <blockquote>foo<br>bar<br>baz</blockquote>:
+  * Select "bar", do "ol":
+    * Word/OO/Firefox/Chrome: Increase indent, add "1".
+    * IE: Increase indent of everything, add "a" before "foo".  If you do
+      <blockquote><p>foo<p>bar<p>baz</blockquote>, same as
+      Word/OO/Firefox/Chrome.
+    * Opera: Don't increase indent of anything, add "1" before "bar".
+* In an existing multi-line indented region equivalent to <blockquote>foo<br>bar</blockquote>baz:
+  * Select "barbaz", do "ol":
+    * Word: Indent both, add "a" before "bar" and "2" before "baz".
+    * OO: Indent "baz", add "1" before "bar" and "2" before "baz".
+    * IE: Indent everything, add "a" before "foo" and "1" before "baz".  If you
+      do <blockquote><p>foo<p>bar</blockquote><p>baz, indent "bar" and "baz"
+      and put "1" before each.
+    * Firefox: Indent "bar" and put "1" before it, put "baz" after "bar" on the
+      same line.  If you do <blockquote><p>foo<p>bar</blockquote><p>baz, same
+      as Chrome.
+    * Chrome: Indent "bar" once and "baz" twice, put "1" before "bar" and "2"
+      before "baz".
+    * Opera: Put a "1" before "bar" and move "baz" to the same line.  If you do
+      <blockquote><p>foo<p>bar</blockquote><p>baz, indent "baz", put a "1"
+      before "bar" and a "2" before "baz".
+  * Select "bar", do "ol", then select "baz" and do "ol":
+    * Word/OO/Opera: Different from if you do both together.
+    * IE: Different with <br>, same with <p>.
+    * Firefox: Three behaviors, depending on whether you do it in one step with
+      <br>, one step with <p>, or two steps with either (same behavior
+      regardless with two steps).
+    * Chrome: Same behavior in all four cases.
+* <blockquote>foo<ol><li>bar</ol></blockquote>baz:
+  * Select "baz", do "ol":
+    * Word/OO/Chrome: Add "baz" as a new item to existing list.
+    * IE/Firefox/Opera: Make "baz" its own new list.
+* <ul><li>foo</li><ol><li>bar</li></ol></ul>baz:
+  * Select "baz", do "ol":
+    * IE/Firefox/Chrome/Opera: Separate list.
 
 Ignoring the conceptual model of HTML, which users won't understand, here's the
 conceptual model I've developed for lists: text is divided up into blocks.
@@ -2592,7 +2648,8 @@
 
   <li>For each <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> <var title="">node</var> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in <var title="">new range</var>,
   if <var title="">node</var> is <a href=#editable>editable</a>; the last member of <var title="">node
-  list</var> (if any) is not an <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 <var title="">node</var>; and
+  list</var> (if any) is not an <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 <var title="">node</var>;
+  <var title="">node</var> is not a <a href=#potential-indentation-element>potential indentation element</a>; and
   either <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 <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 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> 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 <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 it can 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>child</a> of 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>; then append
   <var title="">node</var> to <var title="">node list</var>.
@@ -2689,6 +2746,20 @@
     <li>s. -->
 
     <ol>
+      <li>Let <var title="">extra indentation</var> equal 0.
+
+      <li>Let <var title="">ancestor</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 the first member of
+      <var title="">sublist</var>.
+
+      <li>While <var title="">ancestor</var> is an <a href=#editable>editable</a> <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>:
+
+      <ol>
+        <li>If <var title="">ancestor</var> is a <a href=#potential-indentation-element>potential indentation
+        element</a>, increment <var title="">extra indentation</var>.
+
+        <li>Set <var title="">ancestor</var> to 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>If the first member of <var title="">sublist</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 the first member of
       <var title="">sublist</var> to "li", and let <var title="">li</var> be the result.  Remove
@@ -2709,6 +2780,10 @@
         <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of the first member of <var title="">sublist</var>.
       </ol>
 
+      <li>Repeat the following a number of times equal to <var title="">extra
+      indentation</var>: for each <var title="">node</var> in <var title="">sublist</var>,
+      <a href=#outdent>outdent</a> <var title="">node</var>.
+
       <li>If 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> 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>:
 
@@ -2750,6 +2825,10 @@
       </ol>
     </ol>
 
+    <li>Repeat the following a number of times equal to <var title="">extra
+    indentation</var>: <a href=#indent>indent</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 containing
+    <var title="">li</var>.
+
     <li>If the first member of <var title="">node list</var> is 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 of <var title="">node list</var> 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>, then remove it
     from <var title="">node list</var>.
@@ -2915,17 +2994,25 @@
   <li>If <var title="">node</var> is an <a href=#indentation-element>indentation element</a>:
 
   <ol>
-    <li>If <var title="">node</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> 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> or 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> and
-    <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> are both <a href=#inline-node title="inline node">inline
-    nodes</a>, unset all attributes of <var title="">node</var>, then <a href=#set-the-tag-name>set the
-    tag name</a> of <var title="">node</var> to "div".
-    <!-- In this case, removing it entirely will result in its first or last
-    child becoming part of the previous or next sibling's line box, so we
-    want to keep a div. -->
-
-    <li>Otherwise, remove <var title="">node</var>, <a href=#preserving-its-descendants>preserving its
-    descendants</a>.
+    <li>If <var title="">node</var>'s <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 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> are both
+    <a href=#inline-node title="inline node">inline nodes</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>
+    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>, then 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
+    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, and insert the result into
+    <var title="">node</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 before <var title="">node</var>.
+
+    <li>If <var title="">node</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> 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>, and its 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> 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>, then 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
+    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, and insert the result into
+    <var title="">node</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="">node</var>.
+
+    <!-- Just to be pedantic . . . it could happen! -->
+    <li>If <var title="">node</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>, 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>, 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> 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>, then 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
+    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, and insert the result into
+    <var title="">node</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 before <var title="">node</var>.
+
+    <li>Remove <var title="">node</var>, <a href=#preserving-its-descendants>preserving its descendants</a>.
 
     <li>Abort these steps.
   </ol>
--- a/implementation.js	Tue May 10 12:58:59 2011 -0600
+++ b/implementation.js	Tue May 10 14:13:28 2011 -0600
@@ -2504,9 +2504,10 @@
 		var nodeList = [];
 
 		// "For each node node contained in new range, if node is editable; the
-		// last member of node list (if any) is not an ancestor of node; and
-		// either node is an ol or ul, or its parent is an ol or ul, or it can
-		// be the child of an li; then append node to node list."
+		// last member of node list (if any) is not an ancestor of node; node
+		// is not a potential indentation element; and either node is an ol or
+		// ul, or its parent is an ol or ul, or it can be the child of an li;
+		// then append node to node list."
 		for (
 			var node = newRange.startContainer;
 			node != nextNodeDescendants(newRange.endContainer);
@@ -2515,6 +2516,7 @@
 			if (isEditable(node)
 			&& isContained(node, newRange)
 			&& (!nodeList.length || !isAncestor(nodeList[nodeList.length - 1], node))
+			&& !isPotentialIndentationElement(node)
 			&& (isHtmlElement(node, "OL")
 			|| isHtmlElement(node, "UL")
 			|| isHtmlElement(node.parentNode, "OL")
@@ -2632,6 +2634,27 @@
 				}
 			// "Otherwise:"
 			} else {
+				// "Let extra indentation equal 0."
+				var extraIndentation = 0;
+
+				// "Let ancestor be the parent of the first member of
+				// sublist."
+				var ancestor = sublist[0].parentNode;
+
+				// "While ancestor is an editable Element:"
+				while (ancestor
+				&& isEditable(ancestor)
+				&& ancestor.nodeType == Node.ELEMENT_NODE) {
+					// "If ancestor is a potential indentation element,
+					// increment extra indentation."
+					if (isPotentialIndentationElement(ancestor)) {
+						extraIndentation++;
+					}
+
+					// "Set ancestor to its parent."
+					var ancestor = ancestor.parentNode;
+				}
+
 				// "If the first member of sublist is a p or li or div, set the
 				// tag name of the first member of sublist to "li", and let li
 				// be the result.  Remove the first member of sublist, and
@@ -2665,6 +2688,14 @@
 					var li = sublist[0].ownerDocument.createElement("li");
 				}
 
+				// "Repeat the following a number of times equal to extra
+				// indentation: for each node in sublist, outdent node."
+				for (var i = 0; i < extraIndentation; i++) {
+					for (var j = 0; j < sublist.length; j++) {
+						outdentNode(sublist[j]);
+					}
+				}
+
 				// "If the nextSibling of the last member of sublist is an ol:"
 				if (isHtmlElement(sublist[sublist.length - 1].nextSibling, "OL")) {
 					// "Insert li as the first child of the nextSibling of the
@@ -2717,6 +2748,12 @@
 				}
 			}
 
+			// "Repeat the following a number of times equal to extra
+			// indentation: indent the one-node list containing li."
+			for (var i = 0; i < extraIndentation; i++) {
+				indentNodes([li]);
+			}
+
 			// "If the first member of node list is a br, remove the first
 			// member of node list from its parent, then remove it from node
 			// list."
@@ -3193,22 +3230,40 @@
 
 	// "If node is an indentation element:"
 	if (isIndentationElement(node)) {
-		// "If node's last child and nextSibling are both inline nodes or its
-		// first child and previousSibling are both inline nodes, unset all
-		// attributes of node, then set the tag name of node to "div"."
-		if ((isInlineNode(node.lastChild) && isInlineNode(node.nextSibling))
-		|| (isInlineNode(node.firstChild) && isInlineNode(node.previousSibling))) {
-			while (node.attributes.length) {
-				node.removeAttribute(node.attributes[0].name);
-			}
-
-			setTagName(node, "div");
-
-		// "Otherwise, remove node, preserving its descendants."
-		} else {
-			removePreservingDescendants(node);
+		// "If node's previousSibling and first child are both inline nodes,
+		// and its previousSibling is not a br, then call createElement("br")
+		// on the ownerDocument of node, and insert the result into node's
+		// parent immediately before node."
+		if (isInlineNode(node.previousSibling)
+		&& isInlineNode(node.firstChild)
+		&& !isHtmlElement(node.previousSibling, "BR")) {
+			node.parentNode.insertBefore(node.ownerDocument.createElement("br"), node);
 		}
 
+		// "If node's last child and nextSibling are both inline nodes, and its
+		// last child is not a br, then call createElement("br") on the
+		// ownerDocument of node, and insert the result into node's parent
+		// immediately after node."
+		if (isInlineNode(node.lastChild)
+		&& isInlineNode(node.nextSibling)
+		&& !isHtmlElement(node.lastChild, "BR")) {
+			node.parentNode.insertBefore(node.ownerDocument.createElement("br"), node.nextSibling);
+		}
+
+		// "If node has no children, and its previousSibling and nextSibling
+		// are both inline nodes, and its previousSibling is not a br, then
+		// call createElement("br") on the ownerDocument of node, and insert
+		// the result into node's parent immediately before node."
+		if (!node.hasChildNodes()
+		&& isInlineNode(node.previousSibling)
+		&& isInlineNode(node.nextSibling)
+		&& !isHtmlElement(node.previousSibling, "BR")) {
+			node.parentNode.insertBefore(node.ownerDocument.createElement("br"), node);
+		}
+
+		// "Remove node, preserving its descendants."
+		removePreservingDescendants(node);
+
 		// "Abort these steps."
 		return;
 	}
--- a/source.html	Tue May 10 12:58:59 2011 -0600
+++ b/source.html	Tue May 10 14:13:28 2011 -0600
@@ -2541,6 +2541,62 @@
   * Does not appear to be possible in Word or OO.
   * Also might be impossible to actually make such a list using execCommand() in browsers.
   * Suffice it to say that there's a lot of variation.
+* In an existing indented region equivalent to foo<blockquote>bar</blockquote>baz:
+  * Select "bar", do "ol":
+    * Word/OO/Firefox/Chrome: Increase indent, add "1".
+    * IE: Increase indent, add "a".
+    * Opera: Add "1" (but do not increase indent).
+  * Select "foobar", do "ol":
+    * Word/IE: Increase indent of both, add "1" before "foo" and "a" before
+      "bar".
+    * OO: Increase indent of "bar" one step, increase indent of "foo" two steps
+      so it's aligned with "bar", add "1" before "foo" and "2" before "bar".
+    * Firefox: Increase indent of both, add "1" before foo", add "2" before
+      "bar" aligned with the "1" of "foo" (so large gap between "2" and "bar").
+    * Chrome: Increase indent of "foo", add "1" before "foo" and "2" before
+      "bar".
+    * Opera: Mash everything together on one line.  But if you do
+      <p>foo</p><blockquote>bar</blockquote><p>baz</p> instead, same as Chrome.
+  * Select "foo" and do "ol", then select "bar" and do "ol":
+    * Word/OO/Firefox/Opera: Different than doing both at once (often in
+      exciting ways).
+    * IE/Chrome: Same as doing both at once.
+* In an existing multi-line indented region equivalent to <blockquote>foo<br>bar<br>baz</blockquote>:
+  * Select "bar", do "ol":
+    * Word/OO/Firefox/Chrome: Increase indent, add "1".
+    * IE: Increase indent of everything, add "a" before "foo".  If you do
+      <blockquote><p>foo<p>bar<p>baz</blockquote>, same as
+      Word/OO/Firefox/Chrome.
+    * Opera: Don't increase indent of anything, add "1" before "bar".
+* In an existing multi-line indented region equivalent to <blockquote>foo<br>bar</blockquote>baz:
+  * Select "barbaz", do "ol":
+    * Word: Indent both, add "a" before "bar" and "2" before "baz".
+    * OO: Indent "baz", add "1" before "bar" and "2" before "baz".
+    * IE: Indent everything, add "a" before "foo" and "1" before "baz".  If you
+      do <blockquote><p>foo<p>bar</blockquote><p>baz, indent "bar" and "baz"
+      and put "1" before each.
+    * Firefox: Indent "bar" and put "1" before it, put "baz" after "bar" on the
+      same line.  If you do <blockquote><p>foo<p>bar</blockquote><p>baz, same
+      as Chrome.
+    * Chrome: Indent "bar" once and "baz" twice, put "1" before "bar" and "2"
+      before "baz".
+    * Opera: Put a "1" before "bar" and move "baz" to the same line.  If you do
+      <blockquote><p>foo<p>bar</blockquote><p>baz, indent "baz", put a "1"
+      before "bar" and a "2" before "baz".
+  * Select "bar", do "ol", then select "baz" and do "ol":
+    * Word/OO/Opera: Different from if you do both together.
+    * IE: Different with <br>, same with <p>.
+    * Firefox: Three behaviors, depending on whether you do it in one step with
+      <br>, one step with <p>, or two steps with either (same behavior
+      regardless with two steps).
+    * Chrome: Same behavior in all four cases.
+* <blockquote>foo<ol><li>bar</ol></blockquote>baz:
+  * Select "baz", do "ol":
+    * Word/OO/Chrome: Add "baz" as a new item to existing list.
+    * IE/Firefox/Opera: Make "baz" its own new list.
+* <ul><li>foo</li><ol><li>bar</li></ol></ul>baz:
+  * Select "baz", do "ol":
+    * IE/Firefox/Chrome/Opera: Separate list.
 
 Ignoring the conceptual model of HTML, which users won't understand, here's the
 conceptual model I've developed for lists: text is divided up into blocks.
@@ -2635,7 +2691,8 @@
 
   <li>For each [[node]] <var>node</var> [[contained]] in <var>new range</var>,
   if <var>node</var> is <span>editable</span>; the last member of <var>node
-  list</var> (if any) is not an [[ancestor]] of <var>node</var>; and
+  list</var> (if any) is not an [[ancestor]] of <var>node</var>;
+  <var>node</var> is not a <span>potential indentation element</span>; and
   either <var>node</var> is an [[ol]] or [[ul]], or its [[parent]] is an [[ol]]
   or [[ul]], or it can be the [[child]] of an [[li]]; then append
   <var>node</var> to <var>node list</var>.
@@ -2734,6 +2791,20 @@
     <li>s. -->
 
     <ol>
+      <li>Let <var>extra indentation</var> equal 0.
+
+      <li>Let <var>ancestor</var> be the [[parent]] of the first member of
+      <var>sublist</var>.
+
+      <li>While <var>ancestor</var> is an <span>editable</span> [[element]]:
+
+      <ol>
+        <li>If <var>ancestor</var> is a <span>potential indentation
+        element</span>, increment <var>extra indentation</var>.
+
+        <li>Set <var>ancestor</var> to its [[parent]].
+      </ol>
+
       <li>If the first member of <var>sublist</var> is a [[p]] or [[li]] or
       [[div]], <span>set the tag name</span> of the first member of
       <var>sublist</var> to "li", and let <var>li</var> be the result.  Remove
@@ -2756,6 +2827,10 @@
         [[ownerdocument]] of the first member of <var>sublist</var>.
       </ol>
 
+      <li>Repeat the following a number of times equal to <var>extra
+      indentation</var>: for each <var>node</var> in <var>sublist</var>,
+      <span>outdent</span> <var>node</var>.
+
       <li>If the [[nextsibling]] of the last member of <var>sublist</var> is an
       [[ol]]:
 
@@ -2798,6 +2873,10 @@
       </ol>
     </ol>
 
+    <li>Repeat the following a number of times equal to <var>extra
+    indentation</var>: <span>indent</span> the one-[[node]] list containing
+    <var>li</var>.
+
     <li>If the first member of <var>node list</var> is a [[br]], remove the
     first member of <var>node list</var> from its [[parent]], then remove it
     from <var>node list</var>.
@@ -2967,17 +3046,30 @@
   <li>If <var>node</var> is an <span>indentation element</span>:
 
   <ol>
-    <li>If <var>node</var>'s last [[child]] and [[nextsibling]] are both
-    <span title="inline node">inline nodes</span> or its first [[child]] and
-    [[previoussibling]] are both <span title="inline node">inline
-    nodes</span>, unset all attributes of <var>node</var>, then <span>set the
-    tag name</span> of <var>node</var> to "div".
-    <!-- In this case, removing it entirely will result in its first or last
-    child becoming part of the previous or next sibling's line box, so we
-    want to keep a div. -->
-
-    <li>Otherwise, remove <var>node</var>, <span>preserving its
-    descendants</span>.
+    <li>If <var>node</var>'s [[previoussibling]] and first [[child]] are both
+    <span title="inline node">inline nodes</span>, and its [[previoussibling]]
+    is not a [[br]], then call <code data-anolis-spec=domcore
+    title=dom-Document-createElement>createElement("br")</code> on the
+    [[ownerdocument]] of <var>node</var>, and insert the result into
+    <var>node</var>'s [[parent]] immediately before <var>node</var>.
+
+    <li>If <var>node</var>'s last [[child]] and [[nextsibling]] are both <span
+    title="inline node">inline nodes</span>, and its last [[child]] is not a
+    [[br]], then call <code data-anolis-spec=domcore
+    title=dom-Document-createElement>createElement("br")</code> on the
+    [[ownerdocument]] of <var>node</var>, and insert the result into
+    <var>node</var>'s [[parent]] immediately after <var>node</var>.
+
+    <!-- Just to be pedantic . . . it could happen! -->
+    <li>If <var>node</var> has no [[children]], and its [[previoussibling]] and
+    [[nextsibling]] are both <span title="inline node">inline nodes</span>, and
+    its [[previoussibling]] is not a [[br]], then call <code
+    data-anolis-spec=domcore
+    title=dom-Document-createElement>createElement("br")</code> on the
+    [[ownerdocument]] of <var>node</var>, and insert the result into
+    <var>node</var>'s [[parent]] immediately before <var>node</var>.
+
+    <li>Remove <var>node</var>, <span>preserving its descendants</span>.
 
     <li>Abort these steps.
   </ol>