Further improve insertOrderedList correctness
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 10 May 2011 15:37:03 -0600
changeset 103 4dd2566c6c51
parent 102 babf18ca1062
child 104 ad8ea1721fd8
Further improve insertOrderedList correctness

But I'm not sure about this approach now. It means that if a
significant stretch of text is indented, you can't make it into a list
that's also indented. I think I'm going to have to rewrite this again.
editcommands.html
implementation.js
source.html
--- a/editcommands.html	Tue May 10 14:13:28 2011 -0600
+++ b/editcommands.html	Tue May 10 15:37:03 2011 -0600
@@ -274,6 +274,23 @@
   parent</var>, <a href=#preserving-ranges>preserving ranges</a>.
 </ol>
 
+<p>To <dfn id=remove-extraneous-line-breaks>remove extraneous line breaks</dfn> from a <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>:
+
+<ol>
+  <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, or it is an <a href=#inline-node>inline
+  node</a>, do nothing and abort these steps.
+
+  <li>If 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="">node</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>, and 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 <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="">node</var> is an
+  <a href=#inline-node>inline node</a> that 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 <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="">node</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>.
+
+  <li>If <var title="">node</var> has at least two <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 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 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>, and its second-to-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 an <a href=#inline-node>inline node</a>
+  that 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 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="">node</var> from
+  <var title="">node</var>.
+</ol>
+
 <p>An <dfn id=editing-host>editing host</dfn> is a <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> that is either an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> with
 a <code class=external data-anolis-spec=html title=attr-contenteditable><a href=http://www.whatwg.org/html/#attr-contenteditable>contenteditable</a></code>
 attribute set to the true state, or a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code> whose <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#designmode>designMode</a></code> is enabled.
@@ -722,8 +739,8 @@
     node</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>.
 
     <li>Otherwise, if 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 <var title="">start node</var> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>
-    <var title="">start offset</var> 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> are both <a href=#inline-node title="inline node">inline nodes</a> and neither 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>, subtract
-    one from <var title="">start offset</var>.
+    <var title="">start offset</var> 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> are both <a href=#inline-node title="inline node">inline nodes</a> and 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> isn't 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>, subtract one from <var title="">start offset</var>.
     <!-- IE also includes <br> (at least for the purposes of the indent
     command), but this is unlikely to match user expectations. -->
 
@@ -750,12 +767,20 @@
     node</var> and then set <var title="">end node</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>.
 
     <li>Otherwise, if 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 <var title="">end node</var> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>
-    <var title="">end offset</var> 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> are both <a href=#inline-node title="inline node">inline nodes</a> and neither 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>, add one to
+    <var title="">end offset</var> 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> are both <a href=#inline-node title="inline node">inline nodes</a>, and 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 <var title="">end
+    node</var> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">end offset</var> isn't 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>, add one to
     <var title="">end offset</var>.
 
     <li>Otherwise, break from this loop.
   </ol>
 
+  <li>If 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 <var title="">end node</var> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">end
+  offset</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>, add one to <var title="">end offset</var>.
+
+  <li>While <var title="">end offset</var> is equal to the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of <var title="">end
+  node</var>, set <var title="">end offset</var> to one plus the <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="">end
+  node</var> and then set <var title="">end node</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>.
+
   <li>Let <var title="">new range</var> be a new <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> whose <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> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>nodes</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offsets</a> are <var title="">start node</var>,
   <var title="">start offset</var>, <var title="">end node</var>, and <var title="">end offset</var>.
@@ -2006,29 +2031,6 @@
   <li><a href=#block-extend>Block-extend</a> the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a>, and let <var title="">new range</var> be
   the result.
 
