On master: Abortive rewrite of forcing the value of a node, isn't going anywhere useful
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Sun, 22 May 2011 15:03:05 -0600
changeset 159 aeeb4b72f93e
parent 157 257bb7b1473a (current diff)
parent 158 719673d5b3e0 (diff)
On master: Abortive rewrite of forcing the value of a node, isn't going anywhere useful
editcommands.html
preprocess
source.html
--- a/editcommands.html	Sun May 22 13:38:03 2011 -0600
+++ b/editcommands.html	Sun May 22 15:03:05 2011 -0600
@@ -80,7 +80,7 @@
    <li><a href=#decomposing-a-range-into-nodes><span class=secno>6.3 </span>Decomposing a range into nodes</a></li>
    <li><a href="#clearing-an-element's-value"><span class=secno>6.4 </span>Clearing an element's value</a></li>
    <li><a href=#pushing-down-values><span class=secno>6.5 </span>Pushing down values</a></li>
-   <li><a href=#forcing-the-value-of-a-node><span class=secno>6.6 </span>Forcing the value of a node</a></li>
+   <li><a href=#forcing-the-value-of-a-run-of-nodes><span class=secno>6.6 </span>Forcing the value of a run of nodes</a></li>
    <li><a href=#setting-the-value-of-a-node><span class=secno>6.7 </span>Setting the value of a node</a></li>
    <li><a href=#the-backcolor-command><span class=secno>6.8 </span>The <code title="">backColor</code> command</a></li>
    <li><a href=#the-bold-command><span class=secno>6.9 </span>The <code title="">bold</code> command</a></li>
@@ -624,11 +624,11 @@
 own section of this specification.
 
 <p><a href=#command title=command>Commands</a> may have an associated
-<dfn id=action>action</dfn>, <dfn id=state>state</dfn>, <dfn id=value>value</dfn>, and/or <dfn id=relevant-css-property>relevant
-CSS property</dfn>.  If not otherwise specified, the <a href=#action>action</a> for a
-command is to do nothing, the <a href=#state>state</a> is false, the
-<a href=#value>value</a> is the empty string, and the <a href=#relevant-css-property>relevant CSS
-property</a> is null.
+<dfn id=action>action</dfn>, <dfn id=state>state</dfn>, <dfn id=value>value</dfn>, <dfn id=relevant-css-property>relevant CSS
+property</dfn>, and/or <dfn id=wrapper-element>wrapper element</dfn>.  If not otherwise specified,
+the <a href=#action>action</a> for a command is to do nothing, the <a href=#state>state</a>
+is false, the <a href=#value>value</a> is the empty string, the <a href=#relevant-css-property>relevant CSS
+property</a> is null, and the <a href=#wrapper-element>wrapper element</a> is false.
 <!-- Requesting the state of an unknown command throws an exception in IE 9 RC
 and Firefox 4b11, and returns boolean false in Chrome 10 and Opera 11.
 
@@ -642,7 +642,7 @@
 instructions as arguments.  When <code><a href=#querycommandstate()>queryCommandState()</a></code> is invoked,
 the user agent must return the <a href=#state>state</a> for <var title="">command</var>.  When
 <code><a href=#querycommandvalue()>queryCommandValue()</a></code> is invoked, the user agent must return the
-<a href=#value>value</a> for <var title="">command</var> 
+<a href=#value>value</a> for <var title="">command</var>
 
 <p>Most <a href=#command title=command>commands</a> act on the <dfn id=active-range>active range</dfn>.
 This is defined to be the first <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> in the <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code> given by calling
@@ -1201,9 +1201,9 @@
 </ol>
 
 
