More reorganization
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Sun, 10 Jul 2011 09:08:57 -0600
changeset 378 f12baf3fdada
parent 377 bbc065da041b
child 379 b534abd08917
More reorganization

I should really stop doing this so often, it just lets me waste time
when I don't feel like using my brain. But this did cut down the size
of the assorted block formatting commands section, which was getting
very unwieldy. I also realized I can include more than one algorithm
per section even outside the assorted algorithm section (duh?).
editcommands.html
source.html
--- a/editcommands.html	Sun Jul 10 08:51:12 2011 -0600
+++ b/editcommands.html	Sun Jul 10 09:08:57 2011 -0600
@@ -79,7 +79,8 @@
  <li><a href=#common-algorithms><span class=secno>6 </span>Common algorithms</a>
   <ol>
    <li><a href=#assorted-common-algorithms><span class=secno>6.1 </span>Assorted common algorithms</a></li>
-   <li><a href=#wrapping-a-list-of-nodes><span class=secno>6.2 </span>Wrapping a list of nodes</a></ol></li>
+   <li><a href=#wrapping-a-list-of-nodes><span class=secno>6.2 </span>Wrapping a list of nodes</a></li>
+   <li><a href=#allowed-children><span class=secno>6.3 </span>Allowed children</a></ol></li>
  <li><a href=#inline-formatting-commands><span class=secno>7 </span>Inline formatting commands</a>
   <ol>
    <li><a href=#inline-formatting-command-definitions><span class=secno>7.1 </span>Inline formatting command definitions</a></li>
@@ -106,29 +107,30 @@
   <ol>
    <li><a href=#block-formatting-command-definitions><span class=secno>8.1 </span>Block formatting command definitions</a></li>
    <li><a href=#assorted-block-formatting-command-algorithms><span class=secno>8.2 </span>Assorted block formatting command algorithms</a></li>
-   <li><a href=#allowed-children><span class=secno>8.3 </span>Allowed children</a></li>
-   <li><a href=#block-extending-a-range><span class=secno>8.4 </span>Block-extending a range</a></li>
-   <li><a href=#deleting-the-contents-of-a-range><span class=secno>8.5 </span>Deleting the contents of a range</a></li>
-   <li><a href=#outdenting-a-node><span class=secno>8.6 </span>Outdenting a node</a></li>
-   <li><a href=#toggling-lists><span class=secno>8.7 </span>Toggling lists</a></li>
-   <li><a href=#justifying-the-selection><span class=secno>8.8 </span>Justifying the selection</a></li>
-   <li><a href=#the-delete-command><span class=secno>8.9 </span>The <code title="">delete</code> command</a></li>
-   <li><a href=#the-formatblock-command><span class=secno>8.10 </span>The <code title="">formatBlock</code> command</a></li>
-   <li><a href=#the-forwarddelete-command><span class=secno>8.11 </span>The <code title="">forwardDelete</code> command</a></li>
-   <li><a href=#the-indent-command><span class=secno>8.12 </span>The <code title="">indent</code> command</a></li>
-   <li><a href=#the-inserthorizontalrule-command><span class=secno>8.13 </span>The <code title="">insertHorizontalRule</code> command</a></li>
-   <li><a href=#the-inserthtml-command><span class=secno>8.14 </span>The <code title="">insertHTML</code> command</a></li>
-   <li><a href=#the-insertimage-command><span class=secno>8.15 </span>The <code title="">insertImage</code> command</a></li>
-   <li><a href=#the-insertlinebreak-command><span class=secno>8.16 </span>The <code title="">insertLineBreak</code> command</a></li>
-   <li><a href=#the-insertorderedlist-command><span class=secno>8.17 </span>The <code title="">insertOrderedList</code> command</a></li>
-   <li><a href=#the-insertparagraph-command><span class=secno>8.18 </span>The <code title="">insertParagraph</code> command</a></li>
-   <li><a href=#the-inserttext-command><span class=secno>8.19 </span>The <code title="">insertText</code> command</a></li>
-   <li><a href=#the-insertunorderedlist-command><span class=secno>8.20 </span>The <code title="">insertUnorderedList</code> command</a></li>
-   <li><a href=#the-justifycenter-command><span class=secno>8.21 </span>The <code title="">justifyCenter</code> command</a></li>
-   <li><a href=#the-justifyfull-command><span class=secno>8.22 </span>The <code title="">justifyFull</code> command</a></li>
-   <li><a href=#the-justifyleft-command><span class=secno>8.23 </span>The <code title="">justifyLeft</code> command</a></li>
-   <li><a href=#the-justifyright-command><span class=secno>8.24 </span>The <code title="">justifyRight</code> command</a></li>
-   <li><a href=#the-outdent-command><span class=secno>8.25 </span>The <code title="">outdent</code> command</a></ol></li>
+   <li><a href=#block-extending-a-range><span class=secno>8.3 </span>Block-extending a range</a></li>
+   <li><a href=#deleting-the-contents-of-a-range><span class=secno>8.4 </span>Deleting the contents of a range</a></li>
+   <li><a href="#splitting-a-node-list's-parent"><span class=secno>8.5 </span>Splitting a node list's parent</a></li>
+   <li><a href=#canonical-space-sequences><span class=secno>8.6 </span>Canonical space sequences</a></li>
+   <li><a href=#indenting-and-outdenting><span class=secno>8.7 </span>Indenting and outdenting</a></li>
+   <li><a href=#toggling-lists><span class=secno>8.8 </span>Toggling lists</a></li>
+   <li><a href=#justifying-the-selection><span class=secno>8.9 </span>Justifying the selection</a></li>
+   <li><a href=#the-delete-command><span class=secno>8.10 </span>The <code title="">delete</code> command</a></li>
+   <li><a href=#the-formatblock-command><span class=secno>8.11 </span>The <code title="">formatBlock</code> command</a></li>
+   <li><a href=#the-forwarddelete-command><span class=secno>8.12 </span>The <code title="">forwardDelete</code> command</a></li>
+   <li><a href=#the-indent-command><span class=secno>8.13 </span>The <code title="">indent</code> command</a></li>
+   <li><a href=#the-inserthorizontalrule-command><span class=secno>8.14 </span>The <code title="">insertHorizontalRule</code> command</a></li>
+   <li><a href=#the-inserthtml-command><span class=secno>8.15 </span>The <code title="">insertHTML</code> command</a></li>
+   <li><a href=#the-insertimage-command><span class=secno>8.16 </span>The <code title="">insertImage</code> command</a></li>
+   <li><a href=#the-insertlinebreak-command><span class=secno>8.17 </span>The <code title="">insertLineBreak</code> command</a></li>
+   <li><a href=#the-insertorderedlist-command><span class=secno>8.18 </span>The <code title="">insertOrderedList</code> command</a></li>
+   <li><a href=#the-insertparagraph-command><span class=secno>8.19 </span>The <code title="">insertParagraph</code> command</a></li>
+   <li><a href=#the-inserttext-command><span class=secno>8.20 </span>The <code title="">insertText</code> command</a></li>
+   <li><a href=#the-insertunorderedlist-command><span class=secno>8.21 </span>The <code title="">insertUnorderedList</code> command</a></li>
+   <li><a href=#the-justifycenter-command><span class=secno>8.22 </span>The <code title="">justifyCenter</code> command</a></li>
+   <li><a href=#the-justifyfull-command><span class=secno>8.23 </span>The <code title="">justifyFull</code> command</a></li>
+   <li><a href=#the-justifyleft-command><span class=secno>8.24 </span>The <code title="">justifyLeft</code> command</a></li>
+   <li><a href=#the-justifyright-command><span class=secno>8.25 </span>The <code title="">justifyRight</code> command</a></li>
+   <li><a href=#the-outdent-command><span class=secno>8.26 </span>The <code title="">outdent</code> command</a></ol></li>
  <li><a href=#miscellaneous-commands><span class=secno>9 </span>Miscellaneous commands</a>
   <ol>
    <li><a href=#the-copy-command><span class=secno>9.1 </span>The <code title="">copy</code> command</a></li>
@@ -636,6 +638,19 @@
 <p>An <dfn id=html-element>HTML element</dfn> is 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> whose <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-namespace title=concept-element-namespace>namespace</a> is the
 <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#html-namespace>HTML namespace</a>.
 
+<p>A <dfn id=prohibited-paragraph-child-name>prohibited paragraph child name</dfn> is "address", "article",
+"aside", "blockquote", "caption", "center", "col", "colgroup", "dd", "details",
+"dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form",
+"h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "listing",
+"menu", "nav", "ol", "p", "plaintext", "pre", "section", "summary", "table",
+"tbody", "td", "tfoot", "th", "thead", "tr", "ul", or "xmp".
+
+<p>A <dfn id=prohibited-paragraph-child>prohibited paragraph child</dfn> is an <a href=#html-element>HTML element</a>
+whose <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> is a <a href=#prohibited-paragraph-child-name>prohibited paragraph child name</a>.
+<!-- These are all the things that will close a <p> if found as a descendant.
+I think.  Plus table stuff, since that can't be a descendant of a p either,
+although it won't auto-close it. -->
+
 <p>An <dfn id=inline-node>inline node</dfn> is either a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, or 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> whose
 "display" property computes to "inline", "inline-block", or "inline-table".
 
@@ -851,48 +866,6 @@
 <a href=#remove-extraneous-line-breaks-before>remove extraneous line breaks before</a> it, then <a href=#remove-extraneous-line-breaks-at-the-end-of>remove
 extraneous line breaks at the end of</a> it.
 
-<p>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> <dfn id=follows-a-line-break>follows a line break</dfn> if the following
-algorithm returns true:
-
-<p class=XXX>Editorial issue: These two algorithms depend on block-extending.
-Should that get moved up to the general algorithms?
-
-<ol>
-  <li>Let <var title="">offset</var> be zero.
-
-  <li>While <var title="">offset</var> is zero, set <var title="">offset</var> to 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="">node</var> and then set <var title="">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="">range</var> be a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <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>
-  (<var title="">node</var>, <var title="">offset</var>).
-
-  <li><a href=#block-extend>Block-extend</a> <var title="">range</var>, and let <var title="">new range</var>
-  be the result.
-
-  <li>Return false if <var title="">new range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-before title=concept-bp-before>before</a>
-  (<var title="">node</var>, <var title="">offset</var>), true otherwise.
-</ol>
-
-<p>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> <dfn id=precedes-a-line-break>precedes a line break</dfn> if the following
-algorithm returns true:
-
-<ol>
-  <li>Let <var title="">offset</var> be 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="">node</var>.
-
-  <li>While <var title="">offset</var> is 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="">node</var>, set
-  <var title="">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="">node</var> and then set
-  <var title="">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="">range</var> be a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <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>
-  (<var title="">node</var>, <var title="">offset</var>).
-
-  <li><a href=#block-extend>Block-extend</a> <var title="">range</var>, and let <var title="">new range</var>
-  be the result.
-
-  <li>Return false if <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> is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-after title=concept-bp-after>after</a>
-  (<var title="">node</var>, <var title="">offset</var>), true otherwise.
-</ol>
-
 
 <h3 id=wrapping-a-list-of-nodes><span class=secno>6.2 </span>Wrapping a list of nodes</h3>
 
@@ -1057,6 +1030,132 @@
 </ol>
 
 
+<h3 id=allowed-children><span class=secno>6.3 </span>Allowed children</h3>
+
+<p>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> or string <var title="">child</var> is an <dfn id=allowed-child>allowed child</dfn> of 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> or string <var title="">parent</var> if the following algorithm returns true:
+
+<div class=XXX>
+<p>This list doesn't currently match HTML's validity requirements for a few
+reasons:
+
+<ol>
+  <li>We need to handle invalid elements, which have no conformance
+  requirements but should be treated properly.  In particular, they can
+  interfere with serialization (e.g., center cannot descend from p).
+
+  <li>Sometimes users give instructions that have to produce invalid DOMs to
+  get the expected effect, like indenting the first item of a list.
+
+  <li>The HTML validity requirements are sometimes quite complicated.
+
+  <li>I just haven't had bothered to be systematic about it yet&nbsp;&ndash;
+  I've only covered what's come up in my tests.
+</ol>
+</div>
+
+<ol>
+  <li>If <var title="">parent</var> is "colgroup", "table", "tbody", "tfoot", "thead",
+  "tr", or an <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> equal to one of
+  those, and <var title="">child</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node whose <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> does not
+  consist solely of <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#space-character title="space character">space characters</a>, return false.
+
+  <li>If <var title="">parent</var> is "script", "style", "plaintext", or "xmp", or an
+  <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> equal to one of those, and
+  <var title="">child</var> is not a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, return false.
+  <!-- Actually, no node can occur in the DOM after plaintext, generally.  But
+  let's not get too carried away. -->
+
+  <li>If <var title="">child</var> is 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>, <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>, or
+  <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documenttype>DocumentType</a></code>, return false.
+
+  <li>If <var title="">child</var> is an <a href=#html-element>HTML element</a>, set <var title="">child</var>
+  to the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> of <var title="">child</var>.
+
+  <li>If <var title="">child</var> is not a string, return true.
+
+  <li>If <var title="">parent</var> is an <a href=#html-element>HTML element</a>:
+
+  <ol>
+    <li>If <var title="">child</var> is "a", and <var title="">parent</var> or some <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="">parent</var> is an <code class=external data-anolis-spec=html title="the a element"><a href=http://www.whatwg.org/html/#the-a-element>a</a></code>, return false.
+    <!-- Cannot be serialized as text/html.  In some cases it can, like
+    <a>foo<table><td><a>bar</a></td></table>baz</a>, but it's invalid in those
+    cases too, so no need for complication. -->
+
+    <li>If <var title="">child</var> is a <a href=#prohibited-paragraph-child-name>prohibited paragraph child name</a>
+    and <var title="">parent</var> or some <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="">parent</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 <a href=#element-with-inline-contents>element with inline contents</a>, return false.
+    <!-- This generally cannot be serialized either, for p.  For elements with
+    inline contents, this serves to prevent things like
+    <span><p>foo</p></span>, which will parse fine but aren't supposed to
+    happen anyway. -->
+
+    <li>If <var title="">child</var> is "h1", "h2", "h3", "h4", "h5", or "h6", and
+    <var title="">parent</var> or some <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="">parent</var> is an
+    <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> "h1", "h2", "h3", "h4", "h5",
+    or "h6", return false.
+    <!-- Nor this. -->
+
+    <li>Let <var title="">parent</var> be the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> of <var title="">parent</var>.
+    <!-- Further requirements only care about the parent itself, not ancestors,
+    so we don't need to know the node itself. -->
+  </ol>
+
+  <li>If <var title="">parent</var> is 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 <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>, return
+  true.
+
+  <li>If <var title="">parent</var> is not a string, return false.
+
+  <li>If <var title="">parent</var> is in the following table, then return true if
+  <var title="">child</var> is listed as an allowed child, and false otherwise.
+  <!-- We allow children even where some intervening nodes will be inserted,
+  like tr as a child of table. -->
+
+  <table>
+    <tr><th>Parent <th>Allowed children
+    <tr><td>colgroup <td>col
+    <tr><td>table <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
+    <tr><td>tbody, tfoot, thead <td>td, th, tr
+    <tr><td>tr <td>td, th
+    <tr><td>dl <td>dt, dd
+    <tr><td>dir, ol, ul <td>dir, li, ol, ul
+    <tr><td>hgroup <td>h1, h2, h3, h4, h5, h6
+  </table>
+
+  <li>If <var title="">child</var> is "body", "caption", "col", "colgroup", "frame",
+  "frameset", "head", "html", "tbody", "td", "tfoot", "th", "thead", or "tr",
+  return false.
+
+  <!-- dd/dt/li will serialize fine as the child of random stuff, but it makes
+  no sense at all, so we want to avoid it anyway. -->
+  <li>If <var title="">child</var> is "dd" or "dt" and <var title="">parent</var> is not "dl",
+  return false.
+
+  <li>If <var title="">child</var> is "li" and <var title="">parent</var> is not "ol" or "ul",
+  return false.
+
+  <li>If <var title="">parent</var> is in the following table and <var title="">child</var> is
+  listed as a prohibited child, return false.
+
+  <table>
+    <tr><th>Parent <th>Prohibited children
+    <tr><td>a <td>a
+    <tr><td>dd, dt <td>dd, dt
+    <tr><td>h1, h2, h3, h4, h5, h6 <td>h1, h2, h3, h4, h5, h6
+    <tr><td>li <td>li
+    <tr><td>nobr <td>nobr
+    <tr><td>p, all <a href=#name-of-an-element-with-inline-contents title="name of an element with inline contents">names
+          of an element with inline contents</a>
+        <td>All <a href=#prohibited-paragraph-child-name title="prohibited paragraph child name">prohibited
+          paragraph child names</a>
+    <tr><td>td, th <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
+  </table>
+
+  <li>Return true.
+</ol>
+
+
 <h2 id=inline-formatting-commands><span class=secno>7 </span>Inline formatting commands</h2>
 
 <h3 id=inline-formatting-command-definitions><span class=secno>7.1 </span>Inline formatting command definitions</h3>