-  <!-- If the first line box in a block box starts with a non-preserved line
-  break, the line break will create an empty line box.  If the last line box in
-  a block box ends with a non-preserved line break, however, it will not create
-  an extra line box.  This means that if you have foo<br>bar, there will be no
-  empty line in between, but if you change it to <div>foo</div><br>bar, you've
-  created an extra line.  Chrome 12 dev thus deletes a <br> that immediately
-  follows a <blockquote> it creates.  Firefox 4.0 and Opera 11.00 instead just
-  includes it in the blockquote, so it has no effect.  The issue doesn't come
-  up for IE9, since it indents the whole block and doesn't treat <br>
-  differently from other inline elements.  I follow WebKit because it produces
-  slightly neater markup. -->
-  <li>If 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 <var title="">new range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> with
-  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> equal to its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> 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>:
-
-  <ol>
-    <li>Remove that <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</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>.
-
-    <li>While the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> of <var title="">new range</var> is equal to
-    the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, set the <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="">new range</var> to (<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 <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, 1 +
-    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>).
-  </ol>
-
   <li>Let <var title="">node list</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 empty.
 
   <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>,
@@ -2147,6 +2149,8 @@
   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 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>, <a href=#preserving-ranges>preserving
   ranges</a>.  Then abort these steps.
 
+  <p class=XXX>This might put things on the same line when they shouldn't be.
+
   <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="">node list</var> is an
   <a href=#indentation-element>indentation element</a>; its "display" property computes to "block";
   its "margin-left" and "margin-right" properties compute to "40px"; and its
@@ -2193,6 +2197,8 @@
   <li>For each <var title="">node</var> in <var title="">node list</var>, append <var title="">node</var>
   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><a href=#remove-extraneous-line-breaks>Remove extraneous line breaks</a> from <var title="">new parent</var>.
 </ol>
 
 <dd><strong>State</strong>:
@@ -2632,18 +2638,6 @@
   <li><a href=#block-extend>Block-extend</a> the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a>, and let <var title="">new range</var> be
   the result.
 
-  <li>If 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 <var title="">new range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> with
-  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> equal to its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> 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>:
-
-  <ol>
-    <li>Remove that <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</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>.
-
-    <li>While the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> of <var title="">new range</var> is equal to
-    the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, set the <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="">new range</var> to (<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 <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, 1 +
-    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>).
-  </ol>
-
   <li>Let <var title="">node list</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 empty.
 
   <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>,
@@ -2659,13 +2653,8 @@
   <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>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>, append it to
-    <var title="">sublist</var> (without removing it from <var title="">node list</var>).
-    <!-- It will be removed later, since in every pass we get rid of the first
-    member of node list if it's a br. -->
-
-    <li>Otherwise, remove the first member of <var title="">node list</var> and append
-    it to <var title="">sublist</var>.
+    <li>Remove the first member of <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.
@@ -2773,8 +2762,9 @@
         <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> that are not <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>s, remove the first member
-        from <var title="">node list</var> and append it to <var title="">sublist</var>.
+        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>Let <var title="">li</var> be 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
         <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>.
@@ -2784,6 +2774,11 @@
       indentation</var>: for each <var title="">node</var> in <var title="">sublist</var>,
       <a href=#outdent>outdent</a> <var title="">node</var>.
 
+      <!-- That might have created an extra <br> at some point. -->
+      <li>If 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> but its
+      <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, append 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> to <var title="">sublist</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>:
 
@@ -2792,8 +2787,8 @@
         of the last member of <var title="">sublist</var>, <a href=#preserving-ranges>preserving
         ranges</a>.
 
-        <li>If the first member of <var title="">sublist</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> 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>,
-        remove it from <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 li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code>, remove it
+        from <var title="">sublist</var>.
 
         <li>For each <var title="">node</var> in <var title="">sublist</var> <em>in 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
@@ -2816,8 +2811,8 @@
         <li>Append <var title="">li</var> 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="">ol</var>,
         <a href=#preserving-ranges>preserving ranges</a>.
 
-        <li>If the first member of <var title="">sublist</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> 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>,
-        remove it from <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 li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code>, remove it
+        from <var title="">sublist</var>.
 
         <li>For each <var title="">node</var> in <var title="">sublist</var>, append
         <var title="">node</var> 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="">li</var>,
@@ -2825,13 +2820,13 @@
       </ol>
     </ol>
 
+    <li><a href=#remove-extraneous-line-breaks>Remove extraneous line breaks</a> from <var title="">ol</var>.
+
+    <li><a href=#remove-extraneous-line-breaks>Remove extraneous line breaks</a> from <var title="">li</var>.
+
     <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>.
   </ol>
 </ol>
 
