--- a/editcommands.html Thu May 26 10:51:05 2011 -0600
+++ b/editcommands.html Thu May 26 11:37:49 2011 -0600
@@ -602,6 +602,12 @@
<li>For each <var title="">node</var> in <var title="">node list</var>, insert <var title="">node</var>
into the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of <var title="">original parent</var> immediately before
<var title="">original parent</var>, <a href=#preserving-ranges>preserving ranges</a>.
+ <!-- Notice that a boundary point that was immediately before the element
+ will now be immediately before its children, just because of the regular
+ range mutation rules, without needing to worry about preserving ranges.
+ Likewise for boundary points immediately after the element, if we wind up
+ removing the element in the final step. Preserving ranges is only necessary
+ for the sake of boundary points in the element or its descendants. -->
<li>If the last member of <var title="">node list</var> is an <a href=#inline-node>inline node</a>
other than a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, and the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">original parent</var> is
@@ -637,6 +643,11 @@
<li>Otherwise, run the <a href=#new-parent-instructions>new parent instructions</a>, and let <var title="">new
parent</var> be the result.
+ <li>If <var title="">new parent</var> is null, abort these steps and return null.
+ <!-- This can only happen if the new parent instructions are run and they
+ return null. This can be used to only merge with adjacent siblings, in case
+ you don't want to create a new parent if that fails. -->
+
<li>If <var title="">new parent</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, insert <var title="">new
parent</var> into the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of the first member of <var title="">node list</var>
immediately before the first member of <var title="">node list</var>.
@@ -648,10 +659,10 @@
list</var> in <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#tree-order>tree order</a>:
<ol>
- <li>If the last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new parent</var> and the first member of
- <var title="">node list</var> are both <a href=#inline-node title="inline node">inline
- nodes</a>, and the last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new parent</var> is not a
- <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
+ <li>If <var title="">new parent</var> is not an <a href=#inline-node>inline node</a>, but the
+ last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new parent</var> and the first member of <var title="">node
+ list</var> are both <a href=#inline-node title="inline node">inline nodes</a>, and the
+ last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new parent</var> is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
<code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">new parent</var> and append the result as the
last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new parent</var>.
@@ -663,10 +674,10 @@
<li>Otherwise:
<ol>
- <li>If the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new parent</var> and the last member of
- <var title="">node list</var> are both <a href=#inline-node title="inline node">inline
- nodes</a>, and the last member of <var title="">node list</var> is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>,
- call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
+ <li>If <var title="">new parent</var> is not an <a href=#inline-node>inline node</a>, but 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="">new parent</var> and the last member of <var title="">node
+ list</var> are both <a href=#inline-node title="inline node">inline nodes</a>, and the
+ last member of <var title="">node list</var> is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
<code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">new parent</var> and insert the result 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="">new parent</var>.
@@ -686,7 +697,8 @@
to merge them in this case. -->
<ol>
- <li>If <var title="">new parent</var>'s last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> and <var title="">new parent</var>'s
+ <li>If <var title="">new parent</var> is not an <a href=#inline-node>inline node</a>, but
+ <var title="">new parent</var>'s last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> and <var title="">new parent</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>'s first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> are both <a href=#inline-node title="inline node">inline
nodes</a>, and <var title="">new parent</var>'s last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>,
call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
@@ -1223,6 +1235,58 @@
<li>Return null.
</ol>
+<p>To <dfn id=reorder-modifiable-descendants>reorder modifiable descendants</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>,
+given a <a href=#command>command</a> <var title="">command</var> and a value <var title="">new
+value</var>:
+
+<ol>
+ <li>Let <var title="">candidate</var> equal <var title="">node</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 <var title="">node</var>, or is not a <a href=#simple-modifiable-element>simple
+ modifiable element</a>, or its <a href=#specified-value>specified value</a> and
+ <a href=#effective-value>effective value</a> for <var title="">command</var> are not both <var title="">new
+ value</var>, abort these steps.
+
+ <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> immediately
+ after <var title="">node</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 node's parent.
+
+ We move to after node so that boundary points before and after node wind up
+ consistently inside candidate when we move preserving ranges. If we had
+ {<node>foo<candidate></candidate></node>}
+ it thus becomes
+ {<node>foo</node>}<candidate></candidate>
+ by the range mutation rules, and then when we move preserving ranges, it
+ becomes
+ <candidate>{<node>foo</node>}</candidate>
+ which is reasonable.
+
+ If we had inserted candidate before node, instead it would go
+ {<candidate></candidate><node>foo</node>}
+ {<candidate><node>foo</node>}</candidate>
+ because of the interaction of regular range mutation rules with
+ preserving-ranges rules.
+ -->
+
+ <li>Append the <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="">candidate</var>,
+ <a href=#preserving-ranges>preserving ranges</a>.
+</ol>
+
<h3 id=decomposing-a-range-into-nodes><span class=secno>6.3 </span>Decomposing a range into nodes</h3>
<p>To <dfn id=decompose>decompose</dfn> a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> <var title="">range</var>:
@@ -1292,15 +1356,7 @@
<ol>
<li>Let <var title="">children</var> be the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a> of <var title="">element</var>.
- <li>While <var title="">element</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 its first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>
- into 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> immediately before it, <a href=#preserving-ranges>preserving ranges</a>.
-
- <li>Remove <var title="">element</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>.
- <!-- Notice that a boundary point that was immediately before or after the
- element will now be immediately before or after its children, just because
- of the regular range mutation rules, without needing to worry about
- preserving ranges. Preserving ranges is only necessary for the sake of
- boundary points in the element or its descendants. -->
+ <li>Remove <var title="">element</var>, <a href=#preserving-its-descendants>preserving its descendants</a>.
<li>Return <var title="">children</var>.
</ol>
@@ -1508,91 +1564,19 @@
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>:
-
- <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>.
- </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
+ <li><a href=#reorder-modifiable-descendants>Reorder modifiable descendants</a> of <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><a href=#reorder-modifiable-descendants>Reorder modifiable descendants</a> of <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><a href=#wrap>Wrap</a> the one-<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> list consisting of <var title="">node</var>,
+ with <a href=#sibling-criteria>sibling criteria</a> matching 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>
+ value</a> for <var title="">command</var> are both <var title="">new value</var>, and with
+ <a href=#new-parent-instructions>new parent instructions</a> returning null.
+ <!-- The new parent instructions are too complicated to reasonably feed
+ into the wrap algorithm. -->
</ol>
<li>If the <a href=#effective-value>effective value</a> of <var title="">command</var> is <var title="">new
--- a/implementation.js Thu May 26 10:51:05 2011 -0600
+++ b/implementation.js Thu May 26 11:37:49 2011 -0600
@@ -574,6 +574,11 @@
newParent = newParentInstructions();
}
+ // "If new parent is null, abort these steps and return null."
+ if (!newParent) {
+ return null;
+ }
+
// "If new parent's parent is null, insert new parent into the parent of
// the first member of node list immediately before the first member of
// node list."
@@ -586,11 +591,13 @@
// "If new parent is before the first member of node list in tree order:"
if (isBefore(newParent, nodeList[0])) {
- // "If the last child of new parent and the first member of node list
- // are both inline nodes, and the last child of new parent is not a br,
- // call createElement("br") on the ownerDocument of new parent and
- // append the result as the last child of new parent."
- if (isInlineNode(newParent.lastChild)
+ // "If new parent is not an inline node, but the last child of new
+ // parent and the first member of node list are both inline nodes, and
+ // the last child of new parent is not a br, call createElement("br")
+ // on the ownerDocument of new parent and append the result as the last
+ // child of new parent."
+ if (!isInlineNode(newParent)
+ && isInlineNode(newParent.lastChild)
&& isInlineNode(nodeList[0])
&& !isHtmlElement(newParent.lastChild, "BR")) {
newParent.appendChild(newParent.ownerDocument.createElement("br"));
@@ -604,11 +611,13 @@
// "Otherwise:"
} else {
- // "If the first child of new parent and the last member of node list
- // are both inline nodes, and the last member of node list is not a br,
- // call createElement("br") on the ownerDocument of new parent and
- // insert the result as the first child of new parent."
- if (isInlineNode(newParent.firstChild)
+ // "If new parent is not an inline node, but the first child of new
+ // parent and the last member of node list are both inline nodes, and
+ // the last member of node list is not a br, call createElement("br")
+ // on the ownerDocument of new parent and insert the result as the
+ // first child of new parent."
+ if (!isInlineNode(newParent)
+ && isInlineNode(newParent.firstChild)
&& isInlineNode(nodeList[nodeList.length - 1])
&& !isHtmlElement(nodeList[nodeList.length - 1], "BR")) {
newParent.insertBefore(newParent.ownerDocument.createElement("br"), newParent.firstChild);
@@ -631,11 +640,13 @@
// criteria:"
if (isEditable(newParent.nextSibling)
&& siblingCriteria(newParent.nextSibling)) {
- // "If new parent's last child and new parent's nextSibling's first
- // child are both inline nodes, and new parent's last child is not a
- // br, call createElement("br") on the ownerDocument of new parent and
- // append the result as the last child of new parent."
- if (isInlineNode(newParent.lastChild)
+ // "If new parent is not an inline node, but new parent's last child
+ // and new parent's nextSibling's first child are both inline nodes,
+ // and new parent's last child is not a br, call createElement("br") on
+ // the ownerDocument of new parent and append the result as the last
+ // child of new parent."
+ if (!isInlineNode(newParent)
+ && isInlineNode(newParent.lastChild)
&& isInlineNode(newParent.nextSibling.firstChild)
&& !isHtmlElement(newParent.lastChild, "BR")) {
newParent.appendChild(newParent.ownerDocument.createElement("br"));
@@ -1473,6 +1484,44 @@
return null;
}
+function reorderModifiableDescendants(node, command, newValue) {
+ // "Let candidate equal node."
+ var candidate = node;
+
+ // "While candidate is a modifiable element, and candidate has exactly one
+ // child, and that child is also a modifiable element, and candidate is not
+ // a simple modifiable element or candidate's specified value for command
+ // is not new value, set candidate to its child."
+ while (isModifiableElement(candidate)
+ && candidate.childNodes.length == 1
+ && (!isSimpleModifiableElement(candidate)
+ || !valuesEqual(command, getSpecifiedValue(candidate, command), newValue))) {
+ candidate = candidate.firstChild;
+ }
+
+ // "If candidate is node, or is not a simple modifiable element, or its
+ // specified value and effective value for command are not both new value,
+ // abort these steps."
+ if (candidate == node
+ || !isSimpleModifiableElement(candidate)
+ || !valuesEqual(command, getSpecifiedValue(candidate, command), newValue)
+ || !valuesEqual(command, getEffectiveValue(candidate, command), newValue)) {
+ return;
+ }
+
+ // "While candidate has children, insert the first child of candidate into
+ // candidate's parent immediately before candidate, preserving ranges."
+ while (candidate.hasChildNodes()) {
+ movePreservingRanges(candidate.firstChild, candidate.parentNode, getNodeIndex(candidate));
+ }
+
+ // "Insert candidate into node's parent immediately after node."
+ node.parentNode.insertBefore(candidate, node.nextSibling);
+
+ // "Append the node as the last child of candidate, preserving ranges."
+ movePreservingRanges(node, candidate, -1);
+}
+
// "A modifiable element is a b, em, i, s, span, strong, sub, sup, or u element
// with no attributes except possibly style; or a font element with no
// attributes except possibly style, color, face, and/or size; or an a element
@@ -2192,114 +2241,24 @@
|| node.nodeType == Node.COMMENT_NODE
|| node.nodeType == Node.PROCESSING_INSTRUCTION_NODE)
&& !isUnwrappableNode(node)) {
- // "Let candidate be node's previousSibling."
- var candidate = node.previousSibling;
-
- // "While candidate is a modifiable element, and candidate has exactly one
- // child, and that child is also a modifiable element, and candidate is
- // not a simple modifiable element or candidate's specified value for
- // command is not new value, set candidate to its child."
- while (isModifiableElement(candidate)
- && candidate.childNodes.length == 1
- && isModifiableElement(candidate.firstChild)
- && (!isSimpleModifiableElement(candidate)
- || !valuesEqual(command, getSpecifiedValue(candidate, command), newValue))) {
- candidate = candidate.firstChild;
- }
-
- // "If candidate is a simple modifiable element whose specified value and
- // effective value for command are both new value, and candidate is
- // not the previousSibling of node:"
- if (isSimpleModifiableElement(candidate)
- && valuesEqual(command, getSpecifiedValue(candidate, command), newValue)
- && valuesEqual(command, getEffectiveValue(candidate, command), newValue)
- && candidate != node.previousSibling) {
- // "While candidate has children, insert the first child of
- // candidate into candidate's parent immediately before candidate,
- // preserving ranges."
- while (candidate.childNodes.length > 0) {
- movePreservingRanges(candidate.firstChild, candidate.parentNode, getNodeIndex(candidate));
- }
-
- // "Insert candidate into node's parent before node's
- // previousSibling."
- node.parentNode.insertBefore(candidate, node.previousSibling);
-
- // "Append the nextSibling of candidate as the last child of
- // candidate, preserving ranges."
- movePreservingRanges(candidate.nextSibling, candidate, candidate.childNodes.length);
- }
-
- // "Let candidate be node's nextSibling."
- var candidate = node.nextSibling;
-
- // "While candidate is a modifiable element, and candidate has exactly one
- // child, and that child is also a modifiable element, and candidate is
- // not a simple modifiable element or candidate's specified value for
- // command is not new value, set candidate to its child."
- while (isModifiableElement(candidate)
- && candidate.childNodes.length == 1
- && isModifiableElement(candidate.firstChild)
- && (!isSimpleModifiableElement(candidate)
- || !valuesEqual(command, getSpecifiedValue(candidate, command), newValue))) {
- candidate = candidate.firstChild;
- }
-
- // "If candidate is a simple modifiable element whose specified value and
- // effective value for command are both new value, and candidate is
- // not the nextSibling of node:"
- if (isSimpleModifiableElement(candidate)
- && valuesEqual(command, getSpecifiedValue(candidate, command), newValue)
- && valuesEqual(command, getEffectiveValue(candidate, command), newValue)
- && candidate != node.nextSibling) {
- // "While candidate has children, insert the first child of
- // candidate into candidate's parent immediately before candidate,
- // preserving ranges."
- while (candidate.childNodes.length > 0) {
- movePreservingRanges(candidate.firstChild, candidate.parentNode, getNodeIndex(candidate));
- }
-
- // "Insert candidate into node's parent after node."
- node.parentNode.insertBefore(candidate, node.nextSibling);
-
- // "Append the nextSibling of candidate as the last child of
- // candidate, preserving ranges."
- movePreservingRanges(candidate.nextSibling, candidate, candidate.childNodes.length);
- }
-
- // "Let previous sibling and next sibling be node's previousSibling and
- // nextSibling."
- var previousSibling = node.previousSibling;
- var nextSibling = node.nextSibling;
-
- // "If previous sibling is a simple modifiable element whose specified
- // value and effective value for command are both new value, append
- // node as the last child of previous sibling, preserving ranges."
- if (isSimpleModifiableElement(previousSibling)
- && valuesEqual(command, getSpecifiedValue(previousSibling, command), newValue)
- && valuesEqual(command, getEffectiveValue(previousSibling, command), newValue)) {
- movePreservingRanges(node, previousSibling, previousSibling.childNodes.length);
- }
-
- // "If next sibling is a simple modifiable element whose specified value
- // and effective value for command are both new value:"
- if (isSimpleModifiableElement(nextSibling)
- && valuesEqual(command, getSpecifiedValue(nextSibling, command), newValue)
- && valuesEqual(command, getEffectiveValue(nextSibling, command), newValue)) {
- // "If node is not a child of previous sibling, insert node as the
- // first child of next sibling, preserving ranges."
- if (node.parentNode != previousSibling) {
- movePreservingRanges(node, nextSibling, 0);
- // "Otherwise, while next sibling has children, append the first
- // child of next sibling as the last child of previous sibling,
- // preserving ranges. Then remove next sibling from its parent."
- } else {
- while (nextSibling.childNodes.length) {
- movePreservingRanges(nextSibling.firstChild, previousSibling, previousSibling.childNodes.length);
- }
- nextSibling.parentNode.removeChild(nextSibling);
- }
- }
+ // "Reorder modifiable descendants of node's previousSibling."
+ reorderModifiableDescendants(node.previousSibling, command, newValue);
+
+ // "Reorder modifiable descendants of node's nextSibling."
+ reorderModifiableDescendants(node.nextSibling, command, newValue);
+
+ // "Wrap the one-node list consisting of node, with sibling criteria
+ // matching a simple modifiable element whose specified value and
+ // effective value for command are both new value, and with new parent
+ // instructions returning null."
+ wrap([node],
+ function(node) {
+ return isSimpleModifiableElement(node)
+ && valuesEqual(command, getSpecifiedValue(node, command), newValue)
+ && valuesEqual(command, getEffectiveValue(node, command), newValue);
+ },
+ function() { return null }
+ );
}
// "If the effective value of command is new value on node, abort this
--- a/source.html Thu May 26 10:51:05 2011 -0600
+++ b/source.html Thu May 26 11:37:49 2011 -0600
@@ -561,6 +561,12 @@
<li>For each <var>node</var> in <var>node list</var>, insert <var>node</var>
into the [[parent]] of <var>original parent</var> immediately before
<var>original parent</var>, <span>preserving ranges</span>.
+ <!-- Notice that a boundary point that was immediately before the element
+ will now be immediately before its children, just because of the regular
+ range mutation rules, without needing to worry about preserving ranges.
+ Likewise for boundary points immediately after the element, if we wind up
+ removing the element in the final step. Preserving ranges is only necessary
+ for the sake of boundary points in the element or its descendants. -->
<li>If the last member of <var>node list</var> is an <span>inline node</span>
other than a [[br]], and the first [[child]] of <var>original parent</var> is
@@ -596,6 +602,11 @@
<li>Otherwise, run the <span>new parent instructions</span>, and let <var>new
parent</var> be the result.
+ <li>If <var>new parent</var> is null, abort these steps and return null.
+ <!-- This can only happen if the new parent instructions are run and they
+ return null. This can be used to only merge with adjacent siblings, in case
+ you don't want to create a new parent if that fails. -->
+
<li>If <var>new parent</var>'s [[parent]] is null, insert <var>new
parent</var> into the [[parent]] of the first member of <var>node list</var>
immediately before the first member of <var>node list</var>.
@@ -607,10 +618,11 @@
list</var> in [[treeorder]]:
<ol>
- <li>If the last [[child]] of <var>new parent</var> and the first member of
- <var>node list</var> are both <span title="inline node">inline
- nodes</span>, and the last [[child]] of <var>new parent</var> is not a
- [[br]], call <code data-anolis-spec=domcore
+ <li>If <var>new parent</var> is not an <span>inline node</span>, but the
+ last [[child]] of <var>new parent</var> and the first member of <var>node
+ list</var> are both <span title="inline node">inline nodes</span>, and the
+ last [[child]] of <var>new parent</var> is not a [[br]], call <code
+ data-anolis-spec=domcore
title=dom-Document-createElement>createElement("br")</code> on the
[[ownerdocument]] of <var>new parent</var> and append the result as the
last [[child]] of <var>new parent</var>.
@@ -623,10 +635,11 @@
<li>Otherwise:
<ol>
- <li>If the first [[child]] of <var>new parent</var> and the last member of
- <var>node list</var> are both <span title="inline node">inline
- nodes</span>, and the last member of <var>node list</var> is not a [[br]],
- call <code data-anolis-spec=domcore
+ <li>If <var>new parent</var> is not an <span>inline node</span>, but the
+ first [[child]] of <var>new parent</var> and the last member of <var>node
+ list</var> are both <span title="inline node">inline nodes</span>, and the
+ last member of <var>node list</var> is not a [[br]], call <code
+ data-anolis-spec=domcore
title=dom-Document-createElement>createElement("br")</code> on the
[[ownerdocument]] of <var>new parent</var> and insert the result as the
first [[child]] of <var>new parent</var>.
@@ -647,7 +660,8 @@
to merge them in this case. -->
<ol>
- <li>If <var>new parent</var>'s last [[child]] and <var>new parent</var>'s
+ <li>If <var>new parent</var> is not an <span>inline node</span>, but
+ <var>new parent</var>'s last [[child]] and <var>new parent</var>'s
[[nextsibling]]'s first [[child]] are both <span title="inline node">inline
nodes</span>, and <var>new parent</var>'s last [[child]] is not a [[br]],
call <code data-anolis-spec=domcore
@@ -1192,6 +1206,58 @@
<li>Return null.
</ol>
+<p>To <dfn>reorder modifiable descendants</dfn> of a [[node]] <var>node</var>,
+given a <span>command</span> <var>command</var> and a value <var>new
+value</var>:
+
+<ol>
+ <li>Let <var>candidate</var> equal <var>node</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 <var>node</var>, or is not a <span>simple
+ modifiable element</span>, or its <span>specified value</span> and
+ <span>effective value</span> for <var>command</var> are not both <var>new
+ value</var>, abort these steps.
+
+ <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]] immediately
+ after <var>node</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 node's parent.
+
+ We move to after node so that boundary points before and after node wind up
+ consistently inside candidate when we move preserving ranges. If we had
+ {<node>foo<candidate></candidate></node>}
+ it thus becomes
+ {<node>foo</node>}<candidate></candidate>
+ by the range mutation rules, and then when we move preserving ranges, it
+ becomes
+ <candidate>{<node>foo</node>}</candidate>
+ which is reasonable.
+
+ If we had inserted candidate before node, instead it would go
+ {<candidate></candidate><node>foo</node>}
+ {<candidate><node>foo</node>}</candidate>
+ because of the interaction of regular range mutation rules with
+ preserving-ranges rules.
+ -->
+
+ <li>Append the <var>node</var> as the last [[child]] of <var>candidate</var>,
+ <span>preserving ranges</span>.
+</ol>
+
<h3>Decomposing a range into nodes</h3>
<p>To <dfn>decompose</dfn> a [[range]] <var>range</var>:
@@ -1265,15 +1331,7 @@
<ol>
<li>Let <var>children</var> be the [[children]] of <var>element</var>.
- <li>While <var>element</var> has [[children]], insert its first [[child]]
- into its [[parent]] immediately before it, <span>preserving ranges</span>.
-
- <li>Remove <var>element</var> from its [[parent]].
- <!-- Notice that a boundary point that was immediately before or after the
- element will now be immediately before or after its children, just because
- of the regular range mutation rules, without needing to worry about
- preserving ranges. Preserving ranges is only necessary for the sake of
- boundary points in the element or its descendants. -->
+ <li>Remove <var>element</var>, <span>preserving its descendants</span>.
<li>Return <var>children</var>.
</ol>
@@ -1482,91 +1540,19 @@
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>:
-
- <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>.
- </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
+ <li><span>Reorder modifiable descendants</span> of <var>node</var>'s
+ [[previoussibling]].
+
+ <li><span>Reorder modifiable descendants</span> of <var>node</var>'s
+ [[nextsibling]].
+
+ <li><span>Wrap</span> the one-[[node]] list consisting of <var>node</var>,
+ with <span>sibling criteria</span> matching 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>
+ value</span> for <var>command</var> are both <var>new value</var>, and with
+ <span>new parent instructions</span> returning null.
+ <!-- The new parent instructions are too complicated to reasonably feed
+ into the wrap algorithm. -->
</ol>
<li>If the <span>effective value</span> of <var>command</var> is <var>new