@@ -2689,6 +2788,10 @@
   <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>.
 
+  <p class=XXX>Splitting the parent is really a block algorithm.  It's not
+  clear whether it's desirable to use for inline nodes.  Perhaps it's okay, but
+  it makes me a little uneasy.
+
   <li>For each of the entries in the following list, in the given order,
   <a href="#set-the-selection's-value">set the selection's value</a> to null, with <var title="">command</var> as
   given.
@@ -2897,19 +3000,6 @@
 
 <h3 id=block-formatting-command-definitions><span class=secno>8.1 </span>Block formatting command definitions</h3>
 
-<p>A <dfn id=prohibited-paragraph-child-name>prohibited paragraph child name</dfn> is "address", "article",
-"aside", "blockquote", "caption", "center", "col", "colgroup", "dd", "details",
-"dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form",
-"h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "listing",
-"menu", "nav", "ol", "p", "plaintext", "pre", "section", "summary", "table",
-"tbody", "td", "tfoot", "th", "thead", "tr", "ul", or "xmp".
-
-<p>A <dfn id=prohibited-paragraph-child>prohibited paragraph child</dfn> is an <a href=#html-element>HTML element</a>
-whose <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> is a <a href=#prohibited-paragraph-child-name>prohibited paragraph child name</a>.
-<!-- These are all the things that will close a <p> if found as a descendant.
-I think.  Plus table stuff, since that can't be a descendant of a p either,
-although it won't auto-close it. -->
-
 <p>A <dfn id=name-of-an-element-with-inline-contents>name of an element with inline contents</dfn> is "a", "abbr", "b",
 "bdi", "bdo", "cite", "code", "dfn", "em", "h1", "h2", "h3", "h4", "h5", "h6",
 "i", "kbd", "mark", "pre", "q", "rp", "rt", "ruby", "s", "samp", "small",
@@ -3004,245 +3094,6 @@
   of <var title="">node</var>.
 </ol>
 
-<p>To <dfn id=split-the-parent>split the parent</dfn> of a list <var title="">node list</var> of consecutive
-<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-sibling title=concept-tree-sibling>sibling</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>nodes</a>:
-
-<p class=XXX>Pretty much any time we call this algorithm, it can cause trouble
-if the parent had styles, classes, etc.  There's not going to be any general
-way to handle this, but we should at least try to handle the special case of
-inline styles, because Firefox does actually add them to arbitrary elements.
-Also, when splitting out of an inline parent, it might be good to wrap all the
-inline descendants in a clone of the former parent.
-
-<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 the first member of
-  <var title="">node list</var>.
-
-  <li>If <var title="">original parent</var> is not <a href=#editable>editable</a> 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 null, do nothing and abort these steps.
-
-  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is in <var title="">node
-  list</var>, <a href=#remove-extraneous-line-breaks-before>remove extraneous line breaks before</a> <var title="">original
-  parent</var>.
-
-  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is in <var title="">node
-  list</var>, and <var title="">original parent</var> <a href=#follows-a-line-break>follows a line break</a>,
-  set <var title="">follows line break</var> to true.  Otherwise, set <var title="">follows line
-  break</var> to false.
-
-  <li>If 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="">original parent</var> is in <var title="">node
-  list</var>, and <var title="">original parent</var> <a href=#precedes-a-line-break>precedes a line
-  break</a>, set <var title="">precedes line break</var> to true.  Otherwise, set
-  <var title="">precedes line break</var> to false.
-
-  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is not in <var title="">node
-  list</var>, but 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:
-
-  <div class=XXX>
-  <p>We insert things after the parent.  This is bad, because it will cause
-  them to become part of any ranges that immediately follow.  For instance, if
-  we're hitting "bar" in
-
-  </p><xmp><div><p>foo<p>bar</div>{<p>baz}</xmp>
-
-  <p>it becomes
-
-  </p><xmp><div><p>foo</div>{<p>bar<p>baz}</xmp>
-
-  <p>instead of
-
-  </p><xmp><div><p>foo</div><p>bar{<p>baz}</xmp>
-
-  <p>because of how range mutation rules work.  This doesn't happen if we
-  insert before.  Probably this isn't important enough to try working around,
-  though.
-  </div>
-
-  <ol>
-    <li>For each <var title="">node</var> in <var title="">node list</var>, <em>in reverse
-    order</em>, insert <var title="">node</var> into 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="">original
-    parent</var> immediately after <var title="">original parent</var>, <a href=#preserving-ranges>preserving
-    ranges</a>.
-
-    <li>If <var title="">precedes line break</var> is true, and the last member of
-    <var title="">node list</var> does not <a href=#precedes-a-line-break title="precedes a line break">precede a
-    line break</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and
-    insert the result immediately after the last member of <var title="">node
-    list</var>.
-
-    <li><a href=#remove-extraneous-line-breaks-at-the-end-of>Remove extraneous line breaks at the end of</a> <var title="">original
-    parent</var>.
-
-    <li>Abort these steps.
-  </ol>
-
-  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is not in <var title="">node
-  list</var>:
-
-  <ol>
-    <li>Let <var title="">cloned parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Node-cloneNode><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-clonenode>cloneNode(false)</a></code>
-    on <var title="">original parent</var>.
-
-    <li>If <var title="">original parent</var> has an <code class=external data-anolis-spec=html title="the id attribute"><a href=http://www.whatwg.org/html/#the-id-attribute>id</a></code> attribute, unset it.
-
-    <li>Insert <var title="">cloned parent</var> into 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="">original
-    parent</var> immediately before <var title="">original parent</var>.
-
-    <li>While 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 first member of <var title="">node
-    list</var> is not null, append the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original
-    parent</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="">cloned parent</var>,
-    <a href=#preserving-ranges>preserving ranges</a>.
-  </ol>
-
-  <li>For each <var title="">node</var> in <var title="">node list</var>, insert <var title="">node</var>
-  into 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="">original parent</var> immediately before
-  <var title="">original parent</var>, <a href=#preserving-ranges>preserving ranges</a>.
-  <!-- Notice that a boundary point that was immediately before the element
-  will now be immediately before its children, just because of the regular
-  range mutation rules, without needing to worry about preserving ranges.
-  Likewise for boundary points immediately after the element, if we wind up
-  removing the element in the final step.  Preserving ranges is only necessary
-  for the sake of boundary points in the element or its descendants. -->
-
-  <li>If <var title="">follows line break</var> is true, and the first member of
-  <var title="">node list</var> does not <a href=#follows-a-line-break title="follows a line break">follow a
-  line break</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and
-  insert the result immediately before the first member of <var title="">node
-  list</var>.
-
-  <li>If the last member of <var title="">node list</var> is an <a href=#inline-node>inline node</a>
-  other than 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 first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</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 <var title="">original parent</var> is not an <a href=#inline-node>inline node</a>,
-  remove the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> from <var title="">original
-  parent</var>.
-
-  <li>If <var title="">original parent</var> has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>:
-
-  <ol>
-    <li>Remove <var title="">original parent</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="">precedes line break</var> is true, and the last member of
-    <var title="">node list</var> does not <a href=#precedes-a-line-break title="precedes a line break">precede a
-    line break</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and
-    insert the result immediately after the last member of <var title="">node
-    list</var>.
-  </ol>
-
-  <li>Otherwise, <a href=#remove-extraneous-line-breaks-before>remove extraneous line breaks before</a>
-  <var title="">original parent</var>.
-
-  <li>If <var title="">node list</var>'s last member's <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> is null,
-  but 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 not null, <a href=#remove-extraneous-line-breaks-at-the-end-of>remove extraneous line breaks at the
-  end of</a> <var title="">node list</var>'s last member'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>.
-  <!-- The parent might be null if it's a br that we removed in the last step,
-  in which case this step isn't necessary. -->
-</ol>
-
-<p>To remove 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> while <dfn id=preserving-its-descendants>preserving its
-descendants</dfn>, <a href=#split-the-parent>split the parent</a> of <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-child title=concept-tree-child>children</a>.
-
-<p>To <dfn id=indent>indent</dfn> a list <var title="">node list</var> of consecutive <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-sibling title=concept-tree-sibling>sibling</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>nodes</a>:
-<!--
-We have to handle entire lists of siblings at once, or else we'd wind up doing
-something like
-
-  <ol>
-    {<li>foo</li>
-    <ol><li>bar</li></ol>}
-  </ol>
-  ->
-  <ol><ol>
-    <li>foo</li>
-    <li>bar</li>
-  </ol></ol>
-  ->
-  <ol><ol><ol>
-    <li>foo</li>
-    <li>bar</li>
-  </ol></ol></ol>
-
-since by the time we got to doing the <ol> that originally contained "bar", we
-won't remember that we aren't supposed to indent "foo" a second time.
--->
-
-<ol>
-  <li>If <var title="">node list</var> is empty, do nothing and abort these steps.
-
-  <li>Let <var title="">first node</var> be the first member of <var title="">node list</var>.
-
-  <li>If <var title="">first 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> 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>:
-
-  <ol>
-    <li>Let <var title="">tag</var> be the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> 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="">first node</var>.
-
-    <li><a href=#wrap>Wrap</a> <var title="">node list</var>, with <a href=#sibling-criteria>sibling
-    criteria</a> matching only <a href=#html-element title="HTML element">HTML
-    elements</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> <var title="">tag</var> 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(<var title="">tag</var>)</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="">first node</var>.
-    <!--
-    This matches IE9, Firefox 4.0, and Chrome 12 dev.  If there's a preceding
-    <li>, Opera 11.10 instead adds the new parent to the end of that <li>, so
-    it's not the child of another list, which is invalid.  But the other
-    browsers' way of doing things makes things simpler.  E.g., if we want to
-    indent an <li> and it has <ol>/<ul> children, we have to distinguish
-    between the case where we want to indent the whole <li> or only the first
-    part.  It also allows things like
-
-      <ol><li>
-        foo
-        <ol><li>bar</li></ol>
-        baz
-      </li></ol>
-
-    in which case it's unclear what we should do if the user selects "foo" and
-    indents.  I've filed a bug on HTML5:
-
-    http://www.w3.org/Bugs/Public/show_bug.cgi?id=12609
-    -->
-
-    <li>Abort these steps.
-  </ol>
-
-  <!--
-  Firefox 4.0 respects the CSS styling flag for indent, but Chrome 12 dev does
-  not.  I always produce blockquotes, even if CSS styling is on, for two
-  reasons.  One, IE9 handles inline margin attributes badly: when outdenting,
-  it propagates the margin to the parent, which doesn't actually remove it.
-  Two, in CSS mode I'd want to use <div style="margin: 1em 40px"> to match
-  non-CSS mode, but authors are very likely to want to remove the top/bottom
-  margin, which they can't do if it's not a special tag.  Authors who really
-  want divs for indentation could always convert the blockquotes to divs
-  themselves.  But if people really want it, I could respect CSS styling mode
-  here too.
-
-  The top/bottom margins might be undesirable here, but no more so than for
-  <ol>/<ul>/<p>/etc.  Here as there, authors can remove them with CSS if they
-  want.
-  -->
-
-  <li><a href=#wrap>Wrap</a> <var title="">node list</var>, with <a href=#sibling-criteria>sibling
-  criteria</a> matching any <a href=#indentation-element>indentation element</a>, and <a href=#new-parent-instructions>new
-  parent instructions</a> to return 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("blockquote")</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="">first node</var>.  Let <var title="">new parent</var> be the
-  result.
-  <!--
-  This indents on both sides, so we don't have to worry about directionality.
-  In theory it would be better if we indented only on the start side, but that
-  requires care to get right in mixed-direction cases.  Even once browsers
-  start to support margin-start and so on, we can't use them because a) we have
-  to work okay in legacy browsers and b) it doesn't help if a descendant block
-  has different direction (so should be indented the other way).  So let's not
-  worry about it: most browsers don't, and the ones that do get it wrong.  Just
-  indent on both sides.
-  -->
-
-  <li><a href=#fix-disallowed-ancestors>Fix disallowed ancestors</a> of <var title="">new parent</var>.
-</ol>
-
 <p>To <dfn id=normalize-sublists>normalize sublists</dfn> in 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="">item</var>:
 <!--
 This algorithm implies that we don't support a sublist in the middle of an
@@ -3348,194 +3199,6 @@
   <li>Return "none".
 </ol>
 