@@ -3116,6 +3111,10 @@
     that is equal to either <var title="">node</var> or the last member of <var title="">ancestor
     list</var>.
 
+    <li>If <var title="">target</var> is an <a href=#inline-node>inline node</a> that 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>, and its <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 <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 <var title="">target</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>.
+
     <li>Let <var title="">preceding siblings</var> be the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-preceding-sibling title=concept-tree-preceding-sibling>preceding siblings</a> of
     <var title="">target</var>, and let <var title="">following siblings</var> be the
     <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-following-sibling title=concept-tree-following-sibling>following siblings</a> of <var title="">target</var>.
--- a/implementation.js	Tue May 10 14:13:28 2011 -0600
+++ b/implementation.js	Tue May 10 15:37:03 2011 -0600
@@ -432,6 +432,35 @@
 	}
 }
 
+function removeExtraneousLineBreaks(node) {
+	// "If node is not an Element, or it is an inline node, do nothing and
+	// abort these steps."
+	if (!node
+	|| node.nodeType != Node.ELEMENT_NODE
+	|| isInlineNode(node)) {
+		return;
+	}
+
+	// "If the previousSibling of node is a br, and the previousSibling of the
+	// previousSibling of node is an inline node that is not a br, remove the
+	// previousSibling of node from its parent."
+	if (isHtmlElement(node.previousSibling, "BR")
+	&& isInlineNode(node.previousSibling.previousSibling)
+	&& !isHtmlElement(node.previousSibling.previousSibling, "BR")) {
+		node.parentNode.removeChild(node.previousSibling);
+	}
+
+	// "If node has at least two children, and its last child is a br, and its
+	// second-to-last child is an inline node that is not a br, remove the last
+	// child of node from node."
+	if (node.childNodes.length >= 2
+	&& isHtmlElement(node.lastChild, "BR")
+	&& isInlineNode(node.lastChild.previousSibling)
+	&& !isHtmlElement(node.lastChild.previousSibling, "BR")) {
+		node.removeChild(node.lastChild);
+	}
+}
+
 // "An editing host is a node that is either an Element with a contenteditable
 // attribute set to the true state, or a Document whose designMode is enabled."
 function isEditingHost(node) {
@@ -1226,17 +1255,11 @@
 			startNode = startNode.parentNode;
 
 		// "Otherwise, if the child of start node with index start offset and
-		// its previousSibling are both inline nodes and neither is a br,
-		// subtract one from start offset."
+		// its previousSibling are both inline nodes and the previousSibling
+		// isn't a br, subtract one from start offset."
 		} else if (isInlineNode(startNode.childNodes[startOffset])
 		&& isInlineNode(startNode.childNodes[startOffset].previousSibling)
-		&& (
-			!isHtmlElement(startNode.childNodes[startOffset])
-			|| startNode.childNodes[startOffset].tagName != "BR"
-		) && (
-			!isHtmlElement(startNode.childNodes[startOffset].previousSibling)
-			|| startNode.childNodes[startOffset].previousSibling.tagName != "BR"
-		)) {
+		&& !isHtmlElement(startNode.childNodes[startOffset].previousSibling, "BR")) {
 			startOffset--;
 
 		// "Otherwise, break from this loop."
@@ -1278,17 +1301,11 @@
 			endNode = endNode.parentNode;
 
 		// "Otherwise, if the child of end node with index end offset and its
-		// previousSibling are both inline nodes and neither is a br, add one
-		// to end offset."
+		// previousSibling are both inline nodes, and the child of end node
+		// with index end offset isn't a br, add one to end offset."
 		} else if (isInlineNode(endNode.childNodes[endOffset])
 		&& isInlineNode(endNode.childNodes[endOffset].previousSibling)
-		&& (
-			!isHtmlElement(endNode.childNodes[endOffset])
-			|| endNode.childNodes[endOffset].tagName != "BR"
-		) && (
-			!isHtmlElement(endNode.childNodes[endOffset].previousSibling)
-			|| endNode.childNodes[endOffset].previousSibling.tagName != "BR"
-		)) {
+		&& !isHtmlElement(endNode.childNodes[endOffset], "BR")) {
 			endOffset++;
 
 		// "Otherwise, break from this loop."
@@ -1297,6 +1314,19 @@
 		}
 	}
 
