Make insertImage work more correctly
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Thu, 26 May 2011 10:38:25 -0600
changeset 177 19c0d176432e
parent 176 7776444f1926
child 178 8400d57ca296
Make insertImage work more correctly

Deletion from our perspective is not just deleteRange(), it turns out,
because we need to merge blocks: <p>fo[o</p><p>b]ar</p> becomes
<p>foar</p>, not <p>fo</p><p>ar</p>. This algorithm is likely to get
reused.
autoimplementation.html
editcommands.html
implementation.js
preprocess
source.html
--- a/autoimplementation.html	Wed May 25 13:54:18 2011 -0600
+++ b/autoimplementation.html	Thu May 26 10:38:25 2011 -0600
@@ -873,8 +873,31 @@
 		'<span>foo[</span><span>]bar</span>',
 		["", 'foo[bar]baz'],
 		'foo[bar]baz',
+
+		'foo<b>[bar]</b>baz',
 		'foo<b>{bar}</b>baz',
+		'foo{<b>bar</b>}baz',
+		'foo<span>[bar]</span>baz',
+		'foo<span>{bar}</span>baz',
+		'foo{<span>bar</span>}baz',
+		'<b>foo[bar</b><i>baz]quz</i>',
+		'<p>foo</p><p>[bar]</p><p>baz</p>',
+		'<p>foo</p><p>{bar}</p><p>baz</p>',
+		'<p>foo</p>{<p>bar</p>}<p>baz</p>',
+
 		'<p>foo[bar<p>baz]quz',