-<p>The <dfn id=canonical-space-sequence>canonical space sequence</dfn> of length <var title="">n</var>, with boolean
-flags <var title="">non-breaking start</var> and <var title="">non-breaking end</var>, is
-returned by the following algorithm:
-<!-- See long comment before insertText. -->
-
-<ol>
-  <li>If <var title="">n</var> is zero, return the empty string.
-
-  <li>If <var title="">n</var> is one and both <var title="">non-breaking start</var> and
-  <var title="">non-breaking end</var> are false, return a single space (U+0020).
-
-  <li>If <var title="">n</var> is one, return a single non-breaking space (U+00A0).
-
-  <li>Let <var title="">buffer</var> be the empty string.
-
-  <li>If <var title="">non-breaking start</var> is true, let <var title="">repeated pair</var> be
-  U+00A0 U+0020.  Otherwise, let it be U+0020 U+00A0.
-
-  <li>While <var title="">n</var> is greater than three, append <var title="">repeated pair</var>
-  to <var title="">buffer</var> and subtract two from <var title="">n</var>.
-
-  <li>If <var title="">n</var> is three, append a three-<a href=http://es5.github.com/#x8.4>element</a> string to
-  <var title="">buffer</var> depending on <var title="">non-breaking start</var> and
-  <var title="">non-breaking end</var>:
-
-  <dl class=switch>
-    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> false
-    <dd>U+0020 U+00A0 U+0020
-
-    <dt><var title="">non-breaking start</var> true, <var title="">non-breaking end</var> false
-    <dd>U+00A0 U+00A0 U+0020
-
-    <dt><var title="">non-breaking start</var> false, <var title="">non-breaking end</var> true
-    <dd>U+0020 U+00A0 U+00A0
-
-    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> both true
-    <dd>U+00A0 U+0020 U+00A0
-  </dl>
-
-  <li>Otherwise, append a two-<a href=http://es5.github.com/#x8.4>element</a> string to <var title="">buffer</var> depending
-  on <var title="">non-breaking start</var> and <var title="">non-breaking end</var>:
-
-  <dl class=switch>
-    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> false
-    <dt><var title="">non-breaking start</var> true, <var title="">non-breaking end</var> false
-    <dd>U+00A0 U+0020
-
-    <dt><var title="">non-breaking start</var> false, <var title="">non-breaking end</var> true
-    <dd>U+0020 U+00A0
-
-    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> both true
-    <dd>U+00A0 U+00A0
-  </dl>
-
-  <li>Return <var title="">buffer</var>.
-</ol>
-
-<p>To <dfn id=canonicalize-whitespace>canonicalize whitespace</dfn> at (<var title="">node</var>,
-<var title="">offset</var>):
-
-<ol>
-  <li>If <var title="">node</var> is neither <a href=#editable>editable</a> nor an <a href=#editing-host>editing
-  host</a>, abort these steps.
-
-  <li>Let <var title="">start node</var> equal <var title="">node</var> and let <var title="">start
-  offset</var> equal <var title="">offset</var>.
-
-  <!-- First go to the beginning of the current whitespace run. -->
-  <li>Repeat the following steps:
-
-  <ol>
-    <li>If <var title="">start node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> <a href=#in-the-same-editing-host>in the same editing
-    host</a> 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> minus one, set
-    <var title="">start node</var> to that <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>, then set <var title="">start offset</var>
-    to <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>.
-
-    <li>Otherwise, if <var title="">start offset</var> is zero and <var title="">start node</var>
-    does not <a href=#follows-a-line-break title="follows a line break">follow a line break</a> and
-    <var title="">start 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> is <a href=#in-the-same-editing-host>in the same editing
-    host</a>, set <var title="">start offset</var> to <var title="">start node</var>'s
-    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, then set <var title="">start 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>.
-
-    <p class=XXX>Following a line break is unlikely to be the right criterion.
-
-    <li>Otherwise, if <var title="">start node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and 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>'s <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> for "white-space" is neither "pre" nor "pre-wrap"
-    and <var title="">start offset</var> is not zero and the (<var title="">start offset</var>
-    &minus; 1)st <a href=http://es5.github.com/#x8.4>element</a> of <var title="">start node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a space
-    (0x0020) or non-breaking space (0x00A0), subtract one from <var title="">start
-    offset</var>.
-
-    <li>Otherwise, break from this loop.
-  </ol>
-
-  <!-- Now collapse any consecutive spaces. -->
-  <li>Let <var title="">end node</var> equal <var title="">start node</var> and <var title="">end
-  offset</var> equal <var title="">start offset</var>.
-
-  <li>Let <var title="">length</var> equal zero.
-
-  <li>Let <var title="">follows space</var> be false.
-
-  <li>Repeat the following steps:
-
-  <ol>
-    <li>If <var title="">end node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> <a href=#in-the-same-editing-host>in the same editing
-    host</a> 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>, set <var title="">end node</var>
-    to that <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>, then set <var title="">end offset</var> to zero.
-
-    <li>Otherwise, if <var title="">end offset</var> is <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>
-    and <var title="">end node</var> does not <a href=#precedes-a-line-break title="precedes a line
-    break">precede a line break</a> and <var title="">end 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> is
-    <a href=#in-the-same-editing-host>in the same editing host</a>, set <var title="">end offset</var> to one
-    plus <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, 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>.
-
-    <p class=XXX>Preceding a line break is unlikely to be the right criterion.
-
-    <li>Otherwise, if <var title="">end node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and 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>'s <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> for "white-space" is neither "pre" nor "pre-wrap"
-    and <var title="">end offset</var> is not <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> and the
-    <var title="">end offset</var>th <a href=http://es5.github.com/#x8.4>element</a> of <var title="">end node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a
-    space (0x0020) or non-breaking space (0x00A0):
-
-    <ol>
-      <li>If <var title="">follows space</var> is true and the <var title="">end offset</var>th
-      <a href=http://es5.github.com/#x8.4>element</a> of <var title="">end node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a space (0x0020), call
-      <code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(<var title="">end offset</var>, 1)</a></code> on <var title="">end node</var>, then
-      continue this loop from the beginning.
-
-      <li>Set <var title="">follows space</var> to true if the <var title="">end offset</var>th
-      <a href=http://es5.github.com/#x8.4>element</a> of <var title="">end node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a space (0x0020), false
-      otherwise.
-
-      <li>Add one to <var title="">end offset</var>.
-
-      <li>Add one to <var title="">length</var>.
-    </ol>
-
-    <li>Otherwise, break from this loop.
-  </ol>
-
-  <!-- Now replace with the canonical sequence. -->
-  <li>Let <var title="">replacement whitespace</var> be the <a href=#canonical-space-sequence>canonical space
-  sequence</a> of length <var title="">length</var>.  <var title="">non-breaking start</var>
-  is true if <var title="">start offset</var> is zero and <var title="">start node</var>
-  <a href=#follows-a-line-break>follows a line break</a>, and false otherwise.  <var title="">non-breaking
-  end</var> is true if <var title="">end offset</var> is <var title="">end node</var>'s
-  <code class=external data-anolis-spec=domcore title=dom-CharacterData-length><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-length>length</a></code> and <var title="">end node</var> <a href=#precedes-a-line-break>precedes a line break</a>, and
-  false otherwise.
-
-  <li>While (<var title="">start node</var>, <var title="">start offset</var>) is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-before title=concept-bp-before>before</a>
-  (<var title="">end node</var>, <var title="">end offset</var>):
-
-  <ol>
-    <li>If <var title="">start node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> 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>, set <var title="">start node</var> to that <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>, then set
-    <var title="">start offset</var> to zero.
-
-    <li>Otherwise, if <var title="">start node</var> is not a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node or if
-    <var title="">start offset</var> is <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, set
-    <var title="">start offset</var> to one plus <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, then
-    set <var title="">start 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:
-
-    <ol>
-      <li>Remove the first <a href=http://es5.github.com/#x8.4>element</a> from <var title="">replacement whitespace</var>,
-      and let <var title="">element</var> be that <a href=http://es5.github.com/#x8.4>element</a>.
-
-      <li>If <var title="">element</var> is not the same as the <var title="">start
-      offset</var>th <a href=http://es5.github.com/#x8.4>element</a> of <var title="">start node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code>:
-
-      <ol>
-        <!-- We need to insert then delete, so that we don't change range
-        boundary points. -->
-        <li>Call <code class=external data-anolis-spec=domcore title=dom-CharacterData-insertData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-insertdata>insertData(<var title="">start offset</var>, <var title="">element</var>)</a></code> on
-        <var title="">start node</var>.
-
-        <li>Call <code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(<var title="">start offset</var> + 1, 1)</a></code> on
-        <var title="">start node</var>.
-      </ol>
-
-      <li>Add one to <var title="">start offset</var>.
-    </ol>
-  </ol>
-</ol>
-
 <p>The <dfn id=alignment-value>alignment value</dfn> of 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> is returned by
 the following algorithm:
 <!--
@@ -3570,133 +3233,7 @@
 </ol>
 
 
-<h3 id=allowed-children><span class=secno>8.3 </span>Allowed children</h3>
-
-<p>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> or string <var title="">child</var> is an <dfn id=allowed-child>allowed child</dfn> of 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> or string <var title="">parent</var> if the following algorithm returns true:
-
-<div class=XXX>
-<p>This list doesn't currently match HTML's validity requirements for a few
-reasons:
-
-<ol>
-  <li>We need to handle invalid elements, which have no conformance
-  requirements but should be treated properly.  In particular, they can
-  interfere with serialization (e.g., center cannot descend from p).
-
-  <li>Sometimes users give instructions that have to produce invalid DOMs to
-  get the expected effect, like indenting the first item of a list.
-
-  <li>The HTML validity requirements are sometimes quite complicated.
-
-  <li>I just haven't had bothered to be systematic about it yet&nbsp;&ndash;
-  I've only covered what's come up in my tests.
-</ol>
-</div>
-
-<ol>
-  <li>If <var title="">parent</var> is "colgroup", "table", "tbody", "tfoot", "thead",
-  "tr", or an <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> equal to one of
-  those, and <var title="">child</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node whose <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> does not
-  consist solely of <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#space-character title="space character">space characters</a>, return false.
-
-  <li>If <var title="">parent</var> is "script", "style", "plaintext", or "xmp", or an
-  <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> equal to one of those, and
-  <var title="">child</var> is not a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, return false.
-  <!-- Actually, no node can occur in the DOM after plaintext, generally.  But
-  let's not get too carried away. -->
-
-  <li>If <var title="">child</var> is 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>, <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>, or
-  <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documenttype>DocumentType</a></code>, return false.
-
-  <li>If <var title="">child</var> is an <a href=#html-element>HTML element</a>, set <var title="">child</var>
-  to the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> of <var title="">child</var>.
-
-  <li>If <var title="">child</var> is not a string, return true.
-
-  <li>If <var title="">parent</var> is an <a href=#html-element>HTML element</a>:
-
-  <ol>
-    <li>If <var title="">child</var> is "a", and <var title="">parent</var> or some <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="">parent</var> is an <code class=external data-anolis-spec=html title="the a element"><a href=http://www.whatwg.org/html/#the-a-element>a</a></code>, return false.
-    <!-- Cannot be serialized as text/html.  In some cases it can, like
-    <a>foo<table><td><a>bar</a></td></table>baz</a>, but it's invalid in those
-    cases too, so no need for complication. -->
-
-    <li>If <var title="">child</var> is a <a href=#prohibited-paragraph-child-name>prohibited paragraph child name</a>
-    and <var title="">parent</var> or some <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="">parent</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 <a href=#element-with-inline-contents>element with inline contents</a>, return false.
-    <!-- This generally cannot be serialized either, for p.  For elements with
-    inline contents, this serves to prevent things like
-    <span><p>foo</p></span>, which will parse fine but aren't supposed to
-    happen anyway. -->
-
-    <li>If <var title="">child</var> is "h1", "h2", "h3", "h4", "h5", or "h6", and
-    <var title="">parent</var> or some <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="">parent</var> is an
-    <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> "h1", "h2", "h3", "h4", "h5",
-    or "h6", return false.
-    <!-- Nor this. -->
-
-    <li>Let <var title="">parent</var> be the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> of <var title="">parent</var>.
-    <!-- Further requirements only care about the parent itself, not ancestors,
-    so we don't need to know the node itself. -->
-  </ol>
-
-  <li>If <var title="">parent</var> is 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 <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>, return
-  true.
-
-  <li>If <var title="">parent</var> is not a string, return false.
-
-  <li>If <var title="">parent</var> is in the following table, then return true if
-  <var title="">child</var> is listed as an allowed child, and false otherwise.
-  <!-- We allow children even where some intervening nodes will be inserted,
-  like tr as a child of table. -->
-
-  <table>
-    <tr><th>Parent <th>Allowed children
-    <tr><td>colgroup <td>col
-    <tr><td>table <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
-    <tr><td>tbody, tfoot, thead <td>td, th, tr
-    <tr><td>tr <td>td, th
-    <tr><td>dl <td>dt, dd
-    <tr><td>dir, ol, ul <td>dir, li, ol, ul
-    <tr><td>hgroup <td>h1, h2, h3, h4, h5, h6
-  </table>
-
-  <li>If <var title="">child</var> is "body", "caption", "col", "colgroup", "frame",
-  "frameset", "head", "html", "tbody", "td", "tfoot", "th", "thead", or "tr",
-  return false.
-
-  <!-- dd/dt/li will serialize fine as the child of random stuff, but it makes
-  no sense at all, so we want to avoid it anyway. -->
-  <li>If <var title="">child</var> is "dd" or "dt" and <var title="">parent</var> is not "dl",
-  return false.
-
-  <li>If <var title="">child</var> is "li" and <var title="">parent</var> is not "ol" or "ul",
-  return false.
-
-  <li>If <var title="">parent</var> is in the following table and <var title="">child</var> is
-  listed as a prohibited child, return false.
-
-  <table>
-    <tr><th>Parent <th>Prohibited children
-    <tr><td>a <td>a
-    <tr><td>dd, dt <td>dd, dt
-    <tr><td>h1, h2, h3, h4, h5, h6 <td>h1, h2, h3, h4, h5, h6
-    <tr><td>li <td>li
-    <tr><td>nobr <td>nobr
-    <tr><td>p, all <a href=#name-of-an-element-with-inline-contents title="name of an element with inline contents">names
-          of an element with inline contents</a>
-        <td>All <a href=#prohibited-paragraph-child-name title="prohibited paragraph child name">prohibited
-          paragraph child names</a>
-    <tr><td>td, th <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
-  </table>
-
-  <li>Return true.
-</ol>
-
-
-<h3 id=block-extending-a-range><span class=secno>8.4 </span>Block-extending a range</h3>
+<h3 id=block-extending-a-range><span class=secno>8.3 </span>Block-extending a range</h3>
 
 <p>When a user agent is to <dfn id=block-extend>block-extend</dfn> a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a>
 <var title="">range</var>, it must run the following steps:
@@ -3778,8 +3315,47 @@
   <li>Return <var title="">new range</var>.
 </ol>
 
-
-<h3 id=deleting-the-contents-of-a-range><span class=secno>8.5 </span>Deleting the contents of a range</h3>
+<p>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> <dfn id=follows-a-line-break>follows a line break</dfn> if the following
+algorithm returns true:
+
+<ol>
+  <li>Let <var title="">offset</var> be zero.
+
+  <li>While <var title="">offset</var> is zero, set <var title="">offset</var> to 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="">node</var> and then set <var title="">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="">range</var> be a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <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>
+  (<var title="">node</var>, <var title="">offset</var>).
+
+  <li><a href=#block-extend>Block-extend</a> <var title="">range</var>, and let <var title="">new range</var>
+  be the result.
+
+  <li>Return false if <var title="">new range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-before title=concept-bp-before>before</a>
+  (<var title="">node</var>, <var title="">offset</var>), true otherwise.
+</ol>
+
+<p>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> <dfn id=precedes-a-line-break>precedes a line break</dfn> if the following
+algorithm returns true:
+
+<ol>
+  <li>Let <var title="">offset</var> be 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="">node</var>.
+
+  <li>While <var title="">offset</var> is 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="">node</var>, set
+  <var title="">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="">node</var> and then set
+  <var title="">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="">range</var> be a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <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>
+  (<var title="">node</var>, <var title="">offset</var>).
+
+  <li><a href=#block-extend>Block-extend</a> <var title="">range</var>, and let <var title="">new range</var>
+  be the result.
+
+  <li>Return false if <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> is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-after title=concept-bp-after>after</a>
+  (<var title="">node</var>, <var title="">offset</var>), true otherwise.
+</ol>
+
+
+<h3 id=deleting-the-contents-of-a-range><span class=secno>8.4 </span>Deleting the contents of a range</h3>
 
 <p>To <dfn id=delete-the-contents>delete the contents</dfn> of a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> <var title="">range</var>:
 
@@ -4167,7 +3743,439 @@
 </ol>
 
 