+	// "If the child of end node with index end offset is a br, add one to end
+	// offset."
+	if (isHtmlElement(endNode.childNodes[endOffset], "BR")) {
+		endOffset++;
+	}
+
+	// "While end offset is equal to the length of end node, set end offset to
+	// one plus the index of end node and then set end node to its parent."
+	while (endOffset == getNodeLength(endNode)) {
+		endOffset = 1 + getNodeIndex(endNode);
+		endNode = endNode.parentNode;
+	}
+
 	// "Let new range be a new range whose start and end nodes and offsets
 	// are start node, start offset, end node, and end offset."
 	var newRange = startNode.ownerDocument.createRange();
@@ -2241,21 +2271,6 @@
 		// "Block-extend the range, and let new range be the result."
 		var newRange = blockExtendRange(range);
 
-		// "If the child of new range's end node with index equal to its end
-		// offset is a br:"
-		var end = newRange.endContainer.childNodes[newRange.endOffset];
-		if (isHtmlElement(end) && end.tagName == "BR") {
-			// "Remove that br from its parent."
-			end.parentNode.removeChild(end);
-
-			// "While the end offset of new range is equal to the length of its
-			// end node, set the end of new range to (parent of end node, 1 +
-			// index of end node)."
-			while (newRange.endOffset == getNodeLength(newRange.endContainer)) {
-				newRange.setEnd(newRange.endContainer.parentNode, 1 + getNodeIndex(newRange.endContainer));
-			}
-		}
-
 		// "Let node list be a list of nodes, initially empty."
 		var nodeList = [];
 
@@ -2485,21 +2500,6 @@
 		// "Block-extend the range, and let new range be the result."
 		var newRange = blockExtendRange(range);
 
-		// "If the child of new range's end node with index equal to its end
-		// offset is a br:"
-		var end = newRange.endContainer.childNodes[newRange.endOffset];
-		if (isHtmlElement(end) && end.tagName == "BR") {
-			// "Remove that br from its parent."
-			end.parentNode.removeChild(end);
-
-			// "While the end offset of new range is equal to the length of its
-			// end node, set the end of new range to (parent of end node, 1 +
-			// index of end node)."
-			while (newRange.endOffset == getNodeLength(newRange.endContainer)) {
-				newRange.setEnd(newRange.endContainer.parentNode, 1 + getNodeIndex(newRange.endContainer));
-			}
-		}
-
 		// "Let node list be a list of nodes, initially empty."
 		var nodeList = [];
 
@@ -2534,15 +2534,8 @@
 			// "Let sublist be an empty list of nodes."
 			var sublist = [];
 
-			// "If the first member of node list is a br, append it to sublist
-			// (without removing it from node list)."
-			if (isHtmlElement(nodeList[0], "BR")) {
-				sublist.push(nodeList[0]);
-
-			// "Otherwise, remove the first member of node list and append it to sublist."
-			} else {
-				sublist.push(nodeList.shift());
-			}
+			// "Remove the first member of node list and append it to sublist."
+			sublist.push(nodeList.shift());
 
 			// "If the first member of sublist is an ol, outdent it."
 			if (isHtmlElement(sublist[0], "OL")) {
@@ -2671,14 +2664,13 @@
 					// "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 both inline nodes that are not brs,
-					// remove the first member from node list and append it to
-					// sublist."
+					// of node list are both inline nodes, and the last member
+					// of sublist is not a br, remove the first member from
+					// node list and append it to sublist."
 					while (nodeList.length
 					&& nodeList[0] == sublist[sublist.length -1].nextSibling
 					&& isInlineNode(nodeList[0])
 					&& isInlineNode(sublist[sublist.length -1])
-					&& !isHtmlElement(nodeList[0], "BR")
 					&& !isHtmlElement(sublist[sublist.length -1], "BR")) {
 						sublist.push(nodeList.shift());
 					}
@@ -2696,16 +2688,23 @@
 					}
 				}
 