-<h3 id=forcing-the-value-of-a-node><span class=secno>6.6 </span>Forcing the value of a node</h3>
-<p>To <dfn id=force-the-value>force the 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> to <var title="">new
-value</var>:
+<h3 id=forcing-the-value-of-a-run-of-nodes><span class=secno>6.6 </span>Forcing the value of a run of nodes</h3>
+<p>To <dfn id=force-the-value>force the value</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> <var title="">new value</var>:
 
 <p class=note>This algorithm checks if the node has the desired value, and if
 not, it wraps the node (or, if that's not possible, its descendants) in a
@@ -1215,201 +1215,169 @@
 <ol>
   <li>Let <var title="">command</var> be the current <a href=#command>command</a>.
 
-  <li>If <var title="">node</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is null, abort this algorithm.
-
-  <li>If <var title="">new value</var> is null, abort this algorithm.
-
-  <li>If <var title="">node</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>, <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code>, or <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#comment>Comment</a></code> node, and
-  is not an <a href=#unwrappable-node>unwrappable node</a>:
+  <li>If <var title="">new value</var> is null, or 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> is null, abort this algorithm.
+
+  <li>If some member of <var title="">node list</var> is an <a href=#unwrappable-node>unwrappable
+  node</a>, then while <var title="">node list</var> is not empty:
 
   <ol>
-    <!-- Even if the value matches, we stick it in a preceding sibling if
-    possible.  This ensures "a<cite>b</cite>c" -> "<i>a<cite>b</cite>c</i>"
-    instead of "<i>a</i><cite>b</cite><i>c</i>".  While we're at it, we also
-    handle more elaborate cases like <b>foo</b>[bar]<b>baz</b> and even
-    <i><b>foo</b></i>[bar]<i><b>baz</b></i> (the latter becomes
-    <b><i>foo</i>bar<i>baz</i></b>).
-
-    Theoretically this algorithm could pointlessly reorganize the DOM in the
-    event of unreasonable style rules, but it's not a big enough deal for us to
-    care, since the resulting style will still be right. -->
-    <li>Let <var title="">candidate</var> be <var title="">node</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code>.
-
-    <li>While <var title="">candidate</var> is a <a href=#modifiable-element>modifiable element</a>, and
-    <var title="">candidate</var> has exactly one <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, and 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> is also
-    a <a href=#modifiable-element>modifiable element</a>, and <var title="">candidate</var> is not a
-    <a href=#simple-modifiable-element>simple modifiable element</a> or <var title="">candidate</var>'s
-    <a href=#specified-value>specified value</a> for <var title="">command</var> is not <var title="">new
-    value</var>, set <var title="">candidate</var> to its <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>.
-
-    <li>If <var title="">candidate</var> is a <a href=#simple-modifiable-element>simple modifiable element</a>
-    whose <a href=#specified-value>specified value</a> and <a href=#effective-value>effective value</a> for
-    <var title="">command</var> are both <var title="">new value</var>, and <var title="">candidate</var>
-    is not the <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> of <var title="">node</var>:
+    <li>Let <var title="">sublist</var> be the empty list.
+
+    <li>If the first member of <var title="">node list</var> is an <a href=#unwrappable-node>unwrappable
+    node</a>:
 
     <ol>
-      <li>While <var title="">candidate</var> has <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, insert 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="">candidate</var> into <var title="">candidate</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>
-      immediately before <var title="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
-
-      <li>Insert <var title="">candidate</var> into <var title="">node</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> before
-      <var title="">node</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code>.  <!-- If candidate had no
-      children, any boundary point inside it will get moved to its parent here,
-      which is okay.  We don't want to preserve ranges, because that would move
-      boundary points that originally were in candidate but were moved to its
-      parent by the last step to move to node's parent.  We move to before the
-      previous sibling so that boundary points before and after the previous
-      sibling wind up before or after candidate. -->
-
-      <li>Append the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of <var title="">candidate</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="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
+      <li>Let <var title="">node</var> be the first member of <var title="">node list</var>.
+
+      <li>Remove <var title="">node</var> from <var title="">node list</var>.
+
+      <li>If the <a href=#effective-value>effective value</a> of <var title="">command</var> on
+      <var title="">node</var> is <var title="">new value</var>, continue this loop from the
+      beginning.
+
+      <li>Let <var title="">children</var> be all <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a> of <var title="">node</var>.
+
+      <li>While <var title="">children</var> is not empty:
+      <!-- This means that if it has no children, we do nothing.  IE9 inserts
+      an empty wrapper element in that case, but I'm not sure what the point
+      is, and no one else does, so I don't.  WebKit seems to ignore the node if
+      its only child consists solely of whitespace, but I don't see any grounds
+      for that and no one else does, so I don't. -->
+
+      <ol>
+        <li>If the first member of <var title="">children</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> whose
+        <a href=#specified-value>specified value</a> for <var title="">command</var> is neither null nor
+        equal to <var title="">new value</var>, remove it from <var title="">children</var> and
+        continue this loop from the beginning.
+
+        <li>While <var title="">children</var> is not empty and its first member is not
+        an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> or has <a href=#specified-value>specified value</a> for
+        <var title="">command</var> equal to null or <var title="">new value</var>, remove it
+        from <var title="">children</var> and append it to <var title="">sublist</var>.
+
+        <a href=#force-the-value>Force the value</a> of <var title="">sublist</var>.
+      </ol>
+
+      <li>Continue this loop from the beginning.
     </ol>
 
-    <li>Let <var title="">candidate</var> be <var title="">node</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code>.
-
-    <li>While <var title="">candidate</var> is a <a href=#modifiable-element>modifiable element</a>, and
-    <var title="">candidate</var> has exactly one <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, and 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> is also
-    a <a href=#modifiable-element>modifiable element</a>, and <var title="">candidate</var> is not a
-    <a href=#simple-modifiable-element>simple modifiable element</a> or <var title="">candidate</var>'s
-    <a href=#specified-value>specified value</a> for <var title="">command</var> is not <var title="">new
-    value</var>, set <var title="">candidate</var> to its <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>.
-
-    <li>If <var title="">candidate</var> is a <a href=#simple-modifiable-element>simple modifiable element</a>
-    whose <a href=#specified-value>specified value</a> and <a href=#effective-value>effective value</a> for
-    <var title="">command</var> are both <var title="">new value</var>, and <var title="">candidate</var>
-    is not the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of <var title="">node</var>:
-
-    <ol>
-      <li>While <var title="">candidate</var> has <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, insert 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="">candidate</var> into <var title="">candidate</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>
-      immediately before <var title="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
-
-      <li>Insert <var title="">candidate</var> into <var title="">node</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> after
-      <var title="">node</var>. <!-- Thus candidate is between the same boundary points
-      as node's next sibling, not the same as node.  When inserting, the new
-      thing always gets put in the same place as its next sibling, not its
-      previous sibling: a boundary point at the place it's inserted moves
-      before the new node, not after. -->
-
-      <li>Append the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of <var title="">candidate</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="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
-    </ol>
-
-    <li>Let <var title="">previous sibling</var> and <var title="">next sibling</var> be
-    <var title="">node</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> and <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>.
-
-    <li>If <var title="">previous sibling</var> is a <a href=#simple-modifiable-element>simple modifiable
-    element</a> whose <a href=#specified-value>specified value</a> and <a href=#effective-value>effective
-    value</a> for <var title="">command</var> are both <var title="">new value</var>, append
-    <var title="">node</var> as the last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">previous sibling</var>,
-    <a href=#preserving-ranges>preserving ranges</a>.
-
-    <li>If <var title="">next sibling</var> is a <a href=#simple-modifiable-element>simple modifiable element</a>
-    whose <a href=#specified-value>specified value</a> and <a href=#effective-value>effective value</a> for
-    <var title="">command</var> are both <var title="">new value</var>:
-
-    <ol>
-      <li>If <var title="">node</var> is not 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> of <var title="">previous sibling</var>,
-      insert <var title="">node</var> as the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">next sibling</var>,
-      <a href=#preserving-ranges>preserving ranges</a>.
-
-      <li>Otherwise, while <var title="">next sibling</var> has <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, append 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="">next sibling</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="">previous sibling</var>, <a href=#preserving-ranges>preserving ranges</a>.  Then remove
-      <var title="">next sibling</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>.
-    </ol>
+    <li>While <var title="">node list</var> is not empty and its first member <var title="">node
+    list</var> is not an <a href=#unwrappable-node>unwrappable node</a>, remove it from
+    <var title="">node list</var> and append it to <var title="">sublist</var>.
+
+    <li><a href=#force-the-value>Force the value</a> of <var title="">sublist</var>.
+  </ol>
+
+  <li>If <var title="">node list</var> is empty, abort this algorithm.
+
+  <!-- Now all the nodes are wrappable. -->
+
+  <li>If the <a href=#effective-value>effective value</a> of <var title="">command</var> is <var title="">new
+  value</var> on every member of <var title="">node list</var>, abort this algorithm.
+
+  <!--
+  This bit tries to handle cases like
+
+    <i><b>foo</b></i>[bar]<i><b>baz</b></i>
+    -> <b><i>foo</i></b>bar<b><i>baz</i></b>
+
+  so that wrapping will result in
+
+    <b><i>foo</i>bar<i>baz</i></b>
+
+  instead of
+
+    <i><b>foo</b></i><b>bar</b><i><b>baz</b></i>.
+
+  Theoretically this algorithm could pointlessly reorganize the DOM in the
+  event of unreasonable style rules, but it's not a big enough deal for us to
+  care, since the resulting style will still be right.
+  -->
+  <li>Let <var title="">candidate</var> be the <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> of the first member
+  of <var title="">node list</var>.
+
+  <li>While <var title="">candidate</var> is a <a href=#modifiable-element>modifiable element</a>, and
+  <var title="">candidate</var> has exactly one <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, and 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> is also a
+  <a href=#modifiable-element>modifiable element</a>, and <var title="">candidate</var> is not a
+  <a href=#simple-modifiable-element>simple modifiable element</a> or <var title="">candidate</var>'s
+  <a href=#specified-value>specified value</a> for <var title="">command</var> is not <var title="">new
+  value</var>, set <var title="">candidate</var> to its <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>.
+
+  <li>If <var title="">candidate</var> is a <a href=#simple-modifiable-element>simple modifiable element</a> whose
+  <a href=#specified-value>specified value</a> and <a href=#effective-value>effective value</a> for
+  <var title="">command</var> are both <var title="">new value</var>, and <var title="">candidate</var> is
+  not 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>:
+
+  <ol>
+    <li>While <var title="">candidate</var> has <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, insert 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="">candidate</var> into <var title="">candidate</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> immediately
+    before <var title="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
+
+    <li>Insert <var title="">candidate</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 the first member of
+    <var title="">node list</var> before 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>.
+    <!--
+    If candidate had no children, any boundary point inside it will get moved
+    to its parent here, which is okay.  We don't want to preserve ranges,
+    because that would move boundary points that originally were in candidate
+    but were moved to its parent by the last step to move to the parent of the
+    first member of node list.  We move to before the previous sibling so that
+    boundary points before and after the previous sibling wind up before or
+    after candidate.
+    -->
+
+    <li>Append the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of <var title="">candidate</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="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
+  </ol>
+
+  <li>Let <var title="">candidate</var> be the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of the last member of
+  <var title="">node list</var>.
+
+  <li>While <var title="">candidate</var> is a <a href=#modifiable-element>modifiable element</a>, and
+  <var title="">candidate</var> has exactly one <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, and 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> is also a
+  <a href=#modifiable-element>modifiable element</a>, and <var title="">candidate</var> is not a
+  <a href=#simple-modifiable-element>simple modifiable element</a> or <var title="">candidate</var>'s
+  <a href=#specified-value>specified value</a> for <var title="">command</var> is not <var title="">new
+  value</var>, set <var title="">candidate</var> to its <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>.
+
+  <li>If <var title="">candidate</var> is a <a href=#simple-modifiable-element>simple modifiable element</a> whose
+  <a href=#specified-value>specified value</a> and <a href=#effective-value>effective value</a> for
+  <var title="">command</var> are both <var title="">new value</var>, and <var title="">candidate</var> is
+  not the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of the last member of <var title="">node list</var>:
+
+  <ol>
+    <li>While <var title="">candidate</var> has <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, insert 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="">candidate</var> into <var title="">candidate</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> immediately
+    before <var title="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
+
+    <li>Insert <var title="">candidate</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 the last member of
+    <var title="">node list</var> after the last member of <var title="">node list</var>.
+    <!--
+    Thus candidate is between the same boundary points as node's next sibling,
+    not the same as the last member of node list.  When inserting, the new
+    thing always gets put in the same place as its next sibling, not its
+    previous sibling: a boundary point at the place it's inserted moves before
+    the new node, not after.
+    -->
+
+    <li>Append the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of <var title="">candidate</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="">candidate</var>, <a href=#preserving-ranges>preserving ranges</a>.
   </ol>
 
   <li>If the <a href=#effective-value>effective value</a> of <var title="">command</var> is <var title="">new
   value</var> on <var title="">node</var>, abort this algorithm.
 
-  <li>If <var title="">node</var> is an <a href=#unwrappable-node>unwrappable node</a>:
-
-  <ol>
-    <li>Let <var title="">children</var> be all <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a> of <var title="">node</var>,
-    omitting any that are <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>s whose <a href=#specified-value>specified value</a> for
-    <var title="">command</var> is neither null nor equal to <var title="">new value</var>.
-
-    <li><a href=#force-the-value>Force the value</a> of each <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> in <var title="">children</var>,
-    with <var title="">command</var> and <var title="">new value</var> as in this invocation of
-    the algorithm.
-    <!-- This means that if it has no children, we do nothing.  IE9 inserts an
-    empty wrapper element in that case, but I'm not sure what the point is, and
-    no one else does, so I don't.  WebKit seems to ignore the node if its only
-    child consists solely of whitespace, but I don't see any grounds for that
-    and no one else does, so I don't. -->
-
-    <li>Abort this algorithm.
-  </ol>
-
-  <!-- At this point we have to make a new element as a wrapper.  This isn't
-  worth the effort for comments, so abort in that case. -->
-  <li>If <var title="">node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#comment>Comment</a></code>, abort this algorithm.
-
-  <li>If the <a href=#effective-value>effective value</a> of <var title="">command</var> is <var title="">new
-  value</var> on <var title="">node</var>, abort this algorithm.
-
-  <li>Let <var title="">new parent</var> be null.
-
-  <li>If the <a href=#css-styling-flag>CSS styling flag</a> is false:
-
-  <ol>
-    <li>If <var title="">command</var> is "bold" and <var title="">new value</var> is
-    "bold", let <var title="">new parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("b")</a></code> on the
-    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-    <li>If <var title="">command</var> is "italic" and <var title="">new value</var> is
-    "italic", let <var title="">new parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("i")</a></code> on the
-    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-    <li>If <var title="">command</var> is "strikethrough" and <var title="">new value</var> is
-    "line-through", let <var title="">new parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("s")</a></code> on the
-    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-    <p class=XXX>Actual UAs use strike, not s, but s is shorter and HTML5 makes
-    strike invalid.  I've gone with s for now, but maybe we want to change the
-    spec to require strike.
-
-    <li>If <var title="">command</var> is "underline" and <var title="">new value</var> is
-    "underline", let <var title="">new parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("u")</a></code> on the
-    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-    <li>If <var title="">command</var> is "foreColor", and <var title="">new value</var> is fully
-    opaque with red, green, and blue components in the range 0 to 255:
-
-    <ol>
-      <li>Let <var title="">new parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("font")</a></code> on the
-      <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-      <li>If <var title="">new value</var> is one of the colors listed in the SVG color
-      keywords section of CSS3 Color, set the <code class=external data-anolis-spec=html title=dom-font-color><a href=http://www.whatwg.org/html/#dom-font-color>color</a></code> attribute of
-      <var title="">new parent</var> to <var title="">new value</var>.
-
-      <li>Otherwise, set the <code class=external data-anolis-spec=html title=dom-font-color><a href=http://www.whatwg.org/html/#dom-font-color>color</a></code> attribute of <var title="">new parent</var>
-      to the result of applying the <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#rules-for-serializing-simple-color-values>rules for
-      serializing simple color values</a> to <var title="">new value</var>
-      (interpreted as a <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#simple-color>simple color</a>).
-    </ol>
-
-    <li>If <var title="">command</var> is "fontName", let <var title="">new parent</var> be
-    the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("font")</a></code> on the
-    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, then set the <code class=external data-anolis-spec=html title=dom-font-face><a href=http://www.whatwg.org/html/#dom-font-face>face</a></code> attribute
-    of <var title="">new parent</var> to <var title="">new value</var>.
-  </ol>
+  <!-- At this point we have to make a new element as a wrapper. -->
 
   <li>If <var title="">command</var> is "createLink" or "unlink":
 
   <ol>
-    <li>Let <var title="">new parent</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("a")</a></code> on the
-    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-    <li>Set the <code class=external data-anolis-spec=html title=attr-hyperlink-href><a href=http://www.whatwg.org/html/#attr-hyperlink-href>href</a></code> attribute of <var title="">new parent</var> to <var title="">new
-    value</var>.
-
     <!-- Nested a elements are bad, because they can't be serialized to
     text/html.  hrefs should already have been cleared in a previous step, but
     we might have <a name> or such lurking about. -->
-    <li>Let <var title="">ancestor</var> be <var title="">node</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+    <li>Let <var title="">ancestor</var> be the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of the first member of
+    <var title="">node list</var>.
 
     <li>While <var title="">ancestor</var> is not null:
 
@@ -1427,49 +1395,27 @@
     </ol>
   </ol>
 
-  <!-- WebKit is the only engine that ever outputs anything but font tags for
-  fontSize.  For size=7, it uses font-size: -webkit-xxx-large.  We just output
-  a font tag no matter what. -->
-  <li>If <var title="">command</var> is "fontSize"; and <var title="">new value</var> is one of
-  "xx-small", "small", "medium", "large", "x-large", "xx-large", or
-  "xxx-large"; and either the <a href=#css-styling-flag>CSS styling flag</a> is false, or
-  <var title="">new value</var> is "xxx-large": let <var title="">new parent</var> be the result
-  of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("font")</a></code> on the
-  <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, then set the <code class=external data-anolis-spec=html title=dom-font-size><a href=http://www.whatwg.org/html/#dom-font-size>size</a></code> attribute of
-  <var title="">new parent</var> to the number from the following table based on
-  <var title="">new value</var>:
-
-  <dl class=switch>
-    <dt>xx-small <dd>1
-    <dt>small <dd>2
-    <dt>normal <dd>3
-    <dt>large <dd>4
-    <dt>x-large <dd>5
-    <dt>xx-large <dd>6
-    <dt>xxx-large <dd>7
-  </dl>
-
-  <!-- We always use sup/sub elements, even in CSS mode, following Gecko and
-  contradicting WebKit.  This is because <span value="vertical-align:
-  sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
-  differently: it doesn't reduce font-size, which is ugly. -->
-  <li>If <var title="">command</var> is "subscript" or "superscript" and <var title="">new
-  value</var> is "sub", let <var title="">new parent</var> be the result of calling
-  <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("sub")</a></code> on the
-  <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-  <li>If <var title="">command</var> is "subscript" or "superscript" and <var title="">new
-  value</var> is "super", let <var title="">new parent</var> be the result of calling
-  <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("sup")</a></code> on the
-  <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-  <li>If <var title="">new parent</var> is null, let <var title="">new parent</var> be the result
-  of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("span")</a></code> on the
-  <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
-
-  <li>Insert <var title="">new parent</var> in <var title="">node</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> before
-  <var title="">node</var>.  <!-- This preserves boundary points correctly, as usual.
-  -->
+  <li><a href=#wrap>Wrap</a> <var title="">node list</var>, and let <var title="">new parent</var> be
+  the result.  <a href=#sibling-criteria>Sibling criteria</a> match any <a href=#simple-modifiable-element>simple modifiable
+  element</a> whose <a href=#specified-value>specified value</a> and <a href=#effective-value>effective
+  value</a> are both <var title="">new value</var>.  <a href=#new-parent-instructions>New parent
+  instructions</a> are as follows:
+
+  <ol>
+    <li>Let <var title="">new parent</var> be null.
+
+    <li>If there is a <a href=#wrapper-element>wrapper element</a> defined for
+    <var title="">command</var>, let <var title="">new parent</var> be the result of running
+    those instructions, with <var title="">new value</var> as in this algorithm, and
+    <var title="">document</var> equal to the <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of the first member of
+    <var title="">node list</var>.
+
+    <li>If <var title="">new parent</var> is null, set <var title="">new parent</var> to the
+    result of running <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("span")</a></code> on the <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of the
+    first member of <var title="">node list</var>.
+
+    <li>Return <var title="">new parent</var>.
+  </ol>
 
   <li>If the <a href=#effective-value>effective value</a> of <var title="">command</var> for <var title="">new
   parent</var> is not <var title="">new value</var>, and the <a href=#relevant-css-property>relevant CSS
@@ -1487,18 +1433,15 @@
   parent</var> is not "underline", set the "text-decoration" property of
   <var title="">new parent</var> to "underline".
 
-  <li>Append <var title="">node</var> to <var title="">new parent</var> as 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>,
-  <a href=#preserving-ranges>preserving ranges</a>.
-
-  <li>If <var title="">node</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> and the <a href=#effective-value>effective value</a>
-  of <var title="">command</var> for <var title="">node</var> is not <var title="">new value</var>:
+  <li>If the <a href=#effective-value>effective value</a> of every <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new
+  parent</var> is something other than <var title="">new value</var>, remove <var title="">new
+  parent</var>, <a href=#preserving-its-descendants>preserving its descendants</a>.
+
+  <li>For each <var title="">node</var> in <var title="">node list</var>, if <var title="">node</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> and the <a href=#effective-value>effective value</a> of <var title="">command</var> for
+  <var title="">node</var> is not <var title="">new value</var>:
 
   <ol>
-    <li>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="">new parent</var>
-    before <var title="">new parent</var>, <a href=#preserving-ranges>preserving ranges</a>.
-
-    <li>Remove <var title="">new 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="">new parent</var> is a <code class=external data-anolis-spec=html title="the span element"><a href=http://www.whatwg.org/html/#the-span-element>span</a></code>, and either a)
     <var title="">command</var> is "underline" or "strikethrough", or b)
     <var title="">command</var> is "fontSize" and <var title="">new value</var> is not
@@ -1766,6 +1709,10 @@
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "font-weight"
 
+<p><a href=#wrapper-element>Wrapper element</a>: If the <a href=#css-styling-flag>CSS styling flag</a> is true
+or <var title="">new value</var> is not "bold", return false.  Otherwise, 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("b")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.
+
 
 <h3 id=the-createlink-command><span class=secno>6.10 </span><dfn>The <code title="">createLink</code> command</dfn></h3>
 
@@ -1824,6 +1771,11 @@
 <p><a href=#value>Value</a>: Always the empty string.
 <!-- I'd have expected the value to be the URL, but guess not. -->
 
+<p><a href=#wrapper-element>Wrapper element</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("a")</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 let <var title="">new parent</var> be the result.  Then call
+<code class=external data-anolis-spec=domcore title=dom-Element-setAttribute><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-setattribute>setAttribute("href", <var title="">new value</var>)</a></code> on <var title="">new parent</var>, and
+return <var title="">new parent</var>.
+
 
 <h3 id=the-fontname-command><span class=secno>6.11 </span><dfn>The <code title="">fontName</code> command</dfn></h3>
 
@@ -1873,6 +1825,12 @@
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "font-family"
 
+<p><a href=#wrapper-element>Wrapper element</a>: If the <a href=#css-styling-flag>CSS styling flag</a> is true,
+return false.  Otherwise, 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("font")</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 let <var title="">new parent</var> be the result; then call
+<code class=external data-anolis-spec=domcore title=dom-Element-setAttribute><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-setattribute>setAttribute("face", <var title="">new value</var>)</a></code> on <var title="">new parent</var>; then
+return <var title="">new parent</var>.
+
 
 <h3 id=the-fontsize-command><span class=secno>6.12 </span><dfn>The <code title="">fontSize</code> command</dfn></h3>
 
@@ -1980,6 +1938,40 @@
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "font-size"
 
+<p><a href=#wrapper-element>Wrapper element</a>:
+<!-- WebKit is the only engine that ever outputs anything but font tags for
+fontSize.  For size=7, it uses font-size: -webkit-xxx-large.  We just output a
+font tag no matter what. -->
+
+<ol>
+  <li>If <var title="">new value</var> is not one of "xx-small", "small", "medium", "large",
+  "x-large", "xx-large", or "xxx-large", return false.
+
+  <li>If the <a href=#css-styling-flag>CSS styling flag</a> is true and <var title="">new value</var> is
+  not "xxx-large", return false.
+
+  <li>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("font")</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 let <var title="">new
+  parent</var> be the result.
+
+  <li>Set <var title="">numeric value</var> from the following table based on <var title="">new
+  value</var>:
+
+  <dl class=switch>
+  <dt>xx-small <dd>1
+  <dt>small <dd>2
+  <dt>medium <dd>3
+  <dt>large <dd>4
+  <dt>x-large <dd>5
+  <dt>xx-large <dd>6
+  <dt>xxx-large <dd>7
+  </dl>
+
+  <li>Call <code class=external data-anolis-spec=domcore title=dom-Element-setAttribute><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-setattribute>setAttribute("size", <var title="">numeric value</var>)</a></code> on <var title="">new
+  parent</var>.
+
+  <li>Return <var title="">new parent</var>.
+</ol>
+
 
 <h3 id=the-forecolor-command><span class=secno>6.13 </span><dfn>The <code title="">foreColor</code> command</dfn></h3>
 
@@ -2065,6 +2057,25 @@
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "color"
 
+<p><a href=#wrapper-element>Wrapper element</a>:
+
+<ol>
+  <li>If the <a href=#css-styling-flag>CSS styling flag</a> is false; or <var title="">new value</var> is
+  not fully opaque; or <var title="">new value</var> has a red, green, or blue component
+  less than 0 or greater than 255; return false;
+
+  <li>Let <var title="">new parent</var> be the result of calling
+  <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("font")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.
+
+  <li>If <var title="">new value</var> is one of the keywords listed in the SVG color
+  keywords section of CSS3 color, set the <code class=external data-anolis-spec=html title=dom-font-color><a href=http://www.whatwg.org/html/#dom-font-color>color</a></code> attribute of <var title="">new
+  parent</var> to <var title="">new value</var>.
+
+  <li>Otherwise, set the <code class=external data-anolis-spec=html title=dom-font-color><a href=http://www.whatwg.org/html/#dom-font-color>color</a></code> attribute of <var title="">new parent</var> to
+  the result of applying the <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#rules-for-serializing-simple-color-values>rules for serializing
+  simple color values</a> to <var title="">new value</var> (interpreted as a <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#simple-color>simple color</a>).
+</ol>
+
 
 <h3 id=the-hilitecolor-command><span class=secno>6.14 </span><dfn>The <code title="">hiliteColor</code> command</dfn></h3>
 <!-- IE 9 RC doesn't support this.  It uses backColor instead, but Gecko and
@@ -2192,6 +2203,10 @@
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "font-style"
 
+<p><a href=#wrapper-element>Wrapper element</a>: If the <a href=#css-styling-flag>CSS styling flag</a> is true
+or <var title="">new value</var> is not "italic", return false.  Otherwise, 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("i")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.
+
 
 <h3 id=the-removeformat-command><span class=secno>6.18 </span><dfn>The <code title="">removeFormat</code> command</dfn></h3>
 <!--
@@ -2328,6 +2343,15 @@
 
 <p><a href=#value>Value</a>: Always the empty string.
 
+<p><a href=#wrapper-element>Wrapper element</a>: If the <a href=#css-styling-flag>CSS styling flag</a> is true
+or <var title="">new value</var> is not "line-through", return false.  Otherwise, 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("s")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.
+
+<p class=XXX>Actual UAs use strike, not s, but s is shorter and HTML5 makes
+strike invalid.  I've gone with s for now, but maybe we want to change the spec
+to require strike.
+
+
 
 <h3 id=the-subscript-command><span class=secno>6.20 </span><dfn>The <code title="">subscript</code> command</dfn></h3>
 
@@ -2336,9 +2360,9 @@
 <ol>
   <li><a href=#decompose>Decompose</a> the <a href=#active-range>active range</a>, and let <var title="">node
   list</var> be the result.
-  
+
   <li>Let <var title="">state</var> be the <a href=#state>state</a>.
-  
+
   <li><a href=#set-the-value>Set the value</a> of <var title="">node list</var> to "baseline".
 
   <li>If <var title="">state</var> is false, <a href=#decompose>decompose</a> the <a href=#active-range>active
@@ -2351,6 +2375,15 @@
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "vertical-align"
 
+<!-- We always use sup/sub elements, even in CSS mode, following Gecko and
+contradicting WebKit.  This is because <span value="vertical-align:
+sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
+differently: it doesn't reduce font-size, which is ugly. -->
+<p><a href=#wrapper-element>Wrapper element</a>: If <var title="">new value</var> is "sub", 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("sub")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.
+Otherwise, if <var title="">new value</var> is "super", 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("sup")</a></code> on
+the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.  Otherwise, return false.
+
 
 <h3 id=the-superscript-command><span class=secno>6.21 </span><dfn>The <code title="">superscript</code> command</dfn></h3>
 
@@ -2359,9 +2392,9 @@
 <ol>
   <li><a href=#decompose>Decompose</a> the <a href=#active-range>active range</a>, and let <var title="">node
   list</var> be the result.
-  
+
   <li>Let <var title="">state</var> be the <a href=#state>state</a>.
-  
+
   <li><a href=#set-the-value>Set the value</a> of <var title="">node list</var> to "baseline".
 
   <li>If <var title="">state</var> is false, <a href=#decompose>decompose</a> the <a href=#active-range>active
@@ -2374,6 +2407,15 @@
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "vertical-align"
 
+<!-- We always use sup/sub elements, even in CSS mode, following Gecko and
+contradicting WebKit.  This is because <span value="vertical-align:
+sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
+differently: it doesn't reduce font-size, which is ugly. -->
+<p><a href=#wrapper-element>Wrapper element</a>: If <var title="">new value</var> is "sub", 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("sub")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.
+Otherwise, if <var title="">new value</var> is "super", 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("sup")</a></code> on
+the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.  Otherwise, return false.
+
 
 <h3 id=the-underline-command><span class=secno>6.22 </span><dfn>The <code title="">underline</code> command</dfn></h3>
 
@@ -2436,6 +2478,10 @@
 
 <p><a href=#value>Value</a>: Always the empty string.
 
+<p><a href=#wrapper-element>Wrapper element</a>: If the <a href=#css-styling-flag>CSS styling flag</a> is true
+or <var title="">new value</var> is not "underline", return false.  Otherwise, 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("u")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and return the result.
+
 
 <h3 id=the-unlink-command><span class=secno>6.23 </span><dfn>The <code title="">unlink</code> command</dfn></h3>
 
@@ -2461,6 +2507,11 @@
 
 <p><a href=#value>Value</a>: Always the empty string.
 
+<p><a href=#wrapper-element>Wrapper element</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("a")</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 let <var title="">new parent</var> be the result.  Then call
+<code class=external data-anolis-spec=domcore title=dom-Element-setAttribute><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-setattribute>setAttribute("href", <var title="">new value</var>)</a></code> on <var title="">new parent</var>, and
+return <var title="">new parent</var>.
+
 
 <h2 id=block-formatting-commands><span class=secno>7 </span>Block formatting commands</h2>
 
--- a/preprocess	Sun May 22 13:38:03 2011 -0600
+++ b/preprocess	Sun May 22 15:03:05 2011 -0600
@@ -4,6 +4,7 @@
 # <span data-anolis-spec=domcore title=concept-element-namespace>namespace</span>.
 # <var title> is also really pointless, although I should really get that fixed
 # in Anolis proper.
+import re
 
 replace = {
     'a': '<code data-anolis-spec=html title="the a element">a</code>',
@@ -89,6 +90,14 @@
     capreplace = ">".join(capreplace)
     s = s.replace("[[" + key.capitalize() + "]]", capreplace)
 
+fnreplace = {
+    'createelement': r'<code data-anolis-spec=domcore title=dom-Document-createElement>createElement(\1)</code>',
+    'setattribute': r'<code data-anolis-spec=domcore title=dom-Element-setAttribute>setAttribute(\1)</code>',
+}
+
+for key in fnreplace:
+    s = re.sub(r"\[\[" + key + r"\|([^]]+)\]\]", fnreplace[key], s)
+
 if "[[" in s:
     raise Exception("Something mistyped?  " + s[s.find("[["):s.rfind("]]") + 2])
 
--- a/source.html	Sun May 22 13:38:03 2011 -0600
+++ b/source.html	Sun May 22 15:03:05 2011 -0600
@@ -591,11 +591,11 @@
 own section of this specification.
 
 <p><span title=command>Commands</span> may have an associated
-<dfn>action</dfn>, <dfn>state</dfn>, <dfn>value</dfn>, and/or <dfn>relevant
-CSS property</dfn>.  If not otherwise specified, the <span>action</span> for a
-command is to do nothing, the <span>state</span> is false, the
-<span>value</span> is the empty string, and the <span>relevant CSS
-property</span> is null.
+<dfn>action</dfn>, <dfn>state</dfn>, <dfn>value</dfn>, <dfn>relevant CSS
+property</dfn>, and/or <dfn>wrapper element</dfn>.  If not otherwise specified,
+the <span>action</span> for a command is to do nothing, the <span>state</span>
+is false, the <span>value</span> is the empty string, the <span>relevant CSS
+property</span> is null, and the <span>wrapper element</span> is false.
 <!-- Requesting the state of an unknown command throws an exception in IE 9 RC
 and Firefox 4b11, and returns boolean false in Chrome 10 and Opera 11.
 
@@ -609,7 +609,7 @@
 instructions as arguments.  When <code>queryCommandState()</code> is invoked,
 the user agent must return the <span>state</span> for <var>command</var>.  When
 <code>queryCommandValue()</code> is invoked, the user agent must return the
-<span>value</span> for <var>command</var> 
+<span>value</span> for <var>command</var>
 
 <p>Most <span title=command>commands</span> act on the <dfn>active range</dfn>.
 This is defined to be the first [[range]] in the [[selection]] given by calling
@@ -1173,9 +1173,9 @@
 </ol>
 
 
-<h3>Forcing the value of a node</h3>
-<p>To <dfn>force the value</dfn> of a [[node]] <var>node</var> to <var>new
-value</var>:
+<h3>Forcing the value of a run of nodes</h3>
+<p>To <dfn>force the value</dfn> of a list <var>node list</var> of consecutive
+[[sibling]] [[nodes]] <var>new value</var>:
 
 <p class=note>This algorithm checks if the node has the desired value, and if
 not, it wraps the node (or, if that's not possible, its descendants) in a
@@ -1188,214 +1188,169 @@
 <ol>
   <li>Let <var>command</var> be the current <span>command</span>.
 
-  <li>If <var>node</var>'s [[parent]] is null, abort this algorithm.
-
-  <li>If <var>new value</var> is null, abort this algorithm.
-
-  <li>If <var>node</var> is an [[element]], [[text]], or [[comment]] node, and
-  is not an <span>unwrappable node</span>:
+  <li>If <var>new value</var> is null, or the [[parent]] of the first member of
+  <var>node list</var> is null, abort this algorithm.
+
+  <li>If some member of <var>node list</var> is an <span>unwrappable
+  node</span>, then while <var>node list</var> is not empty:
 
   <ol>
-    <!-- Even if the value matches, we stick it in a preceding sibling if
-    possible.  This ensures "a<cite>b</cite>c" -> "<i>a<cite>b</cite>c</i>"
-    instead of "<i>a</i><cite>b</cite><i>c</i>".  While we're at it, we also
-    handle more elaborate cases like <b>foo</b>[bar]<b>baz</b> and even
-    <i><b>foo</b></i>[bar]<i><b>baz</b></i> (the latter becomes
-    <b><i>foo</i>bar<i>baz</i></b>).
-
-    Theoretically this algorithm could pointlessly reorganize the DOM in the
-    event of unreasonable style rules, but it's not a big enough deal for us to
-    care, since the resulting style will still be right. -->
-    <li>Let <var>candidate</var> be <var>node</var>'s [[previoussibling]].
-
-    <li>While <var>candidate</var> is a <span>modifiable element</span>, and
-    <var>candidate</var> has exactly one [[child]], and that [[child]] is also
-    a <span>modifiable element</span>, and <var>candidate</var> is not a
-    <span>simple modifiable element</span> or <var>candidate</var>'s
-    <span>specified value</span> for <var>command</var> is not <var>new
-    value</var>, set <var>candidate</var> to its [[child]].
-
-    <li>If <var>candidate</var> is a <span>simple modifiable element</span>
-    whose <span>specified value</span> and <span>effective value</span> for
-    <var>command</var> are both <var>new value</var>, and <var>candidate</var>
-    is not the [[previoussibling]] of <var>node</var>:
+    <li>Let <var>sublist</var> be the empty list.
+
+    <li>If the first member of <var>node list</var> is an <span>unwrappable
+    node</span>:
 
     <ol>
-      <li>While <var>candidate</var> has [[children]], insert the first
-      [[child]] of <var>candidate</var> into <var>candidate</var>'s [[parent]]
-      immediately before <var>candidate</var>, <span>preserving ranges</span>.
-
-      <li>Insert <var>candidate</var> into <var>node</var>'s [[parent]] before
-      <var>node</var>'s [[previoussibling]].  <!-- If candidate had no
-      children, any boundary point inside it will get moved to its parent here,
-      which is okay.  We don't want to preserve ranges, because that would move
-      boundary points that originally were in candidate but were moved to its
-      parent by the last step to move to node's parent.  We move to before the
-      previous sibling so that boundary points before and after the previous
-      sibling wind up before or after candidate. -->
-
-      <li>Append the [[nextsibling]] of <var>candidate</var> as the last
-      [[child]] of <var>candidate</var>, <span>preserving ranges</span>.
+      <li>Let <var>node</var> be the first member of <var>node list</var>.
+
+      <li>Remove <var>node</var> from <var>node list</var>.
+
+      <li>If the <span>effective value</span> of <var>command</var> on
+      <var>node</var> is <var>new value</var>, continue this loop from the
+      beginning.
+
+      <li>Let <var>children</var> be all [[children]] of <var>node</var>.
+
+      <li>While <var>children</var> is not empty:
+      <!-- This means that if it has no children, we do nothing.  IE9 inserts
+      an empty wrapper element in that case, but I'm not sure what the point
+      is, and no one else does, so I don't.  WebKit seems to ignore the node if
+      its only child consists solely of whitespace, but I don't see any grounds
+      for that and no one else does, so I don't. -->
+
+      <ol>
+        <li>If the first member of <var>children</var> is an [[element]] whose
+        <span>specified value</span> for <var>command</var> is neither null nor
+        equal to <var>new value</var>, remove it from <var>children</var> and
+        continue this loop from the beginning.
+
+        <li>While <var>children</var> is not empty and its first member is not
+        an [[element]] or has <span>specified value</span> for
+        <var>command</var> equal to null or <var>new value</var>, remove it
+        from <var>children</var> and append it to <var>sublist</var>.
+
+        <span>Force the value</span> of <var>sublist</var>.
+      </ol>
+
+      <li>Continue this loop from the beginning.
     </ol>
 
-    <li>Let <var>candidate</var> be <var>node</var>'s [[nextsibling]].
-
-    <li>While <var>candidate</var> is a <span>modifiable element</span>, and
-    <var>candidate</var> has exactly one [[child]], and that [[child]] is also
-    a <span>modifiable element</span>, and <var>candidate</var> is not a
-    <span>simple modifiable element</span> or <var>candidate</var>'s
-    <span>specified value</span> for <var>command</var> is not <var>new
-    value</var>, set <var>candidate</var> to its [[child]].
-
-    <li>If <var>candidate</var> is a <span>simple modifiable element</span>
-    whose <span>specified value</span> and <span>effective value</span> for
-    <var>command</var> are both <var>new value</var>, and <var>candidate</var>
-    is not the [[nextsibling]] of <var>node</var>:
-
-    <ol>
-      <li>While <var>candidate</var> has [[children]], insert the first
-      [[child]] of <var>candidate</var> into <var>candidate</var>'s [[parent]]
-      immediately before <var>candidate</var>, <span>preserving ranges</span>.
-
-      <li>Insert <var>candidate</var> into <var>node</var>'s [[parent]] after
-      <var>node</var>. <!-- Thus candidate is between the same boundary points
-      as node's next sibling, not the same as node.  When inserting, the new
-      thing always gets put in the same place as its next sibling, not its
-      previous sibling: a boundary point at the place it's inserted moves
-      before the new node, not after. -->
-
-      <li>Append the [[nextsibling]] of <var>candidate</var> as the last
-      [[child]] of <var>candidate</var>, <span>preserving ranges</span>.
-    </ol>
-
-    <li>Let <var>previous sibling</var> and <var>next sibling</var> be
-    <var>node</var>'s [[previoussibling]] and [[nextsibling]].
-
-    <li>If <var>previous sibling</var> is a <span>simple modifiable
-    element</span> whose <span>specified value</span> and <span>effective
-    value</span> for <var>command</var> are both <var>new value</var>, append
-    <var>node</var> as the last [[child]] of <var>previous sibling</var>,
-    <span>preserving ranges</span>.
-
-    <li>If <var>next sibling</var> is a <span>simple modifiable element</span>
-    whose <span>specified value</span> and <span>effective value</span> for
-    <var>command</var> are both <var>new value</var>:
-
-    <ol>
-      <li>If <var>node</var> is not a [[child]] of <var>previous sibling</var>,
-      insert <var>node</var> as the first [[child]] of <var>next sibling</var>,
-      <span>preserving ranges</span>.
-
-      <li>Otherwise, while <var>next sibling</var> has [[children]], append the
-      first [[child]] of <var>next sibling</var> as the last [[child]] of
-      <var>previous sibling</var>, <span>preserving ranges</span>.  Then remove
-      <var>next sibling</var> from its [[parent]].
-    </ol>
+    <li>While <var>node list</var> is not empty and its first member <var>node
+    list</var> is not an <span>unwrappable node</span>, remove it from
+    <var>node list</var> and append it to <var>sublist</var>.
+
+    <li><span>Force the value</span> of <var>sublist</var>.
+  </ol>
+
+  <li>If <var>node list</var> is empty, abort this algorithm.
+
+  <!-- Now all the nodes are wrappable. -->
+
+  <li>If the <span>effective value</span> of <var>command</var> is <var>new
+  value</var> on every member of <var>node list</var>, abort this algorithm.
+
+  <!--
+  This bit tries to handle cases like
+
+    <i><b>foo</b></i>[bar]<i><b>baz</b></i>
+    -> <b><i>foo</i></b>bar<b><i>baz</i></b>
+
+  so that wrapping will result in
+
+    <b><i>foo</i>bar<i>baz</i></b>
+
+  instead of
+
+    <i><b>foo</b></i><b>bar</b><i><b>baz</b></i>.
+
+  Theoretically this algorithm could pointlessly reorganize the DOM in the
+  event of unreasonable style rules, but it's not a big enough deal for us to
+  care, since the resulting style will still be right.
+  -->
+  <li>Let <var>candidate</var> be the [[previoussibling]] of the first member
+  of <var>node list</var>.
+
+  <li>While <var>candidate</var> is a <span>modifiable element</span>, and
+  <var>candidate</var> has exactly one [[child]], and that [[child]] is also a
+  <span>modifiable element</span>, and <var>candidate</var> is not a
+  <span>simple modifiable element</span> or <var>candidate</var>'s
+  <span>specified value</span> for <var>command</var> is not <var>new
+  value</var>, set <var>candidate</var> to its [[child]].
+
+  <li>If <var>candidate</var> is a <span>simple modifiable element</span> whose
+  <span>specified value</span> and <span>effective value</span> for
+  <var>command</var> are both <var>new value</var>, and <var>candidate</var> is
+  not the [[previoussibling]] of the first member of <var>node list</var>:
+
+  <ol>
+    <li>While <var>candidate</var> has [[children]], insert the first [[child]]
+    of <var>candidate</var> into <var>candidate</var>'s [[parent]] immediately
+    before <var>candidate</var>, <span>preserving ranges</span>.
+
+    <li>Insert <var>candidate</var> into the [[parent]] of the first member of
+    <var>node list</var> before the [[previoussibling]] of the first member of
+    <var>node list</var>.
+    <!--
+    If candidate had no children, any boundary point inside it will get moved
+    to its parent here, which is okay.  We don't want to preserve ranges,
+    because that would move boundary points that originally were in candidate
+    but were moved to its parent by the last step to move to the parent of the
+    first member of node list.  We move to before the previous sibling so that
+    boundary points before and after the previous sibling wind up before or
+    after candidate.
+    -->
+
+    <li>Append the [[nextsibling]] of <var>candidate</var> as the last
+    [[child]] of <var>candidate</var>, <span>preserving ranges</span>.
+  </ol>
+
+  <li>Let <var>candidate</var> be the [[nextsibling]] of the last member of
+  <var>node list</var>.
+
+  <li>While <var>candidate</var> is a <span>modifiable element</span>, and
+  <var>candidate</var> has exactly one [[child]], and that [[child]] is also a
+  <span>modifiable element</span>, and <var>candidate</var> is not a
+  <span>simple modifiable element</span> or <var>candidate</var>'s
+  <span>specified value</span> for <var>command</var> is not <var>new
+  value</var>, set <var>candidate</var> to its [[child]].
+
+  <li>If <var>candidate</var> is a <span>simple modifiable element</span> whose
+  <span>specified value</span> and <span>effective value</span> for
+  <var>command</var> are both <var>new value</var>, and <var>candidate</var> is
+  not the [[nextsibling]] of the last member of <var>node list</var>:
+
+  <ol>
+    <li>While <var>candidate</var> has [[children]], insert the first [[child]]
+    of <var>candidate</var> into <var>candidate</var>'s [[parent]] immediately
+    before <var>candidate</var>, <span>preserving ranges</span>.
+
+    <li>Insert <var>candidate</var> into the [[parent]] of the last member of
+    <var>node list</var> after the last member of <var>node list</var>.
+    <!--
+    Thus candidate is between the same boundary points as node's next sibling,
+    not the same as the last member of node list.  When inserting, the new
+    thing always gets put in the same place as its next sibling, not its
+    previous sibling: a boundary point at the place it's inserted moves before
+    the new node, not after.
+    -->
+
+    <li>Append the [[nextsibling]] of <var>candidate</var> as the last
+    [[child]] of <var>candidate</var>, <span>preserving ranges</span>.
   </ol>
 
   <li>If the <span>effective value</span> of <var>command</var> is <var>new
   value</var> on <var>node</var>, abort this algorithm.
 
-  <li>If <var>node</var> is an <span>unwrappable node</span>:
-
-  <ol>
-    <li>Let <var>children</var> be all [[children]] of <var>node</var>,
-    omitting any that are [[element]]s whose <span>specified value</span> for
-    <var>command</var> is neither null nor equal to <var>new value</var>.
-
-    <li><span>Force the value</span> of each [[node]] in <var>children</var>,
-    with <var>command</var> and <var>new value</var> as in this invocation of
-    the algorithm.
-    <!-- This means that if it has no children, we do nothing.  IE9 inserts an
-    empty wrapper element in that case, but I'm not sure what the point is, and
-    no one else does, so I don't.  WebKit seems to ignore the node if its only
-    child consists solely of whitespace, but I don't see any grounds for that
-    and no one else does, so I don't. -->
-
-    <li>Abort this algorithm.
-  </ol>
-
-  <!-- At this point we have to make a new element as a wrapper.  This isn't
-  worth the effort for comments, so abort in that case. -->
-  <li>If <var>node</var> is a [[comment]], abort this algorithm.
-
-  <li>If the <span>effective value</span> of <var>command</var> is <var>new
-  value</var> on <var>node</var>, abort this algorithm.
-
-  <li>Let <var>new parent</var> be null.
-
-  <li>If the <span>CSS styling flag</span> is false:
-
-  <ol>
-    <li>If <var>command</var> is "bold" and <var>new value</var> is
-    "bold", let <var>new parent</var> be the result of calling <code
-    data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement("b")</code> on the
-    [[ownerdocument]] of <var>node</var>.
-
-    <li>If <var>command</var> is "italic" and <var>new value</var> is
-    "italic", let <var>new parent</var> be the result of calling <code
-    data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement("i")</code> on the
-    [[ownerdocument]] of <var>node</var>.
-
-    <li>If <var>command</var> is "strikethrough" and <var>new value</var> is
-    "line-through", let <var>new parent</var> be the result of calling <code
-    data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement("s")</code> on the
-    [[ownerdocument]] of <var>node</var>.
-
-    <p class=XXX>Actual UAs use strike, not s, but s is shorter and HTML5 makes
-    strike invalid.  I've gone with s for now, but maybe we want to change the
-    spec to require strike.
-
-    <li>If <var>command</var> is "underline" and <var>new value</var> is
-    "underline", let <var>new parent</var> be the result of calling <code
-    data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement("u")</code> on the
-    [[ownerdocument]] of <var>node</var>.
-
-    <li>If <var>command</var> is "foreColor", and <var>new value</var> is fully
-    opaque with red, green, and blue components in the range 0 to 255:
-
-    <ol>
-      <li>Let <var>new parent</var> be the result of calling <code
-      data-anolis-spec=domcore
-      title=dom-Document-createElement>createElement("font")</code> on the
-      [[ownerdocument]] of <var>node</var>.
-
-      <li>If <var>new value</var> is one of the colors listed in the SVG color
-      keywords section of CSS3 Color, set the [[fontcolor]] attribute of
-      <var>new parent</var> to <var>new value</var>.
-
-      <li>Otherwise, set the [[fontcolor]] attribute of <var>new parent</var>
-      to the result of applying the <span data-anolis-spec=html>rules for
-      serializing simple color values</span> to <var>new value</var>
-      (interpreted as a <span data-anolis-spec=html>simple color</span>).
-    </ol>
-
-    <li>If <var>command</var> is "fontName", let <var>new parent</var> be
-    the result of calling <code data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement("font")</code> on the
-    [[ownerdocument]] of <var>node</var>, then set the [[fontface]] attribute
-    of <var>new parent</var> to <var>new value</var>.
-  </ol>
+  <!-- At this point we have to make a new element as a wrapper. -->
 
   <li>If <var>command</var> is "createLink" or "unlink":
 
   <ol>
-    <li>Let <var>new parent</var> be the result of calling <code
-    data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement("a")</code> on the
-    [[ownerdocument]] of <var>node</var>.
-
-    <li>Set the [[href]] attribute of <var>new parent</var> to <var>new
-    value</var>.
-
     <!-- Nested a elements are bad, because they can't be serialized to
     text/html.  hrefs should already have been cleared in a previous step, but
     we might have <a name> or such lurking about. -->
-    <li>Let <var>ancestor</var> be <var>node</var>'s [[parent]].
+    <li>Let <var>ancestor</var> be the [[parent]] of the first member of
+    <var>node list</var>.
 
     <li>While <var>ancestor</var> is not null:
 
@@ -1413,53 +1368,27 @@
     </ol>
   </ol>
 
-  <!-- WebKit is the only engine that ever outputs anything but font tags for
-  fontSize.  For size=7, it uses font-size: -webkit-xxx-large.  We just output
-  a font tag no matter what. -->
-  <li>If <var>command</var> is "fontSize"; and <var>new value</var> is one of
-  "xx-small", "small", "medium", "large", "x-large", "xx-large", or
-  "xxx-large"; and either the <span>CSS styling flag</span> is false, or
-  <var>new value</var> is "xxx-large": let <var>new parent</var> be the result
-  of calling <code data-anolis-spec=domcore
-  title=dom-Document-createElement>createElement("font")</code> on the
-  [[ownerdocument]] of <var>node</var>, then set the [[fontsize]] attribute of
-  <var>new parent</var> to the number from the following table based on
-  <var>new value</var>:
-
-  <dl class=switch>
-    <dt>xx-small <dd>1
-    <dt>small <dd>2
-    <dt>normal <dd>3
-    <dt>large <dd>4
-    <dt>x-large <dd>5
-    <dt>xx-large <dd>6
-    <dt>xxx-large <dd>7
-  </dl>
-
-  <!-- We always use sup/sub elements, even in CSS mode, following Gecko and
-  contradicting WebKit.  This is because <span value="vertical-align:
-  sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
-  differently: it doesn't reduce font-size, which is ugly. -->
-  <li>If <var>command</var> is "subscript" or "superscript" and <var>new
-  value</var> is "sub", let <var>new parent</var> be the result of calling
-  <code data-anolis-spec=domcore
-  title=dom-Document-createElement>createElement("sub")</code> on the
-  [[ownerdocument]] of <var>node</var>.
-
-  <li>If <var>command</var> is "subscript" or "superscript" and <var>new
-  value</var> is "super", let <var>new parent</var> be the result of calling
-  <code data-anolis-spec=domcore
-  title=dom-Document-createElement>createElement("sup")</code> on the
-  [[ownerdocument]] of <var>node</var>.
-
-  <li>If <var>new parent</var> is null, let <var>new parent</var> be the result
-  of calling <code data-anolis-spec=domcore
-  title=dom-Document-createElement>createElement("span")</code> on the
-  [[ownerdocument]] of <var>node</var>.
-
-  <li>Insert <var>new parent</var> in <var>node</var>'s [[parent]] before
-  <var>node</var>.  <!-- This preserves boundary points correctly, as usual.
-  -->
+  <li><span>Wrap</span> <var>node list</var>, and let <var>new parent</var> be
+  the result.  <span>Sibling criteria</span> match any <span>simple modifiable
+  element</span> whose <span>specified value</span> and <span>effective
+  value</span> are both <var>new value</var>.  <span>New parent
+  instructions</span> are as follows:
+
+  <ol>
+    <li>Let <var>new parent</var> be null.
+
+    <li>If there is a <span>wrapper element</span> defined for
+    <var>command</var>, let <var>new parent</var> be the result of running
+    those instructions, with <var>new value</var> as in this algorithm, and
+    <var>document</var> equal to the [[ownerdocument]] of the first member of
+    <var>node list</var>.
+
+    <li>If <var>new parent</var> is null, set <var>new parent</var> to the
+    result of running [[createelement|"span"]] on the [[ownerdocument]] of the
+    first member of <var>node list</var>.
+
+    <li>Return <var>new parent</var>.
+  </ol>
 
   <li>If the <span>effective value</span> of <var>command</var> for <var>new
   parent</var> is not <var>new value</var>, and the <span>relevant CSS
@@ -1477,18 +1406,15 @@
   parent</var> is not "underline", set the "text-decoration" property of
   <var>new parent</var> to "underline".
 
-  <li>Append <var>node</var> to <var>new parent</var> as its last [[child]],
-  <span>preserving ranges</span>.
-
-  <li>If <var>node</var> is an [[element]] and the <span>effective value</span>
-  of <var>command</var> for <var>node</var> is not <var>new value</var>:
+  <li>If the <span>effective value</span> of every [[child]] of <var>new
+  parent</var> is something other than <var>new value</var>, remove <var>new
+  parent</var>, <span>preserving its descendants</span>.
+
+  <li>For each <var>node</var> in <var>node list</var>, if <var>node</var> is
+  an [[element]] and the <span>effective value</span> of <var>command</var> for
+  <var>node</var> is not <var>new value</var>:
 
   <ol>
-    <li>Insert <var>node</var> into the [[parent]] of <var>new parent</var>
-    before <var>new parent</var>, <span>preserving ranges</span>.
-
-    <li>Remove <var>new parent</var> from its [[parent]].
-
     <li>If <var>new parent</var> is a [[span]], and either a)
     <var>command</var> is "underline" or "strikethrough", or b)
     <var>command</var> is "fontSize" and <var>new value</var> is not
@@ -1757,6 +1683,10 @@
 
 <p><span>Relevant CSS property</span>: "font-weight"
 
+<p><span>Wrapper element</span>: If the <span>CSS styling flag</span> is true
+or <var>new value</var> is not "bold", return false.  Otherwise, call
+[[createelement|"b"]] on the [[contextobject]] and return the result.
+
 
 <h3><dfn>The <code title>createLink</code> command</dfn></h3>
 
@@ -1815,6 +1745,11 @@
 <p><span>Value</span>: Always the empty string.
 <!-- I'd have expected the value to be the URL, but guess not. -->
 
+<p><span>Wrapper element</span>: Call [[createelement|"a"]] on the
+[[contextobject]], and let <var>new parent</var> be the result.  Then call
+[[setattribute|"href", <var>new value</var>]] on <var>new parent</var>, and
+return <var>new parent</var>.
+
 
 <h3><dfn>The <code title>fontName</code> command</dfn></h3>
 
@@ -1864,6 +1799,12 @@
 
 <p><span>Relevant CSS property</span>: "font-family"
 
+<p><span>Wrapper element</span>: If the <span>CSS styling flag</span> is true,
+return false.  Otherwise, call [[createelement|"font"]] on the
+[[contextobject]], and let <var>new parent</var> be the result; then call
+[[setattribute|"face", <var>new value</var>]] on <var>new parent</var>; then
+return <var>new parent</var>.
+
 
 <h3><dfn>The <code title>fontSize</code> command</dfn></h3>
 
@@ -1971,6 +1912,40 @@
 
 <p><span>Relevant CSS property</span>: "font-size"
 
+<p><span>Wrapper element</span>:
+<!-- WebKit is the only engine that ever outputs anything but font tags for
+fontSize.  For size=7, it uses font-size: -webkit-xxx-large.  We just output a
+font tag no matter what. -->
+
+<ol>
+  <li>If <var>new value</var> is not one of "xx-small", "small", "medium", "large",
+  "x-large", "xx-large", or "xxx-large", return false.
+
+  <li>If the <span>CSS styling flag</span> is true and <var>new value</var> is
+  not "xxx-large", return false.
+
+  <li>Call [[createelement|"font"]] on the [[contextobject]], and let <var>new
+  parent</var> be the result.
+
+  <li>Set <var>numeric value</var> from the following table based on <var>new
+  value</var>:
+
+  <dl class=switch>
+  <dt>xx-small <dd>1
+  <dt>small <dd>2
+  <dt>medium <dd>3
+  <dt>large <dd>4
+  <dt>x-large <dd>5
+  <dt>xx-large <dd>6
+  <dt>xxx-large <dd>7
+  </dl>
+
+  <li>Call [[setattribute|"size", <var>numeric value</var>]] on <var>new
+  parent</var>.
+
+  <li>Return <var>new parent</var>.
+</ol>
+
 
 <h3><dfn>The <code title>foreColor</code> command</dfn></h3>
 
@@ -2056,6 +2031,26 @@
 
 <p><span>Relevant CSS property</span>: "color"
 
+<p><span>Wrapper element</span>:
+
+<ol>
+  <li>If the <span>CSS styling flag</span> is false; or <var>new value</var> is
+  not fully opaque; or <var>new value</var> has a red, green, or blue component
+  less than 0 or greater than 255; return false;
+
+  <li>Let <var>new parent</var> be the result of calling
+  [[createelement|"font"]] on the [[contextobject]].
+
+  <li>If <var>new value</var> is one of the keywords listed in the SVG color
+  keywords section of CSS3 color, set the [[fontcolor]] attribute of <var>new
+  parent</var> to <var>new value</var>.
+
+  <li>Otherwise, set the [[fontcolor]] attribute of <var>new parent</var> to
+  the result of applying the <span data-anolis-spec=html>rules for serializing
+  simple color values</span> to <var>new value</var> (interpreted as a <span
+  data-anolis-spec=html>simple color</span>).
+</ol>
+
 
 <h3><dfn>The <code title>hiliteColor</code> command</dfn></h3>
 <!-- IE 9 RC doesn't support this.  It uses backColor instead, but Gecko and
@@ -2196,6 +2191,10 @@
 
 <p><span>Relevant CSS property</span>: "font-style"
 
+<p><span>Wrapper element</span>: If the <span>CSS styling flag</span> is true
+or <var>new value</var> is not "italic", return false.  Otherwise, call
+[[createelement|"i"]] on the [[contextobject]] and return the result.
+
 
 <h3><dfn>The <code title>removeFormat</code> command</dfn></h3>
 <!--
@@ -2333,6 +2332,15 @@
 
 <p><span>Value</span>: Always the empty string.
 
+<p><span>Wrapper element</span>: If the <span>CSS styling flag</span> is true
+or <var>new value</var> is not "line-through", return false.  Otherwise, call
+[[createelement|"s"]] on the [[contextobject]] and return the result.
+
+<p class=XXX>Actual UAs use strike, not s, but s is shorter and HTML5 makes
+strike invalid.  I've gone with s for now, but maybe we want to change the spec
+to require strike.
+
+
 
 <h3><dfn>The <code title>subscript</code> command</dfn></h3>
 
@@ -2341,9 +2349,9 @@
 <ol>
   <li><span>Decompose</span> the <span>active range</span>, and let <var>node
   list</var> be the result.
-  
+
   <li>Let <var>state</var> be the <span>state</span>.
-  
+
   <li><span>Set the value</span> of <var>node list</var> to "baseline".
 
   <li>If <var>state</var> is false, <span>decompose</span> the <span>active
@@ -2356,6 +2364,15 @@
 
 <p><span>Relevant CSS property</span>: "vertical-align"
 
+<!-- We always use sup/sub elements, even in CSS mode, following Gecko and
+contradicting WebKit.  This is because <span value="vertical-align:
+sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
+differently: it doesn't reduce font-size, which is ugly. -->
+<p><span>Wrapper element</span>: If <var>new value</var> is "sub", call
+[[createelement|"sub"]] on the [[contextobject]] and return the result.
+Otherwise, if <var>new value</var> is "super", call [[createelement|"sup"]] on
+the [[contextobject]] and return the result.  Otherwise, return false.
+
 
 <h3><dfn>The <code title>superscript</code> command</dfn></h3>
 
@@ -2364,9 +2381,9 @@
 <ol>
   <li><span>Decompose</span> the <span>active range</span>, and let <var>node
   list</var> be the result.
-  
+
   <li>Let <var>state</var> be the <span>state</span>.
-  
+
   <li><span>Set the value</span> of <var>node list</var> to "baseline".
 
   <li>If <var>state</var> is false, <span>decompose</span> the <span>active
@@ -2379,6 +2396,15 @@
 
 <p><span>Relevant CSS property</span>: "vertical-align"
 
+<!-- We always use sup/sub elements, even in CSS mode, following Gecko and
+contradicting WebKit.  This is because <span value="vertical-align:
+sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
+differently: it doesn't reduce font-size, which is ugly. -->
+<p><span>Wrapper element</span>: If <var>new value</var> is "sub", call
+[[createelement|"sub"]] on the [[contextobject]] and return the result.
+Otherwise, if <var>new value</var> is "super", call [[createelement|"sup"]] on
+the [[contextobject]] and return the result.  Otherwise, return false.
+
 
 <h3><dfn>The <code title>underline</code> command</dfn></h3>
 
@@ -2443,6 +2469,10 @@
 
 <p><span>Value</span>: Always the empty string.
 
+<p><span>Wrapper element</span>: If the <span>CSS styling flag</span> is true
+or <var>new value</var> is not "underline", return false.  Otherwise, call
+[[createelement|"u"]] on the [[contextobject]] and return the result.
+
 
 <h3><dfn>The <code title>unlink</code> command</dfn></h3>
 
@@ -2468,6 +2498,11 @@
 
 <p><span>Value</span>: Always the empty string.
 
+<p><span>Wrapper element</span>: Call [[createelement|"a"]] on the
+[[contextobject]], and let <var>new parent</var> be the result.  Then call
+[[setattribute|"href", <var>new value</var>]] on <var>new parent</var>, and
+return <var>new parent</var>.
+
 
 <h2>Block formatting commands</h2>