-<h3 id=outdenting-a-node><span class=secno>8.6 </span>Outdenting a node</h3>
+<h3 id="splitting-a-node-list's-parent"><span class=secno>8.5 </span>Splitting a node list's parent</h3>
+
+<p>To <dfn id=split-the-parent>split the parent</dfn> of a list <var title="">node list</var> of consecutive
+<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-sibling title=concept-tree-sibling>sibling</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>nodes</a>:
+
+<p class=XXX>Pretty much any time we call this algorithm, it can cause trouble
+if the parent had styles, classes, etc.  There's not going to be any general
+way to handle this, but we should at least try to handle the special case of
+inline styles, because Firefox does actually add them to arbitrary elements.
+Also, when splitting out of an inline parent, it might be good to wrap all the
+inline descendants in a clone of the former parent.
+
+<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 the first member of
+  <var title="">node list</var>.
+
+  <li>If <var title="">original parent</var> is not <a href=#editable>editable</a> 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 null, do nothing and abort these steps.
+
+  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is in <var title="">node
+  list</var>, <a href=#remove-extraneous-line-breaks-before>remove extraneous line breaks before</a> <var title="">original
+  parent</var>.
+
+  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is in <var title="">node
+  list</var>, and <var title="">original parent</var> <a href=#follows-a-line-break>follows a line break</a>,
+  set <var title="">follows line break</var> to true.  Otherwise, set <var title="">follows line
+  break</var> to false.
+
+  <li>If 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="">original parent</var> is in <var title="">node
+  list</var>, and <var title="">original parent</var> <a href=#precedes-a-line-break>precedes a line
+  break</a>, set <var title="">precedes line break</var> to true.  Otherwise, set
+  <var title="">precedes line break</var> to false.
+
+  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is not in <var title="">node
+  list</var>, but 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:
+
+  <div class=XXX>
+  <p>We insert things after the parent.  This is bad, because it will cause
+  them to become part of any ranges that immediately follow.  For instance, if
+  we're hitting "bar" in
+
+  </p><xmp><div><p>foo<p>bar</div>{<p>baz}</xmp>
+
+  <p>it becomes
+
+  </p><xmp><div><p>foo</div>{<p>bar<p>baz}</xmp>
+
+  <p>instead of
+
+  </p><xmp><div><p>foo</div><p>bar{<p>baz}</xmp>
+
+  <p>because of how range mutation rules work.  This doesn't happen if we
+  insert before.  Probably this isn't important enough to try working around,
+  though.
+  </div>
+
+  <ol>
+    <li>For each <var title="">node</var> in <var title="">node list</var>, <em>in reverse
+    order</em>, insert <var title="">node</var> into 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="">original
+    parent</var> immediately after <var title="">original parent</var>, <a href=#preserving-ranges>preserving
+    ranges</a>.
+
+    <li>If <var title="">precedes line break</var> is true, and the last member of
+    <var title="">node list</var> does not <a href=#precedes-a-line-break title="precedes a line break">precede a
+    line break</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and
+    insert the result immediately after the last member of <var title="">node
+    list</var>.
+
+    <li><a href=#remove-extraneous-line-breaks-at-the-end-of>Remove extraneous line breaks at the end of</a> <var title="">original
+    parent</var>.
+
+    <li>Abort these steps.
+  </ol>
+
+  <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is not in <var title="">node
+  list</var>:
+
+  <ol>
+    <li>Let <var title="">cloned parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Node-cloneNode><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-clonenode>cloneNode(false)</a></code>
+    on <var title="">original parent</var>.
+
+    <li>If <var title="">original parent</var> has an <code class=external data-anolis-spec=html title="the id attribute"><a href=http://www.whatwg.org/html/#the-id-attribute>id</a></code> attribute, unset it.
+
+    <li>Insert <var title="">cloned parent</var> into 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="">original
+    parent</var> immediately before <var title="">original parent</var>.
+
+    <li>While 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 first member of <var title="">node
+    list</var> is not null, append the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original
+    parent</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="">cloned parent</var>,
+    <a href=#preserving-ranges>preserving ranges</a>.
+  </ol>
+
+  <li>For each <var title="">node</var> in <var title="">node list</var>, insert <var title="">node</var>
+  into 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="">original parent</var> immediately before
+  <var title="">original parent</var>, <a href=#preserving-ranges>preserving ranges</a>.
+  <!-- Notice that a boundary point that was immediately before the element
+  will now be immediately before its children, just because of the regular
+  range mutation rules, without needing to worry about preserving ranges.
+  Likewise for boundary points immediately after the element, if we wind up
+  removing the element in the final step.  Preserving ranges is only necessary
+  for the sake of boundary points in the element or its descendants. -->
+
+  <li>If <var title="">follows line break</var> is true, and the first member of
+  <var title="">node list</var> does not <a href=#follows-a-line-break title="follows a line break">follow a
+  line break</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and
+  insert the result immediately before the first member of <var title="">node
+  list</var>.
+
+  <li>If the last member of <var title="">node list</var> is an <a href=#inline-node>inline node</a>
+  other than 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 first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</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 <var title="">original parent</var> is not an <a href=#inline-node>inline node</a>,
+  remove the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> from <var title="">original
+  parent</var>.
+
+  <li>If <var title="">original parent</var> has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>:
+
+  <ol>
+    <li>Remove <var title="">original parent</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="">precedes line break</var> is true, and the last member of
+    <var title="">node list</var> does not <a href=#precedes-a-line-break title="precedes a line break">precede a
+    line break</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and
+    insert the result immediately after the last member of <var title="">node
+    list</var>.
+  </ol>
+
+  <li>Otherwise, <a href=#remove-extraneous-line-breaks-before>remove extraneous line breaks before</a>
+  <var title="">original parent</var>.
+
+  <li>If <var title="">node list</var>'s last member's <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> is null,
+  but 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 not null, <a href=#remove-extraneous-line-breaks-at-the-end-of>remove extraneous line breaks at the
+  end of</a> <var title="">node list</var>'s last member'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>.
+  <!-- The parent might be null if it's a br that we removed in the last step,
+  in which case this step isn't necessary. -->
+</ol>
+
+<p>To remove 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> while <dfn id=preserving-its-descendants>preserving its
+descendants</dfn>, <a href=#split-the-parent>split the parent</a> of <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-child title=concept-tree-child>children</a>.
+
+
+<h3 id=canonical-space-sequences><span class=secno>8.6 </span>Canonical space sequences</h3>
+
+<p>The <dfn id=canonical-space-sequence>canonical space sequence</dfn> of length <var title="">n</var>, with boolean
+flags <var title="">non-breaking start</var> and <var title="">non-breaking end</var>, is
+returned by the following algorithm:
+<!-- See long comment before insertText. -->
+
+<ol>
+  <li>If <var title="">n</var> is zero, return the empty string.
+
+  <li>If <var title="">n</var> is one and both <var title="">non-breaking start</var> and
+  <var title="">non-breaking end</var> are false, return a single space (U+0020).
+
+  <li>If <var title="">n</var> is one, return a single non-breaking space (U+00A0).
+
+  <li>Let <var title="">buffer</var> be the empty string.
+
+  <li>If <var title="">non-breaking start</var> is true, let <var title="">repeated pair</var> be
+  U+00A0 U+0020.  Otherwise, let it be U+0020 U+00A0.
+
+  <li>While <var title="">n</var> is greater than three, append <var title="">repeated pair</var>
+  to <var title="">buffer</var> and subtract two from <var title="">n</var>.
+
+  <li>If <var title="">n</var> is three, append a three-<a href=http://es5.github.com/#x8.4>element</a> string to
+  <var title="">buffer</var> depending on <var title="">non-breaking start</var> and
+  <var title="">non-breaking end</var>:
+
+  <dl class=switch>
+    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> false
+    <dd>U+0020 U+00A0 U+0020
+
+    <dt><var title="">non-breaking start</var> true, <var title="">non-breaking end</var> false
+    <dd>U+00A0 U+00A0 U+0020
+
+    <dt><var title="">non-breaking start</var> false, <var title="">non-breaking end</var> true
+    <dd>U+0020 U+00A0 U+00A0
+
+    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> both true
+    <dd>U+00A0 U+0020 U+00A0
+  </dl>
+
+  <li>Otherwise, append a two-<a href=http://es5.github.com/#x8.4>element</a> string to <var title="">buffer</var> depending
+  on <var title="">non-breaking start</var> and <var title="">non-breaking end</var>:
+
+  <dl class=switch>
+    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> false
+    <dt><var title="">non-breaking start</var> true, <var title="">non-breaking end</var> false
+    <dd>U+00A0 U+0020
+
+    <dt><var title="">non-breaking start</var> false, <var title="">non-breaking end</var> true
+    <dd>U+0020 U+00A0
+
+    <dt><var title="">non-breaking start</var> and <var title="">non-breaking end</var> both true
+    <dd>U+00A0 U+00A0
+  </dl>
+
+  <li>Return <var title="">buffer</var>.
+</ol>
+
+<p>To <dfn id=canonicalize-whitespace>canonicalize whitespace</dfn> at (<var title="">node</var>,
+<var title="">offset</var>):
+
+<ol>
+  <li>If <var title="">node</var> is neither <a href=#editable>editable</a> nor an <a href=#editing-host>editing
+  host</a>, abort these steps.
+
+  <li>Let <var title="">start node</var> equal <var title="">node</var> and let <var title="">start
+  offset</var> equal <var title="">offset</var>.
+
+  <!-- First go to the beginning of the current whitespace run. -->
+  <li>Repeat the following steps:
+
+  <ol>
+    <li>If <var title="">start node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> <a href=#in-the-same-editing-host>in the same editing
+    host</a> 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> minus one, set
+    <var title="">start node</var> to that <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>, then set <var title="">start offset</var>
+    to <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>.
+
+    <li>Otherwise, if <var title="">start offset</var> is zero and <var title="">start node</var>
+    does not <a href=#follows-a-line-break title="follows a line break">follow a line break</a> and
+    <var title="">start 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> is <a href=#in-the-same-editing-host>in the same editing
+    host</a>, set <var title="">start offset</var> to <var title="">start node</var>'s
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, then set <var title="">start 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>.
+
+    <p class=XXX>Following a line break is unlikely to be the right criterion.
+
+    <li>Otherwise, if <var title="">start node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and 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>'s <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> for "white-space" is neither "pre" nor "pre-wrap"
+    and <var title="">start offset</var> is not zero and the (<var title="">start offset</var>
+    &minus; 1)st <a href=http://es5.github.com/#x8.4>element</a> of <var title="">start node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a space
+    (0x0020) or non-breaking space (0x00A0), subtract one from <var title="">start
+    offset</var>.
+
+    <li>Otherwise, break from this loop.
+  </ol>
+
+  <!-- Now collapse any consecutive spaces. -->
+  <li>Let <var title="">end node</var> equal <var title="">start node</var> and <var title="">end
+  offset</var> equal <var title="">start offset</var>.
+
+  <li>Let <var title="">length</var> equal zero.
+
+  <li>Let <var title="">follows space</var> be false.
+
+  <li>Repeat the following steps:
+
+  <ol>
+    <li>If <var title="">end node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> <a href=#in-the-same-editing-host>in the same editing
+    host</a> 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>, set <var title="">end node</var>
+    to that <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>, then set <var title="">end offset</var> to zero.
+
+    <li>Otherwise, if <var title="">end offset</var> is <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>
+    and <var title="">end node</var> does not <a href=#precedes-a-line-break title="precedes a line
+    break">precede a line break</a> and <var title="">end 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> is
+    <a href=#in-the-same-editing-host>in the same editing host</a>, set <var title="">end offset</var> to one
+    plus <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, 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>.
+
+    <p class=XXX>Preceding a line break is unlikely to be the right criterion.
+
+    <li>Otherwise, if <var title="">end node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and 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>'s <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> for "white-space" is neither "pre" nor "pre-wrap"
+    and <var title="">end offset</var> is not <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> and the
+    <var title="">end offset</var>th <a href=http://es5.github.com/#x8.4>element</a> of <var title="">end node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a
+    space (0x0020) or non-breaking space (0x00A0):
+
+    <ol>
+      <li>If <var title="">follows space</var> is true and the <var title="">end offset</var>th
+      <a href=http://es5.github.com/#x8.4>element</a> of <var title="">end node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a space (0x0020), call
+      <code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(<var title="">end offset</var>, 1)</a></code> on <var title="">end node</var>, then
+      continue this loop from the beginning.
+
+      <li>Set <var title="">follows space</var> to true if the <var title="">end offset</var>th
+      <a href=http://es5.github.com/#x8.4>element</a> of <var title="">end node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is a space (0x0020), false
+      otherwise.
+
+      <li>Add one to <var title="">end offset</var>.
+
+      <li>Add one to <var title="">length</var>.
+    </ol>
+
+    <li>Otherwise, break from this loop.
+  </ol>
+
+  <!-- Now replace with the canonical sequence. -->
+  <li>Let <var title="">replacement whitespace</var> be the <a href=#canonical-space-sequence>canonical space
+  sequence</a> of length <var title="">length</var>.  <var title="">non-breaking start</var>
+  is true if <var title="">start offset</var> is zero and <var title="">start node</var>
+  <a href=#follows-a-line-break>follows a line break</a>, and false otherwise.  <var title="">non-breaking
+  end</var> is true if <var title="">end offset</var> is <var title="">end node</var>'s
+  <code class=external data-anolis-spec=domcore title=dom-CharacterData-length><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-length>length</a></code> and <var title="">end node</var> <a href=#precedes-a-line-break>precedes a line break</a>, and
+  false otherwise.
+
+  <li>While (<var title="">start node</var>, <var title="">start offset</var>) is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-before title=concept-bp-before>before</a>
+  (<var title="">end node</var>, <var title="">end offset</var>):
+
+  <ol>
+    <li>If <var title="">start node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> 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>, set <var title="">start node</var> to that <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>, then set
+    <var title="">start offset</var> to zero.
+
+    <li>Otherwise, if <var title="">start node</var> is not a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node or if
+    <var title="">start offset</var> is <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, set
+    <var title="">start offset</var> to one plus <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, then
+    set <var title="">start 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:
+
+    <ol>
+      <li>Remove the first <a href=http://es5.github.com/#x8.4>element</a> from <var title="">replacement whitespace</var>,
+      and let <var title="">element</var> be that <a href=http://es5.github.com/#x8.4>element</a>.
+
+      <li>If <var title="">element</var> is not the same as the <var title="">start
+      offset</var>th <a href=http://es5.github.com/#x8.4>element</a> of <var title="">start node</var>'s <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code>:
+
+      <ol>
+        <!-- We need to insert then delete, so that we don't change range
+        boundary points. -->
+        <li>Call <code class=external data-anolis-spec=domcore title=dom-CharacterData-insertData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-insertdata>insertData(<var title="">start offset</var>, <var title="">element</var>)</a></code> on
+        <var title="">start node</var>.
+
+        <li>Call <code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(<var title="">start offset</var> + 1, 1)</a></code> on
+        <var title="">start node</var>.
+      </ol>
+
+      <li>Add one to <var title="">start offset</var>.
+    </ol>
+  </ol>
+</ol>
+
+
+<h3 id=indenting-and-outdenting><span class=secno>8.7 </span>Indenting and outdenting</h3>
+
+<p>To <dfn id=indent>indent</dfn> a list <var title="">node list</var> of consecutive <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-sibling title=concept-tree-sibling>sibling</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>nodes</a>:
+<!--
+We have to handle entire lists of siblings at once, or else we'd wind up doing
+something like
+
+  <ol>
+    {<li>foo</li>
+    <ol><li>bar</li></ol>}
+  </ol>
+  ->
+  <ol><ol>
+    <li>foo</li>
+    <li>bar</li>
+  </ol></ol>
+  ->
+  <ol><ol><ol>
+    <li>foo</li>
+    <li>bar</li>
+  </ol></ol></ol>
+
+since by the time we got to doing the <ol> that originally contained "bar", we
+won't remember that we aren't supposed to indent "foo" a second time.
+-->
+<ol>
+  <li>If <var title="">node list</var> is empty, do nothing and abort these steps.
+
+  <li>Let <var title="">first node</var> be the first member of <var title="">node list</var>.
+
+  <li>If <var title="">first 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> 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>:
+
+  <ol>
+    <li>Let <var title="">tag</var> be the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> 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="">first node</var>.
+
+    <li><a href=#wrap>Wrap</a> <var title="">node list</var>, with <a href=#sibling-criteria>sibling
+    criteria</a> matching only <a href=#html-element title="HTML element">HTML
+    elements</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> <var title="">tag</var> 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(<var title="">tag</var>)</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="">first node</var>.
+    <!--
+    This matches IE9, Firefox 4.0, and Chrome 12 dev.  If there's a preceding
+    <li>, Opera 11.10 instead adds the new parent to the end of that <li>, so
+    it's not the child of another list, which is invalid.  But the other
+    browsers' way of doing things makes things simpler.  E.g., if we want to
+    indent an <li> and it has <ol>/<ul> children, we have to distinguish
+    between the case where we want to indent the whole <li> or only the first
+    part.  It also allows things like
+
+      <ol><li>
+        foo
+        <ol><li>bar</li></ol>
+        baz
+      </li></ol>
+
+    in which case it's unclear what we should do if the user selects "foo" and
+    indents.  I've filed a bug on HTML5:
+
+    http://www.w3.org/Bugs/Public/show_bug.cgi?id=12609
+    -->
+
+    <li>Abort these steps.
+  </ol>
+
+  <!--
+  Firefox 4.0 respects the CSS styling flag for indent, but Chrome 12 dev does
+  not.  I always produce blockquotes, even if CSS styling is on, for two
+  reasons.  One, IE9 handles inline margin attributes badly: when outdenting,
+  it propagates the margin to the parent, which doesn't actually remove it.
+  Two, in CSS mode I'd want to use <div style="margin: 1em 40px"> to match
+  non-CSS mode, but authors are very likely to want to remove the top/bottom
+  margin, which they can't do if it's not a special tag.  Authors who really
+  want divs for indentation could always convert the blockquotes to divs
+  themselves.  But if people really want it, I could respect CSS styling mode
+  here too.
+
+  The top/bottom margins might be undesirable here, but no more so than for
+  <ol>/<ul>/<p>/etc.  Here as there, authors can remove them with CSS if they
+  want.
+  -->
+
+  <li><a href=#wrap>Wrap</a> <var title="">node list</var>, with <a href=#sibling-criteria>sibling
+  criteria</a> matching any <a href=#indentation-element>indentation element</a>, and <a href=#new-parent-instructions>new
+  parent instructions</a> to return 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("blockquote")</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="">first node</var>.  Let <var title="">new parent</var> be the
+  result.
+  <!--
+  This indents on both sides, so we don't have to worry about directionality.
+  In theory it would be better if we indented only on the start side, but that
+  requires care to get right in mixed-direction cases.  Even once browsers
+  start to support margin-start and so on, we can't use them because a) we have
+  to work okay in legacy browsers and b) it doesn't help if a descendant block
+  has different direction (so should be indented the other way).  So let's not
+  worry about it: most browsers don't, and the ones that do get it wrong.  Just
+  indent on both sides.
+  -->
+
+  <li><a href=#fix-disallowed-ancestors>Fix disallowed ancestors</a> of <var title="">new parent</var>.
+</ol>
 
 <p>To <dfn id=outdent>outdent</dfn> 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>:
 