+				// "If the last member of sublist is not a br but its
+				// nextSibling is, append the nextSibling of the last member of
+				// sublist to sublist."
+				if (!isHtmlElement(sublist[sublist.length - 1], "BR")
+				&& isHtmlElement(sublist[sublist.length - 1].nextSibling, "BR")) {
+					sublist.push(sublist[sublist.length - 1].nextSibling);
+				}
+
 				// "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
 					// last member of sublist, preserving ranges."
 					movePreservingRanges(li, sublist[sublist.length - 1].nextSibling, 0);
 
-					// "If the first member of sublist is a br or li, remove it
-					// from sublist."
-					if (isHtmlElement(sublist[0], "BR")
-					|| isHtmlElement(sublist[0], "LI")) {
+					// "If the first member of sublist is an li, remove it from
+					// sublist."
+					if (isHtmlElement(sublist[0], "LI")) {
 						sublist.shift();
 					}
 
@@ -2733,10 +2732,9 @@
 					// "Append li as the last child of ol, preserving ranges."
 					movePreservingRanges(li, ol, ol.childNodes.length);
 
-					// "If the first member of sublist is a br or li, remove it
-					// from sublist."
-					if (isHtmlElement(sublist[0], "BR")
-					|| isHtmlElement(sublist[0], "LI")) {
+					// "If the first member of sublist is an li, remove it from
+					// sublist."
+					if (isHtmlElement(sublist[0], "LI")) {
 						sublist.shift();
 					}
 
@@ -2748,19 +2746,17 @@
 				}
 			}
 
+			// "Remove extraneous line breaks from ol."
+			removeExtraneousLineBreaks(ol);
+
+			// "Remove extraneous line breaks from li."
+			removeExtraneousLineBreaks(li);
+
 			// "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."
-			if (isHtmlElement(nodeList[0], "BR")) {
-				nodeList[0].parentNode.removeChild(nodeList[0]);
-				nodeList.shift();
-			}
 		}
 		break;
 
@@ -3159,6 +3155,9 @@
 	for (var i = 0; i < nodeList.length; i++) {
 		movePreservingRanges(nodeList[i], newParent, newParent.childNodes.length);
 	}