+		'<p>foo[bar<div>baz]quz</div>',
+		'<p>foo[bar<h1>baz]quz</h1>',
+		'<div>foo[bar</div><p>baz]quz',
+		'<blockquote>foo[bar</blockquote><pre>baz]quz</pre>',
+
+		'<p><b>foo[bar</b><p>baz]quz',
+		'<div><p>foo[bar</div><p>baz]quz',
+		'<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote',
+		'<p>foo[bar<p style=color:red>baz]quz',
+		'<p>foo[bar<p><b>baz]quz</b>',
+
+		'<div><p>foo<p>[bar<p>baz]</div>',
 	],
 	insertorderedlist: [
 		'foo[]bar',
--- a/editcommands.html	Wed May 25 13:54:18 2011 -0600
+++ b/editcommands.html	Thu May 26 10:38:25 2011 -0600
@@ -35,7 +35,7 @@
 <body class=draft>
 <div class=head id=head>
 <h1>HTML Editing Commands</h1>
-<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-25-may-2011>Work in Progress &mdash; Last Update 25 May 2011</h2>
+<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-26-may-2011>Work in Progress &mdash; Last Update 26 May 2011</h2>
 <dl>
  <dt>Editor
  <dd>Aryeh Gregor &lt;ayg+spec@aryeh.name&gt;
@@ -705,6 +705,141 @@
   <li>Return <var title="">new parent</var>.
 </ol>
 
+<p>To <dfn id=delete-the-selection>delete the selection</dfn>:
+
+<ol>
+  <li>Let <var title="">range</var> be the <a href=#active-range>active range</a>.
+
+  <li>If <var title="">range</var> is null, abort these steps and do nothing.
+
+  <li>If no <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> is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in <var title="">range</var>, and
+  either <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> is not a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> 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
+  or <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>,
+  and either <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> is not a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> 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 or <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is 0, call <code class=external data-anolis-spec=domrange title=dom-Range-deleteContents><a href=http://html5.org/specs/dom-range.html#dom-range-deletecontents>deleteContents()</a></code> on <var title="">range</var>
+  and abort these steps.
+  <!-- This is precisely the case where deleteContents() will not alter the
+  DOM, just collapse the selection.  I think. -->
+
+  <p class=XXX>Is it possible for subsequent steps to make the range's start go
+  past its end or vice versa, or does this step successfully prevent that case?
+
+  <!-- Drill the range down to the lowest possible level, so we don't delete
+  more elements than necessary. -->
+  <li>While the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> of <var title="">range</var> has at least 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>:
+  <!--
+  We don't want to keep going when we hit an element with no children, because
+  then we'd do something like
+
+    foo{<br />bar]
+    -> foo<br>{</br>bar]
+    -> foo<br />{bar]
+    -> foo<br />[bar]
+
+  and we deselected the <br>.
+  -->
+
+  <ol>
+    <li>If <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>'s
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, and its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>'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 not null, set
+    <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> to (<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, 1 +
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>) and continue this loop from the beginning.
+    <!--
+    For instance:
+
+      <b>foo[</b><i>bar]</i>
+      -> <b>foo</b>{<i>bar]</i>
+
+    Then the next step will make it <b>foo</b><i>[bar]</i>.
+    -->
+
+    <li>If <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>'s
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, break from this loop.
+    <!-- This happens if the first step brought us all the way up to the root.
+    The step immediately after this loop will bring us back down again.  -->
+
+    <li>Let <var title="">reference node</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>child</a> of <var title="">range</var>'s
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> equal to its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a>.
+
+    <li>If <var title="">reference 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> with no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>,
+    break from this loop.
+    <!-- Don't descend into it, since then it won't get deleted even if it's
+    selected. -->
+
+    <li>Set <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> to (<var title="">reference node</var>,
+    0).
+  </ol>
+
+  <!-- Corner case: maybe we went all the way up to the end of the root. -->
+  <li>If <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of its
+  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, then while <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> 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>
+  and its last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> with no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, set
+  <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> to (last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>,
+  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of 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 <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>).
+
+  <li>While the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> of <var title="">range</var> has at least 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>:
+
+  <ol>
+    <li>If <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is 0, and its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>'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 not null, set <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> to (<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>
+    of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>) and continue this loop from the
+    beginning.
+
+    <li>If <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is 0, break from this loop.
+
+    <li>Let <var title="">reference node</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>child</a> of <var title="">range</var>'s
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> equal to its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> minus one.
+
+    <li>If <var title="">reference 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> with no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>,
+    break from this loop.
+
+    <li>Set <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> to (<var title="">reference node</var>,
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of <var title="">reference node</var>).
+  </ol>
+
+  <li>If <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is 0, then while <var title="">range</var>'s
+  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> 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> and 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> 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>
+  with no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, set <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> to (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 <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, 0).
+
+  <li>Let <var title="">start block</var> be the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> of
+  <var title="">range</var>.
+
+  <li>While <var title="">start block</var> is not an <a href=#html-element>HTML element</a> or its
+  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> is not a <a href=#prohibited-paragraph-children title="prohibited paragraph children">prohibited
+  paragraph child</a>, set <var title="">start block</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+  <p class=XXX>I'm uncertain about the use of prohibited paragraph children
+  here.  I'm using it mostly because it's convenient and seems relatively
+  sensible.  If we really want to use it, we probably want to change its name.
+
+  <li>Let <var title="">end block</var> be the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> of
+  <var title="">range</var>.
+
+  <li>While <var title="">end block</var> is not an <a href=#html-element>HTML element</a> or its
+  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> is not a <a href=#prohibited-paragraph-children title="prohibited paragraph children">prohibited
+  paragraph child</a>, set <var title="">end block</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+  <li>Call <code class=external data-anolis-spec=domrange title=dom-Range-deleteContents><a href=http://html5.org/specs/dom-range.html#dom-range-deletecontents>deleteContents()</a></code> on <var title="">range</var>.
+
+  <p class=XXX>This might blow up non-editable stuff.
+
+  <li>If <var title="">start block</var> or its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is null, or <var title="">end
+  block</var> or its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is null, or <var title="">start block</var> is an
+  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-ancestor title=concept-tree-ancestor>ancestor</a> or <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendant</a> of <var title="">end block</var>, abort these steps.
+
+  <li>Set the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> of <var title="">range</var> to
+  (<var title="">start block</var>, <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of <var title="">start block</var>).
+
+  <li>While <var title="">end block</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="">end block</var> to <var title="">start block</var>, <a href=#preserving-ranges>preserving
+  ranges</a>.
+
+  <li>While <var title="">end block</var> has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, let <var title="">parent</var> be
+  the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of <var title="">end block</var>, then remove <var title="">end block</var> from
+  <var title="">parent</var>, then set <var title="">end block</var> to <var title="">parent</var>.
+</ol>
+
 <p>To move 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> to a new location, <dfn id=preserving-ranges>preserving ranges</dfn>, remove
 the <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> from its original <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> (if any), then insert it in the new
 location.  In doing so, however, ignore the regular <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#range-mutation-rules>range mutation rules</a>, and