@@ -4363,7 +4371,7 @@
 </ol>
 
 
-<h3 id=toggling-lists><span class=secno>8.7 </span>Toggling lists</h3>
+<h3 id=toggling-lists><span class=secno>8.8 </span>Toggling lists</h3>
 
 <!--
 Research for insertOrderedList/insertUnorderedList: tested the following
@@ -4888,7 +4896,7 @@
 </ol>
 
 
-<h3 id=justifying-the-selection><span class=secno>8.8 </span>Justifying the selection</h3>
+<h3 id=justifying-the-selection><span class=secno>8.9 </span>Justifying the selection</h3>
 
 <!--
 There are two basic ways it works: using the align attribute, and using CSS
@@ -5006,7 +5014,7 @@
 </ol>
 
 
-<h3 id=the-delete-command><span class=secno>8.9 </span><dfn>The <code title="">delete</code> command</dfn></h3>
+<h3 id=the-delete-command><span class=secno>8.10 </span><dfn>The <code title="">delete</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>:
 
@@ -5284,7 +5292,7 @@
 </ol>
 
 
-<h3 id=the-formatblock-command><span class=secno>8.10 </span><dfn>The <code title="">formatBlock</code> command</dfn></h3>
+<h3 id=the-formatblock-command><span class=secno>8.11 </span><dfn>The <code title="">formatBlock</code> command</dfn></h3>
 
 <!--
 Tested browser versions: IE9, Firefox 4.0, Chrome 13 dev, Opera 11.10.
@@ -5587,7 +5595,7 @@
 </ol>
 
 
-<h3 id=the-forwarddelete-command><span class=secno>8.11 </span><dfn>The <code title="">forwardDelete</code> command</dfn></h3>
+<h3 id=the-forwarddelete-command><span class=secno>8.12 </span><dfn>The <code title="">forwardDelete</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>:
 <!-- Copy-pasted from delete, see there for comments. -->
@@ -5716,7 +5724,7 @@
 </ol>
 
 
-<h3 id=the-indent-command><span class=secno>8.12 </span><dfn>The <code title="">indent</code> command</dfn></h3>
+<h3 id=the-indent-command><span class=secno>8.13 </span><dfn>The <code title="">indent</code> command</dfn></h3>
 
 <!--
 IE9: Outputs <blockquote style="margin-right: 0px" dir="ltr">, or when
@@ -5817,7 +5825,7 @@
 </ol>
 
 
-<h3 id=the-inserthorizontalrule-command><span class=secno>8.13 </span><dfn>The <code title="">insertHorizontalRule</code> command</dfn></h3>
+<h3 id=the-inserthorizontalrule-command><span class=secno>8.14 </span><dfn>The <code title="">insertHorizontalRule</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>:
 
@@ -5873,7 +5881,7 @@
 </ol>
 
 
-<h3 id=the-inserthtml-command><span class=secno>8.14 </span><dfn>The <code title="">insertHTML</code> command</dfn></h3>
+<h3 id=the-inserthtml-command><span class=secno>8.15 </span><dfn>The <code title="">insertHTML</code> command</dfn></h3>
 
 <!--
 Not supported by IE9.  Handling of disallowed children is interesting:
@@ -5956,7 +5964,7 @@
 </ol>
 
 
-<h3 id=the-insertimage-command><span class=secno>8.15 </span><dfn>The <code title="">insertImage</code> command</dfn></h3>
+<h3 id=the-insertimage-command><span class=secno>8.16 </span><dfn>The <code title="">insertImage</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>:
 
@@ -6005,7 +6013,7 @@
 </ol>
 
 
-<h3 id=the-insertlinebreak-command><span class=secno>8.16 </span><dfn>The <code title="">insertLineBreak</code> command</dfn></h3>
+<h3 id=the-insertlinebreak-command><span class=secno>8.17 </span><dfn>The <code title="">insertLineBreak</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>:
 
@@ -6067,7 +6075,7 @@
 </ol>
 
 
-<h3 id=the-insertorderedlist-command><span class=secno>8.17 </span><dfn>The <code title="">insertOrderedList</code> command</dfn></h3>
+<h3 id=the-insertorderedlist-command><span class=secno>8.18 </span><dfn>The <code title="">insertOrderedList</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#toggle-lists>Toggle lists</a> with <var title="">tag name</var>
 "ol".
@@ -6092,7 +6100,7 @@
 -->
 
 
-<h3 id=the-insertparagraph-command><span class=secno>8.18 </span><dfn>The <code title="">insertParagraph</code> command</dfn></h3>
+<h3 id=the-insertparagraph-command><span class=secno>8.19 </span><dfn>The <code title="">insertParagraph</code> command</dfn></h3>
 
 <!--
 There are three major behaviors here.  Firefox 5.0a2 behaves identically to
@@ -6357,7 +6365,7 @@
 </ol>
 
 
-<h3 id=the-inserttext-command><span class=secno>8.19 </span><dfn>The <code title="">insertText</code> command</dfn></h3>
+<h3 id=the-inserttext-command><span class=secno>8.20 </span><dfn>The <code title="">insertText</code> command</dfn></h3>
 
 <!--
 Supported only by WebKit.  Tests in other browsers were manual.  In the manual
@@ -6538,7 +6546,7 @@
 </ol>
 
 
-<h3 id=the-insertunorderedlist-command><span class=secno>8.20 </span><dfn>The <code title="">insertUnorderedList</code> command</dfn></h3>
+<h3 id=the-insertunorderedlist-command><span class=secno>8.21 </span><dfn>The <code title="">insertUnorderedList</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#toggle-lists>Toggle lists</a> with <var title="">tag name</var>
 "ul".
@@ -6550,7 +6558,7 @@
 false otherwise.
 
 
-<h3 id=the-justifycenter-command><span class=secno>8.21 </span><dfn>The <code title="">justifyCenter</code> command</dfn></h3>
+<h3 id=the-justifycenter-command><span class=secno>8.22 </span><dfn>The <code title="">justifyCenter</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "center".
@@ -6615,7 +6623,7 @@
 -->
 
 
-<h3 id=the-justifyfull-command><span class=secno>8.22 </span><dfn>The <code title="">justifyFull</code> command</dfn></h3>
+<h3 id=the-justifyfull-command><span class=secno>8.23 </span><dfn>The <code title="">justifyFull</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "justify".
@@ -6638,7 +6646,7 @@
 <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>.  If there is no such <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>, return "left".
 
 
-<h3 id=the-justifyleft-command><span class=secno>8.23 </span><dfn>The <code title="">justifyLeft</code> command</dfn></h3>
+<h3 id=the-justifyleft-command><span class=secno>8.24 </span><dfn>The <code title="">justifyLeft</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "left".
@@ -6661,7 +6669,7 @@
 <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>.  If there is no such <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>, return "left".
 
 
-<h3 id=the-justifyright-command><span class=secno>8.24 </span><dfn>The <code title="">justifyRight</code> command</dfn></h3>
+<h3 id=the-justifyright-command><span class=secno>8.25 </span><dfn>The <code title="">justifyRight</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "right".
@@ -6684,7 +6692,7 @@
 <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>.  If there is no such <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>, return "left".
 
 
-<h3 id=the-outdent-command><span class=secno>8.25 </span><dfn>The <code title="">outdent</code> command</dfn></h3>
+<h3 id=the-outdent-command><span class=secno>8.26 </span><dfn>The <code title="">outdent</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>:
 
--- a/source.html	Sun Jul 10 08:51:12 2011 -0600
+++ b/source.html	Sun Jul 10 09:08:57 2011 -0600
@@ -583,6 +583,19 @@
 <p>An <dfn>HTML element</dfn> is an [[element]] whose [[namespace]] is the
 [[htmlnamespace]].
 
+<p>A <dfn>prohibited paragraph child name</dfn> is "address", "article",
+"aside", "blockquote", "caption", "center", "col", "colgroup", "dd", "details",
+"dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form",
+"h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "listing",
+"menu", "nav", "ol", "p", "plaintext", "pre", "section", "summary", "table",
+"tbody", "td", "tfoot", "th", "thead", "tr", "ul", or "xmp".
+
+<p>A <dfn>prohibited paragraph child</dfn> is an <span>HTML element</span>
+whose [[localname]] is a <span>prohibited paragraph child name</span>.
+<!-- These are all the things that will close a <p> if found as a descendant.
+I think.  Plus table stuff, since that can't be a descendant of a p either,
+although it won't auto-close it. -->
+
 <p>An <dfn>inline node</dfn> is either a [[text]] node, or an [[element]] whose
 "display" property computes to "inline", "inline-block", or "inline-table".
 
@@ -801,48 +814,6 @@
 <p>To <dfn>remove extraneous line breaks from</dfn> a [[node]], first
 <span>remove extraneous line breaks before</span> it, then <span>remove
 extraneous line breaks at the end of</span> it.
-
-<p>A [[node]] <var>node</var> <dfn>follows a line break</dfn> if the following
-algorithm returns true:
-
-<p class=XXX>Editorial issue: These two algorithms depend on block-extending.
-Should that get moved up to the general algorithms?
-
-<ol>
-  <li>Let <var>offset</var> be zero.
-
-  <li>While <var>offset</var> is zero, set <var>offset</var> to the [[index]]
-  of <var>node</var> and then set <var>node</var> to its [[parent]].
-
-  <li>Let <var>range</var> be a [[range]] with [[rangestart]] and [[rangeend]]
-  (<var>node</var>, <var>offset</var>).
-
-  <li><span>Block-extend</span> <var>range</var>, and let <var>new range</var>
-  be the result.
-
-  <li>Return false if <var>new range</var>'s [[rangestart]] is [[bpbefore]]
-  (<var>node</var>, <var>offset</var>), true otherwise.
-</ol>
-
-<p>A [[node]] <var>node</var> <dfn>precedes a line break</dfn> if the following
-algorithm returns true:
-
-<ol>
-  <li>Let <var>offset</var> be the [[length]] of <var>node</var>.
-
-  <li>While <var>offset</var> is the [[length]] of <var>node</var>, set
-  <var>offset</var> to one plus the [[index]] of <var>node</var> and then set
-  <var>node</var> to its [[parent]].
-
-  <li>Let <var>range</var> be a [[range]] with [[rangestart]] and [[rangeend]]
-  (<var>node</var>, <var>offset</var>).
-
-  <li><span>Block-extend</span> <var>range</var>, and let <var>new range</var>
-  be the result.
-
-  <li>Return false if <var>new range</var>'s [[rangeend]] is [[bpafter]]
-  (<var>node</var>, <var>offset</var>), true otherwise.
-</ol>
 <!-- @} -->
 
 <h3>Wrapping a list of nodes</h3>
@@ -1013,6 +984,132 @@
 </ol>
 <!-- @} -->
 
+<h3>Allowed children</h3>
+<!-- @{ -->
+<p>A [[node]] or string <var>child</var> is an <dfn>allowed child</dfn> of a
+[[node]] or string <var>parent</var> if the following algorithm returns true:
+
+<div class=XXX>
+<p>This list doesn't currently match HTML's validity requirements for a few
+reasons:
+
+<ol>
+  <li>We need to handle invalid elements, which have no conformance
+  requirements but should be treated properly.  In particular, they can
+  interfere with serialization (e.g., center cannot descend from p).
+
+  <li>Sometimes users give instructions that have to produce invalid DOMs to
+  get the expected effect, like indenting the first item of a list.
+
+  <li>The HTML validity requirements are sometimes quite complicated.
+
+  <li>I just haven't had bothered to be systematic about it yet&nbsp;&ndash;
+  I've only covered what's come up in my tests.
+</ol>
+</div>
+
+<ol>
+  <li>If <var>parent</var> is "colgroup", "table", "tbody", "tfoot", "thead",
+  "tr", or an <span>HTML element</span> with [[localname]] equal to one of
+  those, and <var>child</var> is a [[text]] node whose [[cddata]] does not
+  consist solely of [[spacecharacters]], return false.
+
+  <li>If <var>parent</var> is "script", "style", "plaintext", or "xmp", or an
+  <span>HTML element</span> with [[localname]] equal to one of those, and
+  <var>child</var> is not a [[text]] node, return false.
+  <!-- Actually, no node can occur in the DOM after plaintext, generally.  But
+  let's not get too carried away. -->
+
+  <li>If <var>child</var> is a [[document]], [[documentfragment]], or
+  [[documenttype]], return false.
+
+  <li>If <var>child</var> is an <span>HTML element</span>, set <var>child</var>
+  to the [[localname]] of <var>child</var>.
+
+  <li>If <var>child</var> is not a string, return true.
+
+  <li>If <var>parent</var> is an <span>HTML element</span>:
+
+  <ol>
+    <li>If <var>child</var> is "a", and <var>parent</var> or some [[ancestor]]
+    of <var>parent</var> is an [[a]], return false.
+    <!-- Cannot be serialized as text/html.  In some cases it can, like
+    <a>foo<table><td><a>bar</a></td></table>baz</a>, but it's invalid in those
+    cases too, so no need for complication. -->
+
+    <li>If <var>child</var> is a <span>prohibited paragraph child name</span>
+    and <var>parent</var> or some [[ancestor]] of <var>parent</var> is a [[p]]
+    or <span>element with inline contents</span>, return false.
+    <!-- This generally cannot be serialized either, for p.  For elements with
+    inline contents, this serves to prevent things like
+    <span><p>foo</p></span>, which will parse fine but aren't supposed to
+    happen anyway. -->
+
+    <li>If <var>child</var> is "h1", "h2", "h3", "h4", "h5", or "h6", and
+    <var>parent</var> or some [[ancestor]] of <var>parent</var> is an
+    <span>HTML element</span> with [[localname]] "h1", "h2", "h3", "h4", "h5",
+    or "h6", return false.
+    <!-- Nor this. -->
+
+    <li>Let <var>parent</var> be the [[localname]] of <var>parent</var>.
+    <!-- Further requirements only care about the parent itself, not ancestors,
+    so we don't need to know the node itself. -->
+  </ol>
+
+  <li>If <var>parent</var> is an [[element]] or [[documentfragment]], return
+  true.
+
+  <li>If <var>parent</var> is not a string, return false.
+
+  <li>If <var>parent</var> is in the following table, then return true if
+  <var>child</var> is listed as an allowed child, and false otherwise.
+  <!-- We allow children even where some intervening nodes will be inserted,
+  like tr as a child of table. -->
+
+  <table>
+    <tr><th>Parent <th>Allowed children
+    <tr><td>colgroup <td>col
+    <tr><td>table <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
+    <tr><td>tbody, tfoot, thead <td>td, th, tr
+    <tr><td>tr <td>td, th
+    <tr><td>dl <td>dt, dd
+    <tr><td>dir, ol, ul <td>dir, li, ol, ul
+    <tr><td>hgroup <td>h1, h2, h3, h4, h5, h6
+  </table>
+
+  <li>If <var>child</var> is "body", "caption", "col", "colgroup", "frame",
+  "frameset", "head", "html", "tbody", "td", "tfoot", "th", "thead", or "tr",
+  return false.
+
+  <!-- dd/dt/li will serialize fine as the child of random stuff, but it makes
+  no sense at all, so we want to avoid it anyway. -->
+  <li>If <var>child</var> is "dd" or "dt" and <var>parent</var> is not "dl",
+  return false.
+
+  <li>If <var>child</var> is "li" and <var>parent</var> is not "ol" or "ul",
+  return false.
+
+  <li>If <var>parent</var> is in the following table and <var>child</var> is
+  listed as a prohibited child, return false.
+
+  <table>
+    <tr><th>Parent <th>Prohibited children
+    <tr><td>a <td>a
+    <tr><td>dd, dt <td>dd, dt
+    <tr><td>h1, h2, h3, h4, h5, h6 <td>h1, h2, h3, h4, h5, h6
+    <tr><td>li <td>li
+    <tr><td>nobr <td>nobr
+    <tr><td>p, all <span title="name of an element with inline contents">names
+          of an element with inline contents</span>
+        <td>All <span title="prohibited paragraph child name">prohibited
+          paragraph child names</span>
+    <tr><td>td, th <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
+  </table>
+
+  <li>Return true.
+</ol>
+<!-- @} -->
+
 <h2 id=inline-formatting-commands>Inline formatting commands</h2>
 
 <h3>Inline formatting command definitions</h3>