+
+	// "Remove extraneous line breaks from new parent."
+	removeExtraneousLineBreaks(newParent);
 }
 
 function outdentNode(node) {
@@ -3351,6 +3350,14 @@
 			? node
 			: ancestorList[ancestorList.length - 1];
 
+		// "If target is an inline node that is not a br, and its nextSibling
+		// is a br, remove target's nextSibling from its parent."
+		if (isInlineNode(target)
+		&& !isHtmlElement(target, "BR")
+		&& isHtmlElement(target.nextSibling, "BR")) {
+			target.parentNode.removeChild(target.nextSibling);
+		}
+
 		// "Let preceding siblings be the preceding siblings of target, and let
 		// following siblings be the following siblings of target."
 		var precedingSiblings = [].slice.call(currentAncestor.childNodes, 0, getNodeIndex(target));
--- a/source.html	Tue May 10 14:13:28 2011 -0600
+++ b/source.html	Tue May 10 15:37:03 2011 -0600
@@ -263,6 +263,23 @@
   parent</var>, <span>preserving ranges</span>.
 </ol>
 
+<p>To <dfn>remove extraneous line breaks</dfn> from a [[node]] <var>node</var>:
+
+<ol>
+  <li>If <var>node</var> is not an [[element]], or it is an <span>inline
+  node</span>, do nothing and abort these steps.
+
+  <li>If the [[previoussibling]] of <var>node</var> is a [[br]], and the
+  [[previoussibling]] of the [[previoussibling]] of <var>node</var> is an
+  <span>inline node</span> that is not a [[br]], remove the [[previoussibling]]
+  of <var>node</var> from its [[parent]].
+
+  <li>If <var>node</var> has at least two [[children]], and its last [[child]]
+  is a [[br]], and its second-to-last [[child]] is an <span>inline node</span>
+  that is not a [[br]], remove the last [[child]] of <var>node</var> from
+  <var>node</var>.
+</ol>
+
 <p>An <dfn>editing host</dfn> is a [[node]] that is either an [[element]] with
 a <code data-anolis-spec=html title=attr-contenteditable>contenteditable</code>
 attribute set to the true state, or a [[document]] whose <code
@@ -720,8 +737,8 @@
 
     <li>Otherwise, if the [[child]] of <var>start node</var> with [[index]]
     <var>start offset</var> and its [[previoussibling]] are both <span
-    title="inline node">inline nodes</span> and neither is a [[br]], subtract
-    one from <var>start offset</var>.
+    title="inline node">inline nodes</span> and the [[previoussibling]] isn't a
+    [[br]], subtract one from <var>start offset</var>.
     <!-- IE also includes <br> (at least for the purposes of the indent
     command), but this is unlikely to match user expectations. -->
 
@@ -749,12 +766,20 @@
 
     <li>Otherwise, if the [[child]] of <var>end node</var> with [[index]]
     <var>end offset</var> and its [[previoussibling]] are both <span
-    title="inline node">inline nodes</span> and neither is a [[br]], add one to
+    title="inline node">inline nodes</span>, and the [[child]] of <var>end
+    node</var> with [[index]] <var>end offset</var> isn't a [[br]], add one to
     <var>end offset</var>.
 
     <li>Otherwise, break from this loop.
   </ol>
 
+  <li>If the [[child]] of <var>end node</var> with [[index]] <var>end
+  offset</var> is a [[br]], add one to <var>end offset</var>.
+
+  <li>While <var>end offset</var> is equal to the [[nodelength]] of <var>end
+  node</var>, set <var>end offset</var> to one plus the [[index]] of <var>end
+  node</var> and then set <var>end node</var> to its [[parent]].
+
   <li>Let <var>new range</var> be a new [[range]] whose [[rangestart]] and
   [[rangeend]] [[bpnodes]] and [[bpoffsets]] are <var>start node</var>,
   <var>start offset</var>, <var>end node</var>, and <var>end offset</var>.
@@ -2026,29 +2051,6 @@
   <li><span>Block-extend</span> the [[range]], and let <var>new range</var> be
   the result.
 
-  <!-- If the first line box in a block box starts with a non-preserved line
-  break, the line break will create an empty line box.  If the last line box in
-  a block box ends with a non-preserved line break, however, it will not create
-  an extra line box.  This means that if you have foo<br>bar, there will be no
-  empty line in between, but if you change it to <div>foo</div><br>bar, you've
-  created an extra line.  Chrome 12 dev thus deletes a <br> that immediately
-  follows a <blockquote> it creates.  Firefox 4.0 and Opera 11.00 instead just
-  includes it in the blockquote, so it has no effect.  The issue doesn't come
-  up for IE9, since it indents the whole block and doesn't treat <br>
-  differently from other inline elements.  I follow WebKit because it produces
-  slightly neater markup. -->
-  <li>If the [[child]] of <var>new range</var>'s [[rangeend]] [[bpnode]] with
-  [[index]] equal to its [[rangeend]] [[bpoffset]] is a [[br]]:
-
-  <ol>
-    <li>Remove that [[br]] from its [[parent]].
-
-    <li>While the [[rangeend]] [[bpoffset]] of <var>new range</var> is equal to
-    the [[nodelength]] of its [[rangeend]] [[bpnode]], set the [[rangeend]] of
-    <var>new range</var> to ([[parent]] of [[rangeend]] [[bpnode]], 1 +
-    [[index]] of [[rangeend]] [[bpnode]]).
-  </ol>
-
   <li>Let <var>node list</var> be a list of [[nodes]], initially empty.
 
   <li>For each [[node]] <var>node</var> [[contained]] in <var>new range</var>,
@@ -2169,6 +2171,8 @@
   the last [[child]] of its [[previoussibling]], <span>preserving
   ranges</span>.  Then abort these steps.
 
+  <p class=XXX>This might put things on the same line when they shouldn't be.
+
   <li>If the [[nextsibling]] of the last member of <var>node list</var> is an
   <span>indentation element</span>; its "display" property computes to "block";
   its "margin-left" and "margin-right" properties compute to "40px"; and its
@@ -2217,6 +2221,8 @@
   <li>For each <var>node</var> in <var>node list</var>, append <var>node</var>
   as the last [[child]] of <var>new parent</var>, <span>preserving
   ranges</span>.
+
+  <li><span>Remove extraneous line breaks</span> from <var>new parent</var>.
 </ol>
 
 <dd><strong>State</strong>:
@@ -2675,18 +2681,6 @@
   <li><span>Block-extend</span> the [[range]], and let <var>new range</var> be
   the result.
 
-  <li>If the [[child]] of <var>new range</var>'s [[rangeend]] [[bpnode]] with
-  [[index]] equal to its [[rangeend]] [[bpoffset]] is a [[br]]:
-
-  <ol>
-    <li>Remove that [[br]] from its [[parent]].
-
-    <li>While the [[rangeend]] [[bpoffset]] of <var>new range</var> is equal to
-    the [[nodelength]] of its [[rangeend]] [[bpnode]], set the [[rangeend]] of
-    <var>new range</var> to ([[parent]] of [[rangeend]] [[bpnode]], 1 +
-    [[index]] of [[rangeend]] [[bpnode]]).
-  </ol>
-
   <li>Let <var>node list</var> be a list of [[nodes]], initially empty.
 
   <li>For each [[node]] <var>node</var> [[contained]] in <var>new range</var>,
@@ -2702,13 +2696,8 @@
   <ol>
     <li>Let <var>sublist</var> be an empty list of [[nodes]].
 
-    <li>If the first member of <var>node list</var> is a [[br]], append it to
-    <var>sublist</var> (without removing it from <var>node list</var>).
-    <!-- It will be removed later, since in every pass we get rid of the first
-    member of node list if it's a br. -->
-
-    <li>Otherwise, remove the first member of <var>node list</var> and append
-    it to <var>sublist</var>.
+    <li>Remove the first member of <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.
@@ -2818,8 +2807,9 @@
         <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> that are not [[br]]s, remove the first member
-        from <var>node list</var> and append it to <var>sublist</var>.
+        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>Let <var>li</var> be the result of calling <code
         data-anolis-spec=domcore
@@ -2831,6 +2821,11 @@
       indentation</var>: for each <var>node</var> in <var>sublist</var>,
       <span>outdent</span> <var>node</var>.
 
+      <!-- That might have created an extra <br> at some point. -->
+      <li>If the last member of <var>sublist</var> is not a [[br]] but its
+      [[nextsibling]] is, append the [[nextsibling]] of the last member of
+      <var>sublist</var> to <var>sublist</var>.
+
       <li>If the [[nextsibling]] of the last member of <var>sublist</var> is an
       [[ol]]:
 
@@ -2839,8 +2834,8 @@
         of the last member of <var>sublist</var>, <span>preserving
         ranges</span>.
 
-        <li>If the first member of <var>sublist</var> is a [[br]] or [[li]],
-        remove it from <var>sublist</var>.
+        <li>If the first member of <var>sublist</var> is an [[li]], remove it
+        from <var>sublist</var>.
 
         <li>For each <var>node</var> in <var>sublist</var> <em>in reverse
         order</em>, insert <var>node</var> as the first [[child]] of
@@ -2864,8 +2859,8 @@
         <li>Append <var>li</var> as the last [[child]] of <var>ol</var>,
         <span>preserving ranges</span>.
 
-        <li>If the first member of <var>sublist</var> is a [[br]] or [[li]],
-        remove it from <var>sublist</var>.
+        <li>If the first member of <var>sublist</var> is an [[li]], remove it
+        from <var>sublist</var>.
 
         <li>For each <var>node</var> in <var>sublist</var>, append
         <var>node</var> as the last [[child]] of <var>li</var>,
@@ -2873,13 +2868,13 @@
       </ol>
     </ol>
 
+    <li><span>Remove extraneous line breaks</span> from <var>ol</var>.
+
+    <li><span>Remove extraneous line breaks</span> from <var>li</var>.
+
     <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>.
   </ol>
 </ol>
 
@@ -3173,6 +3168,10 @@
     that is equal to either <var>node</var> or the last member of <var>ancestor
     list</var>.
 
+    <li>If <var>target</var> is an <span>inline node</span> that is not a
+    [[br]], and its [[nextsibling]] is a [[br]], remove <var>target</var>'s
+    [[nextsibling]] from its [[parent]].
+
     <li>Let <var>preceding siblings</var> be the [[precedingsiblings]] of
     <var>target</var>, and let <var>following siblings</var> be the
     [[followingsiblings]] of <var>target</var>.