@@ -1121,7 +1256,7 @@
 
   <li>While the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> of <var title="">cloned range</var> equals the
   <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, and 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="">clone range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> is not null, set the
+  <var title="">cloned range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> is not null, set the
   <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> of <var title="">cloned range</var> to (<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>
   <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, 1 + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>).
 
@@ -2244,7 +2379,7 @@
 
   <li>Let <var title="">range</var> be the <a href=#active-range>active range</a>.
 
-  <li>Run <code class=external data-anolis-spec=domrange title=dom-Range-deleteContents><a href=http://html5.org/specs/dom-range.html#dom-range-deletecontents>deleteContents()</a></code> on <var title="">range</var>.
+  <li><a href=#delete-the-selection>Delete the selection</a>.
 
   <li>Let <var title="">img</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("img")</a></code> on the
   <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.
--- a/implementation.js	Wed May 25 13:54:18 2011 -0600
+++ b/implementation.js	Thu May 26 10:38:25 2011 -0600
@@ -302,8 +302,8 @@
 }
 
 /**
- * Return all editable nodes contained in range that the provided function
- * returns true for, omitting any with an ancestor already being returned.
+ * Return all nodes contained in range that the provided function returns true
+ * for, omitting any with an ancestor already being returned.
  */
 function collectContainedNodes(range, condition) {
 	var node = range.startContainer;
@@ -332,7 +332,6 @@
 	var nodeList = [];
 	while (isBefore(node, stop)) {
 		if (isContained(node, range)
-		&& isEditable(node)
 		&& condition(node)) {
 			nodeList.push(node);
 			node = nextNodeDescendants(node);
@@ -659,6 +658,180 @@
 	return newParent;
 }
 
+// "This is defined to be the first range in the Selection given by calling
+// getSelection() on the context object, or null if there is no such range."
+function getActiveRange() {
+	if (getSelection().rangeCount) {
+		return getSelection().getRangeAt(0);
+	}
+	return null;
+}
+
+function deleteSelection() {
+	// "Let range be the active range."
+	var range = globalRange;
+
+	// "If range is null, abort these steps and do nothing."
+	if (!range) {
+		return;
+	}
+
+	// "If no node is contained in range, and either range's start node is not
+	// a Text or Comment node or range's start offset is its start node's
+	// length, and either range's end node is not a Text or Comment node or
+	// range's end offset is 0, call deleteContents() on range and abort these
+	// steps."
+	if (!collectContainedNodes(range, function() { return true }).length
+	&& ((range.startContainer.nodeType != Node.TEXT_NODE
+	&& range.startContainer.nodeType != Node.COMMENT_NODE)
+	|| range.startOffset == getNodeLength(range.startContainer))
+	&& ((range.endContainer.nodeType != Node.TEXT_NODE
+	&& range.endContainer.nodeType != Node.COMMENT_NODE)
+	|| range.endOffset == 0)) {
+		range.deleteContents();
+		return;
+	}
+
+	// "While the start node of range has at least one child:"
+	while (range.startContainer.hasChildNodes()) {
+		// "If range's start offset is its start node's length, and its start
+		// node's parent is not null, set range's start to (parent of start
+		// node, 1 + index of start node) and continue this loop from the
+		// beginning."
+		if (range.startOffset == getNodeLength(range.startContainer)
+		&& range.startContainer.parentNode) {
+			range.setStart(range.startContainer.parentNode, 1 + getNodeIndex(range.startContainer));
+			continue;
+		}
+
+		// "If range's start offset is its start node's length, break from this
+		// loop."
+		if (range.startOffset == getNodeLength(range.startContainer)) {
+			break;
+		}
+
+		// "Let reference node be the child of range's start node with index
+		// equal to its start offset."
+		var referenceNode = range.startContainer.childNodes[range.startOffset];
+
+		// "If reference node is an Element with no children, break from this
+		// loop."
+		if (referenceNode.nodeType == Node.ELEMENT_NODE
+		&& !referenceNode.hasChildNodes()) {
+			break;
+		}
+
+		// "Set range's start to (reference node, 0)."
+		range.setStart(referenceNode, 0);
+	}
+
+	// "If range's start offset is the length of its start node, then while
+	// range's start node has children and its last child is not an Element
+	// with no children, set range's start to (last child of start node, length
+	// of last child of start node)."
+	if (range.startOffset == getNodeLength(range.startContainer)) {
+		while (range.startContainer.hasChildNodes()
+		&& (range.lastChild.nodeType != Node.ELEMENT_NODE
+		|| range.lastChild.hasChildNodes())) {
+			range.setStart(range.startContainer.lastChild, getNodeLength(range.startContainer.lastChild));
+		}
+	}
+
+	// "While the end node of range has at least one child:"
+	while (range.endContainer.hasChildNodes()) {
+		// "If range's end offset is 0, and its end node's parent is not null,
+		// set range's end to (parent of end node, index of end node) and
+		// continue this loop from the beginning."
+		if (range.endOffset == 0
+		&& range.endContainer.parentNode) {
+			range.setEnd(range.endContainer.parentNode, getNodeIndex(range.endContainer));
+			continue;
+		}
+
+		// "If range's end offset is 0, break from this loop."
+		if (range.endOffset == 0) {
+			break;
+		}
+
+		// "Let reference node be the child of range's end node with index
+		// equal to its end offset minus one."
+		var referenceNode = range.endContainer.childNodes[range.endOffset - 1];
+
+		// "If reference node is an Element with no children, break from this
+		// loop."
+		if (referenceNode.nodeType == Node.ELEMENT_NODE
+		&& !referenceNode.hasChildNodes()) {
+			break;
+		}
+
+		// "Set range's end to (reference node, length of reference node)."
+		range.setEnd(referenceNode, getNodeLength(referenceNode));
+	}
+
+	// "If range's end offset is 0, then while range's end node has children
+	// and its first child is not an Element with no children, set range's end
+	// to (first child of end node, 0)."
+	if (range.endOffset == 0) {
+		while (range.endContainer.hasChildNodes()
+		&& (range.lastChild.nodeType != Node.ELEMENT_NODE
+		|| range.lastChild.hasChildNodes())) {
+			range.setEnd(range.endContainer.firstChild, 0);
+		}
+	}
+
+	// "Let start block be the start node of range."
+	var startBlock = range.startContainer;
+
+	// "While start block is not an HTML element or its local name is not a
+	// prohibited paragraph child, set start block to its parent."
+	while (!isHtmlElement(startBlock, prohibitedParagraphChildren)) {
+		startBlock = startBlock.parentNode;
+	}
+
+	// "Let end block be the end node of range."
+	var endBlock = range.endContainer;
+
+	// "While end block is not an HTML element or its local name is not a
+	// prohibited paragraph child, set end block to its parent."
+	while (!isHtmlElement(endBlock, prohibitedParagraphChildren)) {
+		endBlock = endBlock.parentNode;
+	}
+
+	// "Call deleteContents() on range."
+	range.deleteContents();
+
+	// "If start block or its parent is null, or end block or its parent is
+	// null, or start block is an ancestor or descendant of end block, abort
+	// these steps."
+	if (!startBlock
+	|| !startBlock.parentNode
+	|| !endBlock
+	|| !endBlock.parentNode
+	|| isAncestor(startBlock, endBlock)
+	|| isDescendant(startBlock, endBlock)) {
+		return;
+	}
+
+	// "Set the start and end of range to (start block, length of start
+	// block)."
+	range.setStart(startBlock, getNodeLength(startBlock));
+	range.setEnd(startBlock, getNodeLength(startBlock));
+
+	// "While end block has children, append the first child of end block to
+	// start block, preserving ranges."
+	while (endBlock.hasChildNodes()) {
+		movePreservingRanges(endBlock.firstChild, startBlock, -1);
+	}
+
+	// "While end block has no children, let parent be the parent of end block,
+	// then remove end block from parent, then set end block to parent."
+	while (!endBlock.hasChildNodes()) {
+		var parent_ = endBlock.parentNode;
+		parent_.removeChild(endBlock);
+		endBlock = parent_;
+	}
+}
+
 function removeExtraneousLineBreaksBefore(node) {
 	// "If node is not an Element, or it is an inline node, do nothing and
 	// abort these steps."
@@ -2699,7 +2872,8 @@
 		// "dd", "dl", "dt", "footer", "header", "hgroup", "li", "nav", "ol",
 		// "section", "table", "tbody", "td", "th", "thead", "tr", or "ul"."
 		nodeList = collectContainedNodes(newRange, function(node) {
-			return !isHtmlElement(node, ["ARTICLE", "ASIDE", "BLOCKQUOTE",
+			return isEditable(node)
+				&& !isHtmlElement(node, ["ARTICLE", "ASIDE", "BLOCKQUOTE",
 				"CAPTION", "COL", "COLGROUP", "DD", "DL", "DT", "FOOTER",
 				"HEADER", "HGROUP", "LI", "NAV", "OL", "SECTION", "TABLE",
 				"TBODY", "TD", "TH", "THEAD", "TR", "UL"]);
@@ -2942,8 +3116,8 @@
 			return;
 		}
 
-		// "Run deleteContents() on the range."
-		range.deleteContents();
+		// "Delete the selection."
+		deleteSelection();
 
 		// "Let img be the result of calling createElement("img") on the
 		// context object."
--- a/preprocess	Wed May 25 13:54:18 2011 -0600
+++ b/preprocess	Thu May 26 10:38:25 2011 -0600
@@ -34,6 +34,8 @@
     'documenttype': '<code data-anolis-spec=domcore>DocumentType</code>',
     'element': '<code data-anolis-spec=domcore>Element</code>',
     'em': '<code data-anolis-spec=html title="the em element">em</code>',
+    'endnode': '<span data-anolis-spec=domrange title=concept-range-end>end</span> <span data-anolis-spec=domrange title=concept-boundary-point-node>node</span>',
+    'endoffset': '<span data-anolis-spec=domrange title=concept-range-end>end</span> <span data-anolis-spec=domrange title=concept-boundary-point-offset>offset</span>',
     'followingsibling': '<span data-anolis-spec=domcore title="concept-tree-following-sibling">following sibling</span>',
     'font': '<code data-anolis-spec=html title=font>font</code>',
     'fontcolor': '<code data-anolis-spec=html title=dom-font-color>color</code>',
@@ -69,6 +71,8 @@
     'sibling': '<span data-anolis-spec=domcore title=concept-tree-sibling>sibling</span>',
     'spacecharacter': '<span data-anolis-spec=domcore title="space character">space character</span>',
     'span': '<code data-anolis-spec=html title="the span element">span</code>',
+    'startnode': '<span data-anolis-spec=domrange title=concept-range-start>start</span> <span data-anolis-spec=domrange title=concept-boundary-point-node>node</span>',
+    'startoffset': '<span data-anolis-spec=domrange title=concept-range-start>start</span> <span data-anolis-spec=domrange title=concept-boundary-point-offset>offset</span>',
     'strike': '<code data-anolis-spec=html title="the strike element">strike</code>',
     'strong': '<code data-anolis-spec=html title="the strong element">strong</code>',
     'style': '<code data-anolis-spec=html title="the style attribute">style</code>',
--- a/source.html	Wed May 25 13:54:18 2011 -0600
+++ b/source.html	Thu May 26 10:38:25 2011 -0600
@@ -667,6 +667,144 @@
   <li>Return <var>new parent</var>.
 </ol>
 
+<p>To <dfn>delete the selection</dfn>:
+
+<ol>
+  <li>Let <var>range</var> be the <span>active range</span>.
+
+  <li>If <var>range</var> is null, abort these steps and do nothing.
+
+  <li>If no [[node]] is [[contained]] in <var>range</var>, and
+  either <var>range</var>'s [[startnode]] is not a [[text]] or [[comment]] node
+  or <var>range</var>'s [[startoffset]] is its [[startnode]]'s [[nodelength]],
+  and either <var>range</var>'s [[endnode]] is not a [[text]] or [[comment]]
+  node or <var>range</var>'s [[endoffset]] is 0, call <code
+  data-anolis-spec=domrange
+  title=dom-Range-deleteContents>deleteContents()</code> on <var>range</var>
+  and abort these steps.
+  <!-- This is precisely the case where deleteContents() will not alter the
+  DOM, just collapse the selection.  I think. -->
+
+  <p class=XXX>Is it possible for subsequent steps to make the range's start go
+  past its end or vice versa, or does this step successfully prevent that case?
+
+  <!-- Drill the range down to the lowest possible level, so we don't delete
+  more elements than necessary. -->
+  <li>While the [[startnode]] of <var>range</var> has at least one [[child]]:
+  <!--
+  We don't want to keep going when we hit an element with no children, because
+  then we'd do something like
+
+    foo{<br />bar]
+    -> foo<br>{</br>bar]
+    -> foo<br />{bar]
+    -> foo<br />[bar]
+
+  and we deselected the <br>.
+  -->
+
+  <ol>
+    <li>If <var>range</var>'s [[startoffset]] is its [[startnode]]'s
+    [[nodelength]], and its [[startnode]]'s [[parent]] is not null, set
+    <var>range</var>'s [[rangestart]] to ([[parent]] of [[startnode]], 1 +
+    [[index]] of [[startnode]]) and continue this loop from the beginning.
+    <!--
+    For instance:
+
+      <b>foo[</b><i>bar]</i>
+      -> <b>foo</b>{<i>bar]</i>
+
+    Then the next step will make it <b>foo</b><i>[bar]</i>.
+    -->
+
+    <li>If <var>range</var>'s [[startoffset]] is its [[startnode]]'s
+    [[nodelength]], break from this loop.
+    <!-- This happens if the first step brought us all the way up to the root.
+    The step immediately after this loop will bring us back down again.  -->
+
+    <li>Let <var>reference node</var> be the [[child]] of <var>range</var>'s
+    [[startnode]] with [[index]] equal to its [[startoffset]].
+
+    <li>If <var>reference node</var> is an [[element]] with no [[children]],
+    break from this loop.
+    <!-- Don't descend into it, since then it won't get deleted even if it's
+    selected. -->
+
+    <li>Set <var>range</var>'s [[rangestart]] to (<var>reference node</var>,
+    0).
+  </ol>
+
+  <!-- Corner case: maybe we went all the way up to the end of the root. -->
+  <li>If <var>range</var>'s [[startoffset]] is the [[nodelength]] of its
+  [[startnode]], then while <var>range</var>'s [[startnode]] has [[children]]
+  and its last [[child]] is not an [[element]] with no [[children]], set
+  <var>range</var>'s [[rangestart]] to (last [[child]] of [[startnode]],
+  [[nodelength]] of last [[child]] of [[startnode]]).
+
+  <li>While the [[endnode]] of <var>range</var> has at least one [[child]]:
+
+  <ol>
+    <li>If <var>range</var>'s [[endoffset]] is 0, and its [[endnode]]'s
+    [[parent]] is not null, set <var>range</var>'s [[rangeend]] to ([[parent]]
+    of [[endnode]], [[index]] of [[endnode]]) and continue this loop from the
+    beginning.
+
+    <li>If <var>range</var>'s [[endoffset]] is 0, break from this loop.
+
+    <li>Let <var>reference node</var> be the [[child]] of <var>range</var>'s
+    [[endnode]] with [[index]] equal to its [[endoffset]] minus one.
+
+    <li>If <var>reference node</var> is an [[element]] with no [[children]],
+    break from this loop.
+
+    <li>Set <var>range</var>'s [[rangeend]] to (<var>reference node</var>,
+    [[nodelength]] of <var>reference node</var>).
+  </ol>
+
+  <li>If <var>range</var>'s [[endoffset]] is 0, then while <var>range</var>'s
+  [[endnode]] has [[children]] and its first [[child]] is not an [[element]]
+  with no [[children]], set <var>range</var>'s [[rangeend]] to (first [[child]]
+  of [[endnode]], 0).
+
+  <li>Let <var>start block</var> be the [[rangestart]] [[bpnode]] of
+  <var>range</var>.
+
+  <li>While <var>start block</var> is not an <span>HTML element</span> or its
+  [[localname]] is not a <span title="prohibited paragraph children">prohibited
+  paragraph child</span>, set <var>start block</var> to its [[parent]].
+
+  <p class=XXX>I'm uncertain about the use of prohibited paragraph children
+  here.  I'm using it mostly because it's convenient and seems relatively
+  sensible.  If we really want to use it, we probably want to change its name.
+
+  <li>Let <var>end block</var> be the [[rangeend]] [[bpnode]] of
+  <var>range</var>.
+
+  <li>While <var>end block</var> is not an <span>HTML element</span> or its
+  [[localname]] is not a <span title="prohibited paragraph children">prohibited
+  paragraph child</span>, set <var>end block</var> to its [[parent]].
+
+  <li>Call <code data-anolis-spec=domrange
+  title=dom-Range-deleteContents>deleteContents()</code> on <var>range</var>.
+
+  <p class=XXX>This might blow up non-editable stuff.
+
+  <li>If <var>start block</var> or its [[parent]] is null, or <var>end
+  block</var> or its [[parent]] is null, or <var>start block</var> is an
+  [[ancestor]] or [[descendant]] of <var>end block</var>, abort these steps.
+
+  <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
+  (<var>start block</var>, [[nodelength]] of <var>start block</var>).
+
+  <li>While <var>end block</var> has [[children]], append the first [[child]]
+  of <var>end block</var> to <var>start block</var>, <span>preserving
+  ranges</span>.
+
+  <li>While <var>end block</var> has no [[children]], let <var>parent</var> be
+  the [[parent]] of <var>end block</var>, then remove <var>end block</var> from
+  <var>parent</var>, then set <var>end block</var> to <var>parent</var>.
+</ol>
+
 <p>To move a [[node]] to a new location, <dfn>preserving ranges</dfn>, remove
 the [[node]] from its original [[parent]] (if any), then insert it in the new
 location.  In doing so, however, ignore the regular [[rangemutationrules]], and
@@ -1091,7 +1229,7 @@
 
   <li>While the [[rangeend]] [[bpoffset]] of <var>cloned range</var> equals the
   [[nodelength]] of its [[rangeend]] [[bpnode]], and the [[parent]] of
-  <var>clone range</var>'s [[rangeend]] [[bpnode]] is not null, set the
+  <var>cloned range</var>'s [[rangeend]] [[bpnode]] is not null, set the
   [[rangeend]] of <var>cloned range</var> to ([[parent]] of [[rangeend]]
   [[bpnode]], 1 + [[index]] of [[rangeend]] [[bpnode]]).
 
@@ -2233,8 +2371,7 @@
 
   <li>Let <var>range</var> be the <span>active range</span>.
 
-  <li>Run <code data-anolis-spec=domrange
-  title=dom-Range-deleteContents>deleteContents()</code> on <var>range</var>.
+  <li><span>Delete the selection</span>.
 
   <li>Let <var>img</var> be the result of calling <code
   data-anolis-spec=domcore