@@ -2664,6 +2761,10 @@
   <span>split the parent</span> of the one-[[node]] list consisting of
   <var>node</var>.
 
+  <p class=XXX>Splitting the parent is really a block algorithm.  It's not
+  clear whether it's desirable to use for inline nodes.  Perhaps it's okay, but
+  it makes me a little uneasy.
+
   <li>For each of the entries in the following list, in the given order,
   <span>set the selection's value</span> to null, with <var>command</var> as
   given.
@@ -2875,19 +2976,6 @@
 
 <h3>Block formatting command definitions</h3>
 <!-- @{ -->
-<p>A <dfn>prohibited paragraph child name</dfn> is "address", "article",
-"aside", "blockquote", "caption", "center", "col", "colgroup", "dd", "details",
-"dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form",
-"h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "listing",
-"menu", "nav", "ol", "p", "plaintext", "pre", "section", "summary", "table",
-"tbody", "td", "tfoot", "th", "thead", "tr", "ul", or "xmp".
-
-<p>A <dfn>prohibited paragraph child</dfn> is an <span>HTML element</span>
-whose [[localname]] is a <span>prohibited paragraph child name</span>.
-<!-- These are all the things that will close a <p> if found as a descendant.
-I think.  Plus table stuff, since that can't be a descendant of a p either,
-although it won't auto-close it. -->
-
 <p>A <dfn>name of an element with inline contents</dfn> is "a", "abbr", "b",
 "bdi", "bdo", "cite", "code", "dfn", "em", "h1", "h2", "h3", "h4", "h5", "h6",
 "i", "kbd", "mark", "pre", "q", "rp", "rt", "ruby", "s", "samp", "small",
@@ -2982,250 +3070,6 @@
   of <var>node</var>.
 </ol>
 
-<p>To <dfn>split the parent</dfn> of a list <var>node list</var> of consecutive
-[[sibling]] [[nodes]]:
-
-<p class=XXX>Pretty much any time we call this algorithm, it can cause trouble
-if the parent had styles, classes, etc.  There's not going to be any general
-way to handle this, but we should at least try to handle the special case of
-inline styles, because Firefox does actually add them to arbitrary elements.
-Also, when splitting out of an inline parent, it might be good to wrap all the
-inline descendants in a clone of the former parent.
-
-<ol>
-  <li>Let <var>original parent</var> be the [[parent]] of the first member of
-  <var>node list</var>.
-
-  <li>If <var>original parent</var> is not <span>editable</span> or its
-  [[parent]] is null, do nothing and abort these steps.
-
-  <li>If the first [[child]] of <var>original parent</var> is in <var>node
-  list</var>, <span>remove extraneous line breaks before</span> <var>original
-  parent</var>.
-
-  <li>If the first [[child]] of <var>original parent</var> is in <var>node
-  list</var>, and <var>original parent</var> <span>follows a line break</span>,
-  set <var>follows line break</var> to true.  Otherwise, set <var>follows line
-  break</var> to false.
-
-  <li>If the last [[child]] of <var>original parent</var> is in <var>node
-  list</var>, and <var>original parent</var> <span>precedes a line
-  break</span>, set <var>precedes line break</var> to true.  Otherwise, set
-  <var>precedes line break</var> to false.
-
-  <li>If the first [[child]] of <var>original parent</var> is not in <var>node
-  list</var>, but its last [[child]] is:
-
-  <div class=XXX>
-  <p>We insert things after the parent.  This is bad, because it will cause
-  them to become part of any ranges that immediately follow.  For instance, if
-  we're hitting "bar" in
-
-  <xmp><div><p>foo<p>bar</div>{<p>baz}</xmp>
-
-  <p>it becomes
-
-  <xmp><div><p>foo</div>{<p>bar<p>baz}</xmp>
-
-  <p>instead of
-
-  <xmp><div><p>foo</div><p>bar{<p>baz}</xmp>
-
-  <p>because of how range mutation rules work.  This doesn't happen if we
-  insert before.  Probably this isn't important enough to try working around,
-  though.
-  </div>
-
-  <ol>
-    <li>For each <var>node</var> in <var>node list</var>, <em>in reverse
-    order</em>, insert <var>node</var> into the [[parent]] of <var>original
-    parent</var> immediately after <var>original parent</var>, <span>preserving
-    ranges</span>.
-
-    <li>If <var>precedes line break</var> is true, and the last member of
-    <var>node list</var> does not <span title="precedes a line break">precede a
-    line break</span>, call [[createelement|"br"]] on the [[contextobject]] and
-    insert the result immediately after the last member of <var>node
-    list</var>.
-
-    <li><span>Remove extraneous line breaks at the end of</span> <var>original
-    parent</var>.
-
-    <li>Abort these steps.
-  </ol>
-
-  <li>If the first [[child]] of <var>original parent</var> is not in <var>node
-  list</var>:
-
-  <ol>
-    <li>Let <var>cloned parent</var> be the result of calling <code
-    data-anolis-spec=domcore title=dom-Node-cloneNode>cloneNode(false)</code>
-    on <var>original parent</var>.
-
-    <li>If <var>original parent</var> has an [[id]] attribute, unset it.
-
-    <li>Insert <var>cloned parent</var> into the [[parent]] of <var>original
-    parent</var> immediately before <var>original parent</var>.
-
-    <li>While the [[previoussibling]] of the first member of <var>node
-    list</var> is not null, append the first [[child]] of <var>original
-    parent</var> as the last [[child]] of <var>cloned parent</var>,
-    <span>preserving ranges</span>.
-  </ol>
-
-  <li>For each <var>node</var> in <var>node list</var>, insert <var>node</var>
-  into the [[parent]] of <var>original parent</var> immediately before
-  <var>original parent</var>, <span>preserving ranges</span>.
-  <!-- Notice that a boundary point that was immediately before the element
-  will now be immediately before its children, just because of the regular
-  range mutation rules, without needing to worry about preserving ranges.
-  Likewise for boundary points immediately after the element, if we wind up
-  removing the element in the final step.  Preserving ranges is only necessary
-  for the sake of boundary points in the element or its descendants. -->
-
-  <li>If <var>follows line break</var> is true, and the first member of
-  <var>node list</var> does not <span title="follows a line break">follow a
-  line break</span>, call [[createelement|"br"]] on the [[contextobject]] and
-  insert the result immediately before the first member of <var>node
-  list</var>.
-
-  <li>If the last member of <var>node list</var> is an <span>inline node</span>
-  other than a [[br]], and the first [[child]] of <var>original parent</var> is
-  a [[br]], and <var>original parent</var> is not an <span>inline node</span>,
-  remove the first [[child]] of <var>original parent</var> from <var>original
-  parent</var>.
-
-  <li>If <var>original parent</var> has no [[children]]:
-
-  <ol>
-    <li>Remove <var>original parent</var> from its [[parent]].
-
-    <li>If <var>precedes line break</var> is true, and the last member of
-    <var>node list</var> does not <span title="precedes a line break">precede a
-    line break</span>, call [[createelement|"br"]] on the [[contextobject]] and
-    insert the result immediately after the last member of <var>node
-    list</var>.
-  </ol>
-
-  <li>Otherwise, <span>remove extraneous line breaks before</span>
-  <var>original parent</var>.
-
-  <li>If <var>node list</var>'s last member's [[nextsibling]] is null,
-  but its [[parent]] is not null, <span>remove extraneous line breaks at the
-  end of</span> <var>node list</var>'s last member's [[parent]].
-  <!-- The parent might be null if it's a br that we removed in the last step,
-  in which case this step isn't necessary. -->
-</ol>
-
-<p>To remove a [[node]] <var>node</var> while <dfn>preserving its
-descendants</dfn>, <span>split the parent</span> of <var>node</var>'s
-[[children]].
-
-<p>To <dfn>indent</dfn> a list <var>node list</var> of consecutive [[sibling]]
-[[nodes]]:
-<!--
-We have to handle entire lists of siblings at once, or else we'd wind up doing
-something like
-
-  <ol>
-    {<li>foo</li>
-    <ol><li>bar</li></ol>}
-  </ol>
-  ->
-  <ol><ol>
-    <li>foo</li>
-    <li>bar</li>
-  </ol></ol>
-  ->
-  <ol><ol><ol>
-    <li>foo</li>
-    <li>bar</li>
-  </ol></ol></ol>
-
-since by the time we got to doing the <ol> that originally contained "bar", we
-won't remember that we aren't supposed to indent "foo" a second time.
--->
-
-<ol>
-  <li>If <var>node list</var> is empty, do nothing and abort these steps.
-
-  <li>Let <var>first node</var> be the first member of <var>node list</var>.
-
-  <li>If <var>first node</var>'s [[parent]] is an [[ol]] or [[ul]]:
-
-  <ol>
-    <li>Let <var>tag</var> be the [[localname]] of the [[parent]] of
-    <var>first node</var>.
-
-    <li><span>Wrap</span> <var>node list</var>, with <span>sibling
-    criteria</span> matching only <span title="HTML element">HTML
-    elements</span> with [[localname]] <var>tag</var> and <span>new parent
-    instructions</span> returning the result of calling <code
-    data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement(<var>tag</var>)</code> on
-    the [[ownerdocument]] of <var>first node</var>.
-    <!--
-    This matches IE9, Firefox 4.0, and Chrome 12 dev.  If there's a preceding
-    <li>, Opera 11.10 instead adds the new parent to the end of that <li>, so
-    it's not the child of another list, which is invalid.  But the other
-    browsers' way of doing things makes things simpler.  E.g., if we want to
-    indent an <li> and it has <ol>/<ul> children, we have to distinguish
-    between the case where we want to indent the whole <li> or only the first
-    part.  It also allows things like
-
-      <ol><li>
-        foo
-        <ol><li>bar</li></ol>
-        baz
-      </li></ol>
-
-    in which case it's unclear what we should do if the user selects "foo" and
-    indents.  I've filed a bug on HTML5:
-
-    http://www.w3.org/Bugs/Public/show_bug.cgi?id=12609
-    -->
-
-    <li>Abort these steps.
-  </ol>
-
-  <!--
-  Firefox 4.0 respects the CSS styling flag for indent, but Chrome 12 dev does
-  not.  I always produce blockquotes, even if CSS styling is on, for two
-  reasons.  One, IE9 handles inline margin attributes badly: when outdenting,
-  it propagates the margin to the parent, which doesn't actually remove it.
-  Two, in CSS mode I'd want to use <div style="margin: 1em 40px"> to match
-  non-CSS mode, but authors are very likely to want to remove the top/bottom
-  margin, which they can't do if it's not a special tag.  Authors who really
-  want divs for indentation could always convert the blockquotes to divs
-  themselves.  But if people really want it, I could respect CSS styling mode
-  here too.
-
-  The top/bottom margins might be undesirable here, but no more so than for
-  <ol>/<ul>/<p>/etc.  Here as there, authors can remove them with CSS if they
-  want.
-  -->
-
-  <li><span>Wrap</span> <var>node list</var>, with <span>sibling
-  criteria</span> matching any <span>indentation element</span>, and <span>new
-  parent instructions</span> to return the result of calling <code
-  data-anolis-spec=domcore
-  title=dom-Document-createElement>createElement("blockquote")</code> on the
-  [[ownerdocument]] of <var>first node</var>.  Let <var>new parent</var> be the
-  result.
-  <!--
-  This indents on both sides, so we don't have to worry about directionality.
-  In theory it would be better if we indented only on the start side, but that
-  requires care to get right in mixed-direction cases.  Even once browsers
-  start to support margin-start and so on, we can't use them because a) we have
-  to work okay in legacy browsers and b) it doesn't help if a descendant block
-  has different direction (so should be indented the other way).  So let's not
-  worry about it: most browsers don't, and the ones that do get it wrong.  Just
-  indent on both sides.
-  -->
-
-  <li><span>Fix disallowed ancestors</span> of <var>new parent</var>.
-</ol>
-
 <p>To <dfn>normalize sublists</dfn> in a [[node]] <var>item</var>:
 <!--
 This algorithm implies that we don't support a sublist in the middle of an
@@ -3333,194 +3177,6 @@
   <li>Return "none".
 </ol>
 
-<p>The <dfn>canonical space sequence</dfn> of length <var>n</var>, with boolean
-flags <var>non-breaking start</var> and <var>non-breaking end</var>, is
-returned by the following algorithm:
-<!-- See long comment before insertText. -->
-
-<ol>
-  <li>If <var>n</var> is zero, return the empty string.
-
-  <li>If <var>n</var> is one and both <var>non-breaking start</var> and
-  <var>non-breaking end</var> are false, return a single space (U+0020).
-
-  <li>If <var>n</var> is one, return a single non-breaking space (U+00A0).
-
-  <li>Let <var>buffer</var> be the empty string.
-
-  <li>If <var>non-breaking start</var> is true, let <var>repeated pair</var> be
-  U+00A0 U+0020.  Otherwise, let it be U+0020 U+00A0.
-
-  <li>While <var>n</var> is greater than three, append <var>repeated pair</var>
-  to <var>buffer</var> and subtract two from <var>n</var>.
-
-  <li>If <var>n</var> is three, append a three-[[strel]] string to
-  <var>buffer</var> depending on <var>non-breaking start</var> and
-  <var>non-breaking end</var>:
-
-  <dl class=switch>
-    <dt><var>non-breaking start</var> and <var>non-breaking end</var> false
-    <dd>U+0020 U+00A0 U+0020
-
-    <dt><var>non-breaking start</var> true, <var>non-breaking end</var> false
-    <dd>U+00A0 U+00A0 U+0020
-
-    <dt><var>non-breaking start</var> false, <var>non-breaking end</var> true
-    <dd>U+0020 U+00A0 U+00A0
-
-    <dt><var>non-breaking start</var> and <var>non-breaking end</var> both true
-    <dd>U+00A0 U+0020 U+00A0
-  </dl>
-
-  <li>Otherwise, append a two-[[strel]] string to <var>buffer</var> depending
-  on <var>non-breaking start</var> and <var>non-breaking end</var>:
-
-  <dl class=switch>
-    <dt><var>non-breaking start</var> and <var>non-breaking end</var> false
-    <dt><var>non-breaking start</var> true, <var>non-breaking end</var> false
-    <dd>U+00A0 U+0020
-
-    <dt><var>non-breaking start</var> false, <var>non-breaking end</var> true
-    <dd>U+0020 U+00A0
-
-    <dt><var>non-breaking start</var> and <var>non-breaking end</var> both true
-    <dd>U+00A0 U+00A0
-  </dl>
-
-  <li>Return <var>buffer</var>.
-</ol>
-
-<p>To <dfn>canonicalize whitespace</dfn> at (<var>node</var>,
-<var>offset</var>):
-
-<ol>
-  <li>If <var>node</var> is neither <span>editable</span> nor an <span>editing
-  host</span>, abort these steps.
-
-  <li>Let <var>start node</var> equal <var>node</var> and let <var>start
-  offset</var> equal <var>offset</var>.
-
-  <!-- First go to the beginning of the current whitespace run. -->
-  <li>Repeat the following steps:
-
-  <ol>
-    <li>If <var>start node</var> has a [[child]] <span>in the same editing
-    host</span> with [[index]] <var>start offset</var> minus one, set
-    <var>start node</var> to that [[child]], then set <var>start offset</var>
-    to <var>start node</var>'s [[length]].
-
-    <li>Otherwise, if <var>start offset</var> is zero and <var>start node</var>
-    does not <span title="follows a line break">follow a line break</span> and
-    <var>start node</var>'s [[parent]] is <span>in the same editing
-    host</span>, set <var>start offset</var> to <var>start node</var>'s
-    [[index]], then set <var>start node</var> to its [[parent]].
-
-    <p class=XXX>Following a line break is unlikely to be the right criterion.
-
-    <li>Otherwise, if <var>start node</var> is a [[text]] node and its
-    [[parent]]'s [[compval]] for "white-space" is neither "pre" nor "pre-wrap"
-    and <var>start offset</var> is not zero and the (<var>start offset</var>
-    &minus; 1)st [[strel]] of <var>start node</var>'s [[cddata]] is a space
-    (0x0020) or non-breaking space (0x00A0), subtract one from <var>start
-    offset</var>.
-
-    <li>Otherwise, break from this loop.
-  </ol>
-
-  <!-- Now collapse any consecutive spaces. -->
-  <li>Let <var>end node</var> equal <var>start node</var> and <var>end
-  offset</var> equal <var>start offset</var>.
-
-  <li>Let <var>length</var> equal zero.
-
-  <li>Let <var>follows space</var> be false.
-
-  <li>Repeat the following steps:
-
-  <ol>
-    <li>If <var>end node</var> has a [[child]] <span>in the same editing
-    host</span> with [[index]] <var>end offset</var>, set <var>end node</var>
-    to that [[child]], then set <var>end offset</var> to zero.
-
-    <li>Otherwise, if <var>end offset</var> is <var>end node</var>'s [[length]]
-    and <var>end node</var> does not <span title="precedes a line
-    break">precede a line break</span> and <var>end node</var>'s [[parent]] is
-    <span>in the same editing host</span>, set <var>end offset</var> to one
-    plus <var>end node</var>'s [[index]], then set <var>end node</var> to its
-    [[parent]].
-
-    <p class=XXX>Preceding a line break is unlikely to be the right criterion.
-
-    <li>Otherwise, if <var>end node</var> is a [[text]] node and its
-    [[parent]]'s [[compval]] for "white-space" is neither "pre" nor "pre-wrap"
-    and <var>end offset</var> is not <var>end node</var>'s [[length]] and the
-    <var>end offset</var>th [[strel]] of <var>end node</var>'s [[cddata]] is a
-    space (0x0020) or non-breaking space (0x00A0):
-
-    <ol>
-      <li>If <var>follows space</var> is true and the <var>end offset</var>th
-      [[strel]] of <var>end node</var>'s [[cddata]] is a space (0x0020), call
-      [[deletedata|<var>end offset</var>, 1]] on <var>end node</var>, then
-      continue this loop from the beginning.
-
-      <li>Set <var>follows space</var> to true if the <var>end offset</var>th
-      [[strel]] of <var>end node</var>'s [[cddata]] is a space (0x0020), false
-      otherwise.
-
-      <li>Add one to <var>end offset</var>.
-
-      <li>Add one to <var>length</var>.
-    </ol>
-
-    <li>Otherwise, break from this loop.
-  </ol>
-
-  <!-- Now replace with the canonical sequence. -->
-  <li>Let <var>replacement whitespace</var> be the <span>canonical space
-  sequence</span> of length <var>length</var>.  <var>non-breaking start</var>
-  is true if <var>start offset</var> is zero and <var>start node</var>
-  <span>follows a line break</span>, and false otherwise.  <var>non-breaking
-  end</var> is true if <var>end offset</var> is <var>end node</var>'s
-  [[cdlength]] and <var>end node</var> <span>precedes a line break</span>, and
-  false otherwise.
-
-  <li>While (<var>start node</var>, <var>start offset</var>) is [[bpbefore]]
-  (<var>end node</var>, <var>end offset</var>):
-
-  <ol>
-    <li>If <var>start node</var> has a [[child]] with [[index]] <var>start
-    offset</var>, set <var>start node</var> to that [[child]], then set
-    <var>start offset</var> to zero.
-
-    <li>Otherwise, if <var>start node</var> is not a [[text]] node or if
-    <var>start offset</var> is <var>start node</var>'s [[length]], set
-    <var>start offset</var> to one plus <var>start node</var>'s [[index]], then
-    set <var>start node</var> to its [[parent]].
-
-    <li>Otherwise:
-
-    <ol>
-      <li>Remove the first [[strel]] from <var>replacement whitespace</var>,
-      and let <var>element</var> be that [[strel]].
-
-      <li>If <var>element</var> is not the same as the <var>start
-      offset</var>th [[strel]] of <var>start node</var>'s [[cddata]]:
-
-      <ol>
-        <!-- We need to insert then delete, so that we don't change range
-        boundary points. -->
-        <li>Call [[insertdata|<var>start offset</var>, <var>element</var>]] on
-        <var>start node</var>.
-
-        <li>Call [[deletedata|<var>start offset</var> + 1, 1]] on
-        <var>start node</var>.
-      </ol>
-
-      <li>Add one to <var>start offset</var>.
-    </ol>
-  </ol>
-</ol>
-
 <p>The <dfn>alignment value</dfn> of a [[node]] <var>node</var> is returned by
 the following algorithm:
 <!--
@@ -3555,132 +3211,6 @@
 </ol>
 <!-- @} -->
 
-<h3>Allowed children</h3>
-<!-- @{ -->
-<p>A [[node]] or string <var>child</var> is an <dfn>allowed child</dfn> of a
-[[node]] or string <var>parent</var> if the following algorithm returns true:
-
-<div class=XXX>
-<p>This list doesn't currently match HTML's validity requirements for a few
-reasons:
-
-<ol>
-  <li>We need to handle invalid elements, which have no conformance
-  requirements but should be treated properly.  In particular, they can
-  interfere with serialization (e.g., center cannot descend from p).
-
-  <li>Sometimes users give instructions that have to produce invalid DOMs to
-  get the expected effect, like indenting the first item of a list.
-
-  <li>The HTML validity requirements are sometimes quite complicated.
-
-  <li>I just haven't had bothered to be systematic about it yet&nbsp;&ndash;
-  I've only covered what's come up in my tests.
-</ol>
-</div>
-
-<ol>
-  <li>If <var>parent</var> is "colgroup", "table", "tbody", "tfoot", "thead",
-  "tr", or an <span>HTML element</span> with [[localname]] equal to one of
-  those, and <var>child</var> is a [[text]] node whose [[cddata]] does not
-  consist solely of [[spacecharacters]], return false.
-
-  <li>If <var>parent</var> is "script", "style", "plaintext", or "xmp", or an
-  <span>HTML element</span> with [[localname]] equal to one of those, and
-  <var>child</var> is not a [[text]] node, return false.
-  <!-- Actually, no node can occur in the DOM after plaintext, generally.  But
-  let's not get too carried away. -->
-
-  <li>If <var>child</var> is a [[document]], [[documentfragment]], or
-  [[documenttype]], return false.
-
-  <li>If <var>child</var> is an <span>HTML element</span>, set <var>child</var>
-  to the [[localname]] of <var>child</var>.
-
-  <li>If <var>child</var> is not a string, return true.
-
-  <li>If <var>parent</var> is an <span>HTML element</span>:
-
-  <ol>
-    <li>If <var>child</var> is "a", and <var>parent</var> or some [[ancestor]]
-    of <var>parent</var> is an [[a]], return false.
-    <!-- Cannot be serialized as text/html.  In some cases it can, like
-    <a>foo<table><td><a>bar</a></td></table>baz</a>, but it's invalid in those
-    cases too, so no need for complication. -->
-
-    <li>If <var>child</var> is a <span>prohibited paragraph child name</span>
-    and <var>parent</var> or some [[ancestor]] of <var>parent</var> is a [[p]]
-    or <span>element with inline contents</span>, return false.
-    <!-- This generally cannot be serialized either, for p.  For elements with
-    inline contents, this serves to prevent things like
-    <span><p>foo</p></span>, which will parse fine but aren't supposed to
-    happen anyway. -->
-
-    <li>If <var>child</var> is "h1", "h2", "h3", "h4", "h5", or "h6", and
-    <var>parent</var> or some [[ancestor]] of <var>parent</var> is an
-    <span>HTML element</span> with [[localname]] "h1", "h2", "h3", "h4", "h5",
-    or "h6", return false.
-    <!-- Nor this. -->
-
-    <li>Let <var>parent</var> be the [[localname]] of <var>parent</var>.
-    <!-- Further requirements only care about the parent itself, not ancestors,
-    so we don't need to know the node itself. -->
-  </ol>
-
-  <li>If <var>parent</var> is an [[element]] or [[documentfragment]], return
-  true.
-
-  <li>If <var>parent</var> is not a string, return false.
-
-  <li>If <var>parent</var> is in the following table, then return true if
-  <var>child</var> is listed as an allowed child, and false otherwise.
-  <!-- We allow children even where some intervening nodes will be inserted,
-  like tr as a child of table. -->
-
-  <table>
-    <tr><th>Parent <th>Allowed children
-    <tr><td>colgroup <td>col
-    <tr><td>table <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
-    <tr><td>tbody, tfoot, thead <td>td, th, tr
-    <tr><td>tr <td>td, th
-    <tr><td>dl <td>dt, dd
-    <tr><td>dir, ol, ul <td>dir, li, ol, ul
-    <tr><td>hgroup <td>h1, h2, h3, h4, h5, h6
-  </table>
-
-  <li>If <var>child</var> is "body", "caption", "col", "colgroup", "frame",
-  "frameset", "head", "html", "tbody", "td", "tfoot", "th", "thead", or "tr",
-  return false.
-
-  <!-- dd/dt/li will serialize fine as the child of random stuff, but it makes
-  no sense at all, so we want to avoid it anyway. -->
-  <li>If <var>child</var> is "dd" or "dt" and <var>parent</var> is not "dl",
-  return false.
-
-  <li>If <var>child</var> is "li" and <var>parent</var> is not "ol" or "ul",
-  return false.
-
-  <li>If <var>parent</var> is in the following table and <var>child</var> is
-  listed as a prohibited child, return false.
-
-  <table>
-    <tr><th>Parent <th>Prohibited children
-    <tr><td>a <td>a
-    <tr><td>dd, dt <td>dd, dt
-    <tr><td>h1, h2, h3, h4, h5, h6 <td>h1, h2, h3, h4, h5, h6
-    <tr><td>li <td>li
-    <tr><td>nobr <td>nobr
-    <tr><td>p, all <span title="name of an element with inline contents">names
-          of an element with inline contents</span>
-        <td>All <span title="prohibited paragraph child name">prohibited
-          paragraph child names</span>
-    <tr><td>td, th <td>caption, col, colgroup, tbody, td, tfoot, th, thead, tr
-  </table>
-
-  <li>Return true.
-</ol>
-<!-- @} -->
-
 <h3>Block-extending a range</h3>
 <!-- @{ -->
 <p>When a user agent is to <dfn>block-extend</dfn> a [[range]]
@@ -3762,6 +3292,45 @@
 
   <li>Return <var>new range</var>.
 </ol>
+
+<p>A [[node]] <var>node</var> <dfn>follows a line break</dfn> if the following
+algorithm returns true:
+
+<ol>
+  <li>Let <var>offset</var> be zero.
+
+  <li>While <var>offset</var> is zero, set <var>offset</var> to the [[index]]
+  of <var>node</var> and then set <var>node</var> to its [[parent]].
+
+  <li>Let <var>range</var> be a [[range]] with [[rangestart]] and [[rangeend]]
+  (<var>node</var>, <var>offset</var>).
+
+  <li><span>Block-extend</span> <var>range</var>, and let <var>new range</var>
+  be the result.
+
+  <li>Return false if <var>new range</var>'s [[rangestart]] is [[bpbefore]]
+  (<var>node</var>, <var>offset</var>), true otherwise.
+</ol>
+
+<p>A [[node]] <var>node</var> <dfn>precedes a line break</dfn> if the following
+algorithm returns true:
+
+<ol>
+  <li>Let <var>offset</var> be the [[length]] of <var>node</var>.
+
+  <li>While <var>offset</var> is the [[length]] of <var>node</var>, set
+  <var>offset</var> to one plus the [[index]] of <var>node</var> and then set
+  <var>node</var> to its [[parent]].
+
+  <li>Let <var>range</var> be a [[range]] with [[rangestart]] and [[rangeend]]
+  (<var>node</var>, <var>offset</var>).
+
+  <li><span>Block-extend</span> <var>range</var>, and let <var>new range</var>
+  be the result.
+
+  <li>Return false if <var>new range</var>'s [[rangeend]] is [[bpafter]]
+  (<var>node</var>, <var>offset</var>), true otherwise.
+</ol>
 <!-- @} -->
 
 <h3>Deleting the contents of a range</h3>
@@ -4153,8 +3722,445 @@
 </ol>
 <!-- @} -->
 
-<h3>Outdenting a node</h3>
+<h3>Splitting a node list's parent</h3>
 <!-- @{ -->
+<p>To <dfn>split the parent</dfn> of a list <var>node list</var> of consecutive
+[[sibling]] [[nodes]]:
+
+<p class=XXX>Pretty much any time we call this algorithm, it can cause trouble
+if the parent had styles, classes, etc.  There's not going to be any general
+way to handle this, but we should at least try to handle the special case of
+inline styles, because Firefox does actually add them to arbitrary elements.
+Also, when splitting out of an inline parent, it might be good to wrap all the
+inline descendants in a clone of the former parent.
+
+<ol>
+  <li>Let <var>original parent</var> be the [[parent]] of the first member of
+  <var>node list</var>.
+
+  <li>If <var>original parent</var> is not <span>editable</span> or its
+  [[parent]] is null, do nothing and abort these steps.
+
+  <li>If the first [[child]] of <var>original parent</var> is in <var>node
+  list</var>, <span>remove extraneous line breaks before</span> <var>original
+  parent</var>.
+
+  <li>If the first [[child]] of <var>original parent</var> is in <var>node
+  list</var>, and <var>original parent</var> <span>follows a line break</span>,
+  set <var>follows line break</var> to true.  Otherwise, set <var>follows line
+  break</var> to false.
+
+  <li>If the last [[child]] of <var>original parent</var> is in <var>node
+  list</var>, and <var>original parent</var> <span>precedes a line
+  break</span>, set <var>precedes line break</var> to true.  Otherwise, set
+  <var>precedes line break</var> to false.
+
+  <li>If the first [[child]] of <var>original parent</var> is not in <var>node
+  list</var>, but its last [[child]] is:
+
+  <div class=XXX>
+  <p>We insert things after the parent.  This is bad, because it will cause
+  them to become part of any ranges that immediately follow.  For instance, if
+  we're hitting "bar" in
+
+  <xmp><div><p>foo<p>bar</div>{<p>baz}</xmp>
+
+  <p>it becomes
+
+  <xmp><div><p>foo</div>{<p>bar<p>baz}</xmp>
+
+  <p>instead of
+
+  <xmp><div><p>foo</div><p>bar{<p>baz}</xmp>
+
+  <p>because of how range mutation rules work.  This doesn't happen if we
+  insert before.  Probably this isn't important enough to try working around,
+  though.
+  </div>
+
+  <ol>
+    <li>For each <var>node</var> in <var>node list</var>, <em>in reverse
+    order</em>, insert <var>node</var> into the [[parent]] of <var>original
+    parent</var> immediately after <var>original parent</var>, <span>preserving
+    ranges</span>.
+
+    <li>If <var>precedes line break</var> is true, and the last member of
+    <var>node list</var> does not <span title="precedes a line break">precede a
+    line break</span>, call [[createelement|"br"]] on the [[contextobject]] and
+    insert the result immediately after the last member of <var>node
+    list</var>.
+
+    <li><span>Remove extraneous line breaks at the end of</span> <var>original
+    parent</var>.
+
+    <li>Abort these steps.
+  </ol>
+
+  <li>If the first [[child]] of <var>original parent</var> is not in <var>node
+  list</var>:
+
+  <ol>
+    <li>Let <var>cloned parent</var> be the result of calling <code
+    data-anolis-spec=domcore title=dom-Node-cloneNode>cloneNode(false)</code>
+    on <var>original parent</var>.
+
+    <li>If <var>original parent</var> has an [[id]] attribute, unset it.
+
+    <li>Insert <var>cloned parent</var> into the [[parent]] of <var>original
+    parent</var> immediately before <var>original parent</var>.
+
+    <li>While the [[previoussibling]] of the first member of <var>node
+    list</var> is not null, append the first [[child]] of <var>original
+    parent</var> as the last [[child]] of <var>cloned parent</var>,
+    <span>preserving ranges</span>.
+  </ol>
+
+  <li>For each <var>node</var> in <var>node list</var>, insert <var>node</var>
+  into the [[parent]] of <var>original parent</var> immediately before
+  <var>original parent</var>, <span>preserving ranges</span>.
+  <!-- Notice that a boundary point that was immediately before the element
+  will now be immediately before its children, just because of the regular
+  range mutation rules, without needing to worry about preserving ranges.
+  Likewise for boundary points immediately after the element, if we wind up
+  removing the element in the final step.  Preserving ranges is only necessary
+  for the sake of boundary points in the element or its descendants. -->
+
+  <li>If <var>follows line break</var> is true, and the first member of
+  <var>node list</var> does not <span title="follows a line break">follow a
+  line break</span>, call [[createelement|"br"]] on the [[contextobject]] and
+  insert the result immediately before the first member of <var>node
+  list</var>.
+
+  <li>If the last member of <var>node list</var> is an <span>inline node</span>
+  other than a [[br]], and the first [[child]] of <var>original parent</var> is
+  a [[br]], and <var>original parent</var> is not an <span>inline node</span>,
+  remove the first [[child]] of <var>original parent</var> from <var>original
+  parent</var>.
+
+  <li>If <var>original parent</var> has no [[children]]:
+
+  <ol>
+    <li>Remove <var>original parent</var> from its [[parent]].
+
+    <li>If <var>precedes line break</var> is true, and the last member of
+    <var>node list</var> does not <span title="precedes a line break">precede a
+    line break</span>, call [[createelement|"br"]] on the [[contextobject]] and
+    insert the result immediately after the last member of <var>node
+    list</var>.
+  </ol>
+
+  <li>Otherwise, <span>remove extraneous line breaks before</span>
+  <var>original parent</var>.
+
+  <li>If <var>node list</var>'s last member's [[nextsibling]] is null,
+  but its [[parent]] is not null, <span>remove extraneous line breaks at the
+  end of</span> <var>node list</var>'s last member's [[parent]].
+  <!-- The parent might be null if it's a br that we removed in the last step,
+  in which case this step isn't necessary. -->
+</ol>
+
+<p>To remove a [[node]] <var>node</var> while <dfn>preserving its
+descendants</dfn>, <span>split the parent</span> of <var>node</var>'s
+[[children]].
+<!-- @} -->
+
+<h3>Canonical space sequences</h3>
+<!-- @{ -->
+<p>The <dfn>canonical space sequence</dfn> of length <var>n</var>, with boolean
+flags <var>non-breaking start</var> and <var>non-breaking end</var>, is
+returned by the following algorithm:
+<!-- See long comment before insertText. -->
+
+<ol>
+  <li>If <var>n</var> is zero, return the empty string.
+
+  <li>If <var>n</var> is one and both <var>non-breaking start</var> and
+  <var>non-breaking end</var> are false, return a single space (U+0020).
+
+  <li>If <var>n</var> is one, return a single non-breaking space (U+00A0).
+
+  <li>Let <var>buffer</var> be the empty string.
+
+  <li>If <var>non-breaking start</var> is true, let <var>repeated pair</var> be
+  U+00A0 U+0020.  Otherwise, let it be U+0020 U+00A0.
+
+  <li>While <var>n</var> is greater than three, append <var>repeated pair</var>
+  to <var>buffer</var> and subtract two from <var>n</var>.
+
+  <li>If <var>n</var> is three, append a three-[[strel]] string to
+  <var>buffer</var> depending on <var>non-breaking start</var> and
+  <var>non-breaking end</var>:
+
+  <dl class=switch>
+    <dt><var>non-breaking start</var> and <var>non-breaking end</var> false
+    <dd>U+0020 U+00A0 U+0020
+
+    <dt><var>non-breaking start</var> true, <var>non-breaking end</var> false
+    <dd>U+00A0 U+00A0 U+0020
+
+    <dt><var>non-breaking start</var> false, <var>non-breaking end</var> true
+    <dd>U+0020 U+00A0 U+00A0
+
+    <dt><var>non-breaking start</var> and <var>non-breaking end</var> both true
+    <dd>U+00A0 U+0020 U+00A0
+  </dl>
+
+  <li>Otherwise, append a two-[[strel]] string to <var>buffer</var> depending
+  on <var>non-breaking start</var> and <var>non-breaking end</var>:
+
+  <dl class=switch>
+    <dt><var>non-breaking start</var> and <var>non-breaking end</var> false
+    <dt><var>non-breaking start</var> true, <var>non-breaking end</var> false
+    <dd>U+00A0 U+0020
+
+    <dt><var>non-breaking start</var> false, <var>non-breaking end</var> true
+    <dd>U+0020 U+00A0
+
+    <dt><var>non-breaking start</var> and <var>non-breaking end</var> both true
+    <dd>U+00A0 U+00A0
+  </dl>
+
+  <li>Return <var>buffer</var>.
+</ol>
+
+<p>To <dfn>canonicalize whitespace</dfn> at (<var>node</var>,
+<var>offset</var>):
+
+<ol>
+  <li>If <var>node</var> is neither <span>editable</span> nor an <span>editing
+  host</span>, abort these steps.
+
+  <li>Let <var>start node</var> equal <var>node</var> and let <var>start
+  offset</var> equal <var>offset</var>.
+
+  <!-- First go to the beginning of the current whitespace run. -->
+  <li>Repeat the following steps:
+
+  <ol>
+    <li>If <var>start node</var> has a [[child]] <span>in the same editing
+    host</span> with [[index]] <var>start offset</var> minus one, set
+    <var>start node</var> to that [[child]], then set <var>start offset</var>
+    to <var>start node</var>'s [[length]].
+
+    <li>Otherwise, if <var>start offset</var> is zero and <var>start node</var>
+    does not <span title="follows a line break">follow a line break</span> and
+    <var>start node</var>'s [[parent]] is <span>in the same editing
+    host</span>, set <var>start offset</var> to <var>start node</var>'s
+    [[index]], then set <var>start node</var> to its [[parent]].
+
+    <p class=XXX>Following a line break is unlikely to be the right criterion.
+
+    <li>Otherwise, if <var>start node</var> is a [[text]] node and its
+    [[parent]]'s [[compval]] for "white-space" is neither "pre" nor "pre-wrap"
+    and <var>start offset</var> is not zero and the (<var>start offset</var>
+    &minus; 1)st [[strel]] of <var>start node</var>'s [[cddata]] is a space
+    (0x0020) or non-breaking space (0x00A0), subtract one from <var>start
+    offset</var>.
+
+    <li>Otherwise, break from this loop.
+  </ol>
+
+  <!-- Now collapse any consecutive spaces. -->
+  <li>Let <var>end node</var> equal <var>start node</var> and <var>end
+  offset</var> equal <var>start offset</var>.
+
+  <li>Let <var>length</var> equal zero.
+
+  <li>Let <var>follows space</var> be false.
+
+  <li>Repeat the following steps:
+
+  <ol>
+    <li>If <var>end node</var> has a [[child]] <span>in the same editing
+    host</span> with [[index]] <var>end offset</var>, set <var>end node</var>
+    to that [[child]], then set <var>end offset</var> to zero.
+
+    <li>Otherwise, if <var>end offset</var> is <var>end node</var>'s [[length]]
+    and <var>end node</var> does not <span title="precedes a line
+    break">precede a line break</span> and <var>end node</var>'s [[parent]] is
+    <span>in the same editing host</span>, set <var>end offset</var> to one
+    plus <var>end node</var>'s [[index]], then set <var>end node</var> to its
+    [[parent]].
+
+    <p class=XXX>Preceding a line break is unlikely to be the right criterion.
+
+    <li>Otherwise, if <var>end node</var> is a [[text]] node and its
+    [[parent]]'s [[compval]] for "white-space" is neither "pre" nor "pre-wrap"
+    and <var>end offset</var> is not <var>end node</var>'s [[length]] and the
+    <var>end offset</var>th [[strel]] of <var>end node</var>'s [[cddata]] is a
+    space (0x0020) or non-breaking space (0x00A0):
+
+    <ol>
+      <li>If <var>follows space</var> is true and the <var>end offset</var>th
+      [[strel]] of <var>end node</var>'s [[cddata]] is a space (0x0020), call
+      [[deletedata|<var>end offset</var>, 1]] on <var>end node</var>, then
+      continue this loop from the beginning.
+
+      <li>Set <var>follows space</var> to true if the <var>end offset</var>th
+      [[strel]] of <var>end node</var>'s [[cddata]] is a space (0x0020), false
+      otherwise.
+
+      <li>Add one to <var>end offset</var>.
+
+      <li>Add one to <var>length</var>.
+    </ol>
+
+    <li>Otherwise, break from this loop.
+  </ol>
+
+  <!-- Now replace with the canonical sequence. -->
+  <li>Let <var>replacement whitespace</var> be the <span>canonical space
+  sequence</span> of length <var>length</var>.  <var>non-breaking start</var>
+  is true if <var>start offset</var> is zero and <var>start node</var>
+  <span>follows a line break</span>, and false otherwise.  <var>non-breaking
+  end</var> is true if <var>end offset</var> is <var>end node</var>'s
+  [[cdlength]] and <var>end node</var> <span>precedes a line break</span>, and
+  false otherwise.
+
+  <li>While (<var>start node</var>, <var>start offset</var>) is [[bpbefore]]
+  (<var>end node</var>, <var>end offset</var>):
+
+  <ol>
+    <li>If <var>start node</var> has a [[child]] with [[index]] <var>start
+    offset</var>, set <var>start node</var> to that [[child]], then set
+    <var>start offset</var> to zero.
+
+    <li>Otherwise, if <var>start node</var> is not a [[text]] node or if
+    <var>start offset</var> is <var>start node</var>'s [[length]], set
+    <var>start offset</var> to one plus <var>start node</var>'s [[index]], then
+    set <var>start node</var> to its [[parent]].
+
+    <li>Otherwise:
+
+    <ol>
+      <li>Remove the first [[strel]] from <var>replacement whitespace</var>,
+      and let <var>element</var> be that [[strel]].
+
+      <li>If <var>element</var> is not the same as the <var>start
+      offset</var>th [[strel]] of <var>start node</var>'s [[cddata]]:
+
+      <ol>
+        <!-- We need to insert then delete, so that we don't change range
+        boundary points. -->
+        <li>Call [[insertdata|<var>start offset</var>, <var>element</var>]] on
+        <var>start node</var>.
+
+        <li>Call [[deletedata|<var>start offset</var> + 1, 1]] on
+        <var>start node</var>.
+      </ol>
+
+      <li>Add one to <var>start offset</var>.
+    </ol>
+  </ol>
+</ol>
+<!-- @} -->
+
+<h3>Indenting and outdenting</h3>
+<!-- @{ -->
+<p>To <dfn>indent</dfn> a list <var>node list</var> of consecutive [[sibling]]
+[[nodes]]:
+<!--
+We have to handle entire lists of siblings at once, or else we'd wind up doing
+something like
+
+  <ol>
+    {<li>foo</li>
+    <ol><li>bar</li></ol>}
+  </ol>
+  ->
+  <ol><ol>
+    <li>foo</li>
+    <li>bar</li>
+  </ol></ol>
+  ->
+  <ol><ol><ol>
+    <li>foo</li>
+    <li>bar</li>
+  </ol></ol></ol>
+
+since by the time we got to doing the <ol> that originally contained "bar", we
+won't remember that we aren't supposed to indent "foo" a second time.
+-->
+<ol>
+  <li>If <var>node list</var> is empty, do nothing and abort these steps.
+
+  <li>Let <var>first node</var> be the first member of <var>node list</var>.
+
+  <li>If <var>first node</var>'s [[parent]] is an [[ol]] or [[ul]]:
+
+  <ol>
+    <li>Let <var>tag</var> be the [[localname]] of the [[parent]] of
+    <var>first node</var>.
+
+    <li><span>Wrap</span> <var>node list</var>, with <span>sibling
+    criteria</span> matching only <span title="HTML element">HTML
+    elements</span> with [[localname]] <var>tag</var> and <span>new parent
+    instructions</span> returning the result of calling <code
+    data-anolis-spec=domcore
+    title=dom-Document-createElement>createElement(<var>tag</var>)</code> on
+    the [[ownerdocument]] of <var>first node</var>.
+    <!--
+    This matches IE9, Firefox 4.0, and Chrome 12 dev.  If there's a preceding
+    <li>, Opera 11.10 instead adds the new parent to the end of that <li>, so
+    it's not the child of another list, which is invalid.  But the other
+    browsers' way of doing things makes things simpler.  E.g., if we want to
+    indent an <li> and it has <ol>/<ul> children, we have to distinguish
+    between the case where we want to indent the whole <li> or only the first
+    part.  It also allows things like
+
+      <ol><li>
+        foo
+        <ol><li>bar</li></ol>
+        baz
+      </li></ol>
+
+    in which case it's unclear what we should do if the user selects "foo" and
+    indents.  I've filed a bug on HTML5:
+
+    http://www.w3.org/Bugs/Public/show_bug.cgi?id=12609
+    -->
+
+    <li>Abort these steps.
+  </ol>
+
+  <!--
+  Firefox 4.0 respects the CSS styling flag for indent, but Chrome 12 dev does
+  not.  I always produce blockquotes, even if CSS styling is on, for two
+  reasons.  One, IE9 handles inline margin attributes badly: when outdenting,
+  it propagates the margin to the parent, which doesn't actually remove it.
+  Two, in CSS mode I'd want to use <div style="margin: 1em 40px"> to match
+  non-CSS mode, but authors are very likely to want to remove the top/bottom
+  margin, which they can't do if it's not a special tag.  Authors who really
+  want divs for indentation could always convert the blockquotes to divs
+  themselves.  But if people really want it, I could respect CSS styling mode
+  here too.
+
+  The top/bottom margins might be undesirable here, but no more so than for
+  <ol>/<ul>/<p>/etc.  Here as there, authors can remove them with CSS if they
+  want.
+  -->
+
+  <li><span>Wrap</span> <var>node list</var>, with <span>sibling
+  criteria</span> matching any <span>indentation element</span>, and <span>new
+  parent instructions</span> to return the result of calling <code
+  data-anolis-spec=domcore
+  title=dom-Document-createElement>createElement("blockquote")</code> on the
+  [[ownerdocument]] of <var>first node</var>.  Let <var>new parent</var> be the
+  result.
+  <!--
+  This indents on both sides, so we don't have to worry about directionality.
+  In theory it would be better if we indented only on the start side, but that
+  requires care to get right in mixed-direction cases.  Even once browsers
+  start to support margin-start and so on, we can't use them because a) we have
+  to work okay in legacy browsers and b) it doesn't help if a descendant block
+  has different direction (so should be indented the other way).  So let's not
+  worry about it: most browsers don't, and the ones that do get it wrong.  Just
+  indent on both sides.
+  -->
+
+  <li><span>Fix disallowed ancestors</span> of <var>new parent</var>.
+</ol>
+
 <p>To <dfn>outdent</dfn> a [[node]] <var>node</var>:
 
 <!--