--- a/editing.html Mon Aug 29 14:42:53 2011 -0600
+++ b/editing.html Tue Aug 30 13:52:24 2011 -0600
@@ -65,7 +65,7 @@
<body class=draft>
<div class=head id=head>
<h1>HTML Editing APIs</h1>
-<h2 class="no-num no-toc" id=work-in-progress-—-last-update-29-august-2011>Work in Progress — Last Update 29 August 2011</h2>
+<h2 class="no-num no-toc" id=work-in-progress-—-last-update-30-august-2011>Work in Progress — Last Update 30 August 2011</h2>
<dl>
<dt>Editor
<dd>Aryeh Gregor <<a href=mailto:ayg@aryeh.name>ayg@aryeh.name</a>>
@@ -154,7 +154,7 @@
<li><a href=#assorted-block-formatting-command-algorithms>Assorted block formatting command algorithms</a></li>
<li><a href=#block-extending-a-range>Block-extending a range</a></li>
<li><a href=#recording-and-restoring-overrides>Recording and restoring overrides</a></li>
- <li><a href=#deleting-the-contents-of-a-range>Deleting the contents of a range</a></li>
+ <li><a href=#deleting-the-selection>Deleting the selection</a></li>
<li><a href="#splitting-a-node-list's-parent">Splitting a node list's parent</a></li>
<li><a href=#canonical-space-sequences>Canonical space sequences</a></li>
<li><a href=#indenting-and-outdenting>Indenting and outdenting</a></li>
@@ -1306,7 +1306,18 @@
<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#tree-order>tree order</a>.
<li>If <var title="">ref</var> is an <a href=#editable>editable</a> <a href=#extraneous-line-break>extraneous line
- break</a>, remove it 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>.
+ break</a>:
+
+ <ol>
+ <li>
+ <p class=comments>If the block ends with <code title=""><span><br></span></code>, for
+ instance, we want to remove the span too.
+
+ <p>While <var title="">ref</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is <a href=#editable>editable</a> and
+ <a href=#invisible>invisible</a>, set <var title="">ref</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>Remove <var title="">ref</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>
</ol>
<p>To <dfn id=remove-extraneous-line-breaks-from>remove extraneous line breaks from</dfn> a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a>, first
@@ -4410,31 +4421,33 @@
</ol>
<!--@}-->
-<h3 id=deleting-the-contents-of-a-range>Deleting the contents of a range</h3>
+<h3 id=deleting-the-selection>Deleting the selection</h3>
<p class=comments>TODO: Consider what should happen for block merging in corner
cases like display: inline-table.
-<p>To <dfn id=delete-the-contents>delete the contents</dfn> of a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> <var title="">range</var>, given a
-<var title="">block merging</var> flag that defaults to true and a <var title="">strip
-wrappers</var> flag that defaults to true:
+<p>To <dfn id=delete-the-selection>delete the selection</dfn>, given a <var title="">block merging</var> flag
+that defaults to true, a <var title="">strip wrappers</var> flag that defaults to
+true, and a string <var title="">direction</var> that defaults to "forward":
<div class=note>
<p>The idea behind this algorithm is self-explanatory, but the details wind up
being remarkably complicated.
-<p>First, any editable nodes inside the range will be deleted, and the range
-will be collapsed. By way of contrast, <a href=#effectively-contained>effectively contained</a>
-tries to expand the range to include as much as possible, so <code title=""><p>[foo]</p></code> contains the <code title=""><p></code>. What
-we do here is contract the range to include as little as possible, so <code title="">{<p>foo</p>}</code> contains only <code title="">foo</code> and
-doesn't delete the paragraph.
-
-<p>After that, if the range originally started and ended in different blocks,
-and the <var title="">block merging</var> flag is true, the end block will get merged
-into the start block. This is needed so if the user selects text on several
-lines and deletes it, the text immediately that was before the selection winds
-up on the same line as the text immediately after it. For example, <code title=""><p>fo[o</p><div>b]ar</div></code> becomes <code title=""><p>fo[]ar</p></code>. This procedure winds up being tricky, and
-takes up a large chunk of the logic.
+<p>First, any editable nodes inside the selection will be deleted, and the
+selection will be collapsed. By way of contrast, <a href=#effectively-contained>effectively
+contained</a> tries to expand the range to include as much as possible, so
+<code title=""><p>[foo]</p></code> contains the <code title=""><p></code>. What we do here is contract
+the range to include as little as possible, so <code title="">{<p>foo</p>} </code> contains
+only <code title="">foo</code> and doesn't delete the paragraph.
+
+<p>After that, if the selection originally started and ended in different
+blocks, and the <var title="">block merging</var> flag is true, the end block will get
+merged into the start block. This is needed so if the user selects text on
+several lines and deletes it, the text immediately that was before the
+selection winds up on the same line as the text immediately after it. For
+example, <code title=""><p>fo[o</p><div>b]ar</div></code> becomes <code title=""><p>fo[]ar</p></code>.
+This procedure winds up being tricky, and takes up a large chunk of the logic.
<p>Tables are a notable special case. If an entire table is contained in the
range, it will be deleted. If it's anything less, only the contents of the
@@ -4456,11 +4469,12 @@
</div>
<ol>
- <li>If <var title="">range</var> is null, abort these steps and do nothing.
+ <li>If the <a href=#active-range>active range</a> is null, abort these steps and do
+ nothing.
<li>Let <var title="">start node</var>, <var title="">start offset</var>, <var title="">end node</var>,
- and <var title="">end offset</var> be <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> and
- <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>nodes</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offsets</a>.
+ and <var title="">end offset</var> be the <a href=#active-range>active range</a>'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>
+ and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>nodes</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offsets</a>.
<li>
<div class=comments>
@@ -4475,7 +4489,7 @@
-> foo<br />{bar]
-> foo<br />[bar]</pre>
- <p>and we deselected the <br>.
+ <p>and we deselected the <code title=""><br></code>.
</div>
<p>While <var title="">start node</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>:
@@ -4489,7 +4503,7 @@
-> <b>foo{</b><i>bar]</i>
-> <b>foo</b>{<i>bar]</i></pre>
- <p>Then the next step will make it <b>foo</b><i>[bar]</i>.
+ <p>Then the next step will make it <code title=""><b>foo</b><i>[bar]</i></code>.
<p>We don't want to do this for block nodes, because that would lead to
something like
@@ -4497,7 +4511,7 @@
<pre><p>foo[</p><p>]bar<p></pre>
<p>ultimately collapsing, which is wrong. Once we do the deletion, it
- needs to wind up <p>foo[]bar</p>, whereas an actually collapsed
+ needs to wind up <code title=""><p>foo[]bar</p></code>, whereas an actually collapsed
selection should do nothing.
</div>
@@ -4562,8 +4576,17 @@
</ol>
<li>If (<var title="">end node</var>, <var title="">end offset</var>) is not <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-after title=concept-bp-after>after</a>
- (<var title="">start node</var>, <var title="">start offset</var>), 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 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> and abort these steps.
+ (<var title="">start node</var>, <var title="">start offset</var>):
+
+ <ol>
+ <li>If <var title="">direction</var> is "forward", call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToStart><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetostart>collapseToStart()</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Otherwise, call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToEnd><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetoend>collapseToEnd()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s
+ <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Abort these steps.
+ </ol>
<li>If <var title="">start node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and <var title="">start offset</var>
is 0, set <var title="">start offset</var> to the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <var title="">start node</var>,
@@ -4573,9 +4596,11 @@
its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, set <var title="">end offset</var> to one plus the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of
<var title="">end node</var>, then set <var title="">end node</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
- <li>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="">start node</var>,
- <var title="">start offset</var>) 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> to (<var title="">end node</var>,
- <var title="">end offset</var>).
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">start node</var>, <var title="">start offset</var>)</a></code> on
+ the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">end node</var>, <var title="">end offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
<li>
<div class=comments>
@@ -4589,8 +4614,8 @@
anything.
</div>
- <p>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>.
+ <p>Let <var title="">start block</var> be the <a href=#active-range>active range</a>'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>.
<li>While <var title="">start block</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is <a href=#in-the-same-editing-host>in the same editing
host</a> and <var title="">start block</var> is an <a href=#inline-node>inline node</a>, set
@@ -4626,8 +4651,7 @@
<var title="">start block</var>, or <var title="">start block</var> is a <code class=external data-anolis-spec=html title="the td element"><a href=http://www.whatwg.org/html/#the-td-element>td</a></code> or <code class=external data-anolis-spec=html title="the th element"><a href=http://www.whatwg.org/html/#the-th-element>th</a></code>, set
<var title="">start block</var> to null.
- <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>Let <var title="">end block</var> be the <a href=#active-range>active range</a>'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>.
<li>While <var title="">end block</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is <a href=#in-the-same-editing-host>in the same editing
host</a> and <var title="">end block</var> is an <a href=#inline-node>inline node</a>, set
@@ -4669,7 +4693,11 @@
<li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at (<var title="">start node</var>,
<var title="">start offset</var>).
- <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 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>.
+ <li>If <var title="">direction</var> is "forward", call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToStart><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetostart>collapseToStart()</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Otherwise, call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToEnd><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetoend>collapseToEnd()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s
+ <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
<li>
<p class=comments>This is needed to restore any overrides that would
@@ -4697,9 +4725,9 @@
cell-selection mode when you try to select between cells, at least in some
cases, instead of selecting letter-by-letter.
- <p>For each <var title="">node</var> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in <var title="">range</var>, append
- <var title="">node</var> to <var title="">node list</var> if the last member of <var title="">node
- list</var> (if any) is not 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> of <var title="">node</var>;
+ <p>For each <var title="">node</var> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the <a href=#active-range>active range</a>,
+ append <var title="">node</var> to <var title="">node list</var> if the last member of
+ <var title="">node list</var> (if any) is not 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> of <var title="">node</var>;
<var title="">node</var> is <a href=#editable>editable</a>; and <var title="">node</var> is not a
<code class=external data-anolis-spec=html title="the thead element"><a href=http://www.whatwg.org/html/#the-thead-element>thead</a></code>, <code class=external data-anolis-spec=html title="the tbody element"><a href=http://www.whatwg.org/html/#the-tbody-element>tbody</a></code>, <code class=external data-anolis-spec=html title="the tfoot element"><a href=http://www.whatwg.org/html/#the-tfoot-element>tfoot</a></code>, <code class=external data-anolis-spec=html title="the tr element"><a href=http://www.whatwg.org/html/#the-tr-element>tr</a></code>, <code class=external data-anolis-spec=html title="the th element"><a href=http://www.whatwg.org/html/#the-th-element>th</a></code>, or <code class=external data-anolis-spec=html title="the td element"><a href=http://www.whatwg.org/html/#the-td-element>td</a></code>.
@@ -4738,10 +4766,11 @@
<li>If <var title="">end node</var> is an <a href=#editable>editable</a> <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, call
<code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(0, <var title="">end offset</var>)</a></code> on it.
- <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at <var title="">range</var>'s
+ <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'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>.
- <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at <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>.
+ <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'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>.
<li>
<div class=comments>
@@ -4771,7 +4800,11 @@
and <var title="">end block</var> are the same:
<ol>
- <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 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>.
+ <li>If <var title="">direction</var> is "forward", call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToStart><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetostart>collapseToStart()</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Otherwise, call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToEnd><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetoend>collapseToEnd()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s
+ <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
<li><a href=#restore-states-and-values>Restore states and values</a> from <var title="">overrides</var>.
@@ -4788,9 +4821,6 @@
<p>If <var title="">start block</var> has 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>, which is a <a href=#collapsed-block-prop>collapsed
block prop</a>, remove 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> from it.
- <li>If <var title="">end block</var> has 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>, which is a <a href=#collapsed-block-prop>collapsed
- block prop</a>, remove 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> from it.
-
<li>
<p class=comments>Just repeatedly blow up the end block in this case.
@@ -4802,8 +4832,9 @@
<li>While <var title="">reference 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="">start
block</var>, set <var title="">reference node</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
- <li>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-indexof title=concept-indexof>index</a> of <var title="">reference node</var>).
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>, with
+ first argument <var title="">start block</var> and second argument the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of
+ <var title="">reference node</var>.
<li>If <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>:
@@ -4860,8 +4891,9 @@
block</var>:
<ol>
- <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>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>, with
+ first argument <var title="">start block</var> and second argument <var title="">start
+ block</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>.
<li>Let <var title="">reference node</var> be <var title="">start block</var>.
@@ -4875,12 +4907,12 @@
<li>Let <var title="">nodes to move</var> be a list of <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a>, initially empty.
<li>If <var title="">reference 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> is neither null nor 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> nor a <a href=#block-node>block node</a>, append it to <var title="">nodes to
- move</var>.
-
- <li>While <var title="">nodes to move</var> is nonempty and its last member's
- <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> is neither null nor 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> nor a <a href=#block-node>block node</a>,
- append it to <var title="">nodes to move</var>.
+ <a href=#block-node>block node</a>, append it to <var title="">nodes to move</var>.
+
+ <li>While <var title="">nodes to move</var> is nonempty and its last member isn't a
+ <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> and its last member's <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> is neither null nor a
+ <a href=#block-node>block node</a>, append its last member's <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> to
+ <var title="">nodes to move</var>.
<li><a href=#record-the-values>Record the values</a> of <var title="">nodes to move</var>, and let
<var title="">values</var> be the result.
@@ -4888,9 +4920,6 @@
<li>For each <var title="">node</var> in <var title="">nodes to move</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="">start block</var>,
<a href=#preserving-ranges>preserving ranges</a>.
-
- <li>If the <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> of <var title="">reference node</var> is a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, remove
- it from its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
</ol>
<li>
@@ -4901,8 +4930,9 @@
<p>Otherwise:
<ol>
- <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>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>, with
+ first argument <var title="">start block</var> and second argument <var title="">start
+ block</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>.
<li>If <var title="">end block</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-firstChild><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-firstchild>firstChild</a></code> is an <a href=#inline-node>inline node</a>
and <var title="">start block</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-lastChild><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-lastchild>lastChild</a></code> is a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, remove <var title="">start
@@ -4926,6 +4956,9 @@
<code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and 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="">start block</var>.
+ <li><a href=#remove-extraneous-line-breaks-at-the-end-of>Remove extraneous line breaks at the end of</a> <var title="">start
+ block</var>.
+
<li><a href=#restore-states-and-values>Restore states and values</a> from <var title="">overrides</var>.
</ol>
@@ -6557,7 +6590,7 @@
<div class=note>
<p>This is the same as hitting backspace (see <a href=#additional-requirements>Additional requirements</a>). The easy part is
-if the selection isn't collapsed: just <a href=#delete-the-contents>delete the contents</a>. But
+if the selection isn't collapsed: just <a href=#delete-the-selection>delete the selection</a>. But
it turns out rich-text editors have a lot of special behaviors for hitting
backspace with a collapsed selection. Most obviously, if there's a text node
right before the cursor (maybe wrapped in some inline elements), we delete its
@@ -6600,8 +6633,8 @@
<p><a href=#action>Action</a>:
<ol>
- <li>If the <a href=#active-range>active range</a> is not <code class=external data-anolis-spec=domrange title=dom-Range-collapsed><a href=http://html5.org/specs/dom-range.html#dom-range-collapsed>collapsed</a></code>, <a href=#delete-the-contents>delete the contents</a>
- of the <a href=#active-range>active range</a> and abort these steps.
+ <li>If the <a href=#active-range>active range</a> is not <code class=external data-anolis-spec=domrange title=dom-Range-collapsed><a href=http://html5.org/specs/dom-range.html#dom-range-collapsed>collapsed</a></code>, <a href=#delete-the-selection>delete the selection</a>
+ and abort these steps.
<li>
<p class=comments>Needed so that if there are multiple consecutive spaces we
@@ -6691,10 +6724,21 @@
</div>
<p>If <var title="">node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and <var title="">offset</var> is not zero,
- call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
- Then <a href=#delete-the-contents>delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>
- (<var title="">node</var>, <var title="">offset</var> − 1) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>
- (<var title="">node</var>, <var title="">offset</var>) and abort these steps.
+ or if <var title="">node</var> is a <a href=#block-node>block node</a> that has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">offset</var> − 1 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 a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> or
+ <code class=external data-anolis-spec=html title="the hr element"><a href=http://www.whatwg.org/html/#the-hr-element>hr</a></code> or <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code>:
+
+ <ol>
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">node</var>, <var title="">offset</var> − 1)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>.
+
+ <li>Abort these steps.
+ </ol>
<li>
<p class=comments>At the time of this writing, this should be impossible.
@@ -6702,13 +6746,6 @@
<p>If <var title="">node</var> is an <a href=#inline-node>inline node</a>, abort these steps.
- <li>If <var title="">node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">offset</var>
- − 1 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 a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> or <code class=external data-anolis-spec=html title="the hr element"><a href=http://www.whatwg.org/html/#the-hr-element>hr</a></code> or <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code>, call
- <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
- Then <a href=#delete-the-contents>delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>
- (<var title="">node</var>, <var title="">offset</var> − 1) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>
- (<var title="">node</var>, <var title="">offset</var>) and abort these steps.
-
<li>
<p class=comments> If we're at the beginning of a list, we want to outdent
the first list item. This doesn't actually match anyone or anything. Word
@@ -6853,13 +6890,17 @@
an <a href=#inline-node>inline node</a>:
<ol>
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">start node</var>, <var title="">start offset</var>
+ − 1)</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">start node</var>, <var title="">start offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>.
+
<li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
<code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
- <li><a href=#delete-the-contents>Delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>
- (<var title="">start node</var>, <var title="">start offset</var> − 1) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>
- (<var title="">start node</var>, <var title="">start offset</var>).
-
<li>Abort these steps.
</ol>
@@ -6908,22 +6949,49 @@
<li>
<p class=comments>When merging adjacent list items, make sure we only merge
the items themselves, not any block children. We want
- <li><p>foo<li><p>bar to become <li><p>foo<p>bar, not
- <li><p>foo<br>bar or <li><p>foobar.
-
- <p>If the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">start node</var> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">start
- offset</var> is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> or <code class=external data-anolis-spec=html title="the dt element"><a href=http://www.whatwg.org/html/#the-dt-element>dt</a></code> or <code class=external data-anolis-spec=html title="the dd element"><a href=http://www.whatwg.org/html/#the-dd-element>dd</a></code>, and its <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> is
- also an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> or <code class=external data-anolis-spec=html title="the dt element"><a href=http://www.whatwg.org/html/#the-dt-element>dt</a></code> or <code class=external data-anolis-spec=html title="the dd element"><a href=http://www.whatwg.org/html/#the-dd-element>dd</a></code>, set <var title="">start node</var> to its
- <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">start offset</var> − 1, then set
- <var title="">start offset</var> to <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, then set
- <var title="">node</var> to <var title="">start 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>, then set
- <var title="">offset</var> to 0.
+ <code title=""><li><p>foo<li><p>[]bar</code> to become <code title=""><li><p>foo<p>[]bar</code>, not
+ <code title=""><li><p>foo<br>[]bar</code> or <code title=""><li><p>foo[]bar</code>. To do the
+ deletion, we need to wipe out the current selection, so we save it as a
+ range. Saving it as a node/offset pair isn't enough, because it might be
+ invalid after we do the deletion. A range will update according to the range
+ mutation rules.
+
+ <p>If <var title="">start node</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">start
+ offset</var> is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> or <code class=external data-anolis-spec=html title="the dt element"><a href=http://www.whatwg.org/html/#the-dt-element>dt</a></code> or <code class=external data-anolis-spec=html title="the dd element"><a href=http://www.whatwg.org/html/#the-dd-element>dd</a></code>, 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>'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> is also an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> or <code class=external data-anolis-spec=html title="the dt element"><a href=http://www.whatwg.org/html/#the-dt-element>dt</a></code> or <code class=external data-anolis-spec=html title="the dd element"><a href=http://www.whatwg.org/html/#the-dd-element>dd</a></code>:
+
+ <ol>
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Range-cloneRange><a href=http://html5.org/specs/dom-range.html#dom-range-clonerange>cloneRange()</a></code> on the <a href=#active-range>active range</a>, and let
+ <var title="">original range</var> be the result.
+
+ <li>Set <var title="">start node</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">start
+ offset</var> − 1.
+
+ <li>Set <var title="">start offset</var> to <var title="">start node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>.
+
+ <li>Set <var title="">node</var> to <var title="">start 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>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">start node</var>, <var title="">start offset</var>)</a></code> on
+ the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">node</var>, 0)</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s
+ <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-removeAllRanges><a href=http://html5.org/specs/dom-range.html#dom-selection-removeallranges>removeAllRanges()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-addRange><a href=http://html5.org/specs/dom-range.html#dom-selection-addrange>addRange(<var title="">original range</var>)</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s
+ <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Abort these steps.
+ </ol>
<li>
<p class=comments>General block-merging case.
- <p>Otherwise, while <var title="">start node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>
- <var title="">start offset</var> minus one:
+ <p>While <var title="">start node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">start
+ offset</var> minus one:
<ol>
<li>If <var title="">start node</var>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">start
@@ -6936,9 +7004,13 @@
<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 node</var>.
</ol>
- <li><a href=#delete-the-contents>Delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>
- (<var title="">start node</var>, <var title="">start offset</var>) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>
- (<var title="">node</var>, <var title="">offset</var>).
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">start node</var>, <var title="">start offset</var>)</a></code> on
+ the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>, with <var title="">direction</var> "backward".
</ol>
@@ -7290,8 +7362,8 @@
<p><a href=#action>Action</a>:
<ol>
- <li>If the <a href=#active-range>active range</a> is not <code class=external data-anolis-spec=domrange title=dom-Range-collapsed><a href=http://html5.org/specs/dom-range.html#dom-range-collapsed>collapsed</a></code>, <a href=#delete-the-contents>delete the contents</a>
- of the <a href=#active-range>active range</a> and abort these steps.
+ <li>If the <a href=#active-range>active range</a> is not <code class=external data-anolis-spec=domrange title=dom-Range-collapsed><a href=http://html5.org/specs/dom-range.html#dom-range-collapsed>collapsed</a></code>, <a href=#delete-the-selection>delete the selection</a>
+ and abort these steps.
<li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at (<a href=#active-range>active range</a>'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>, <a href=#active-range>active range</a>'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>).
@@ -7312,10 +7384,6 @@
<a href=#invisible>invisible</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>, remove 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> from
<var title="">node</var>.
- <li>Otherwise, if <var title="">node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>
- <var title="">offset</var> 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 a <a href=#collapsed-block-prop>collapsed block
- prop</a>, add one to <var title="">offset</var>.
-
<li>Otherwise, if <var title="">offset</var> is the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of
<var title="">node</var> and <var title="">node</var> is an <a href=#inline-node>inline node</a>, or if
<var title="">node</var> is <a href=#invisible>invisible</a>, set <var title="">offset</var> to one
@@ -7327,9 +7395,9 @@
delete.
<p>Otherwise, if <var title="">node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>
- <var title="">offset</var> 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 not a <a href=#block-node>block node</a> or a
- <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> or an <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code>, set <var title="">node</var> to that <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, then set
- <var title="">offset</var> to zero.
+ <var title="">offset</var> 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 neither a <a href=#block-node>block node</a>
+ nor 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> nor an <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code> nor a <a href=#collapsed-block-prop>collapsed block prop</a>, set
+ <var title="">node</var> to that <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, then set <var title="">offset</var> to zero.
<li>Otherwise, break from this loop.
</ol>
@@ -7338,9 +7406,6 @@
<var title="">node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>:
<ol>
- <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
- <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
-
<li>Let <var title="">end offset</var> be <var title="">offset</var> plus one.
<li>
@@ -7371,9 +7436,13 @@
general category M when interpreted as a Unicode code point, add one to
<var title="">end offset</var>.
- <li><a href=#delete-the-contents>Delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>
- (<var title="">node</var>, <var title="">offset</var>) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> (<var title="">node</var>,
- <var title="">end offset</var>).
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">node</var>, <var title="">end offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>.
<li>Abort these steps.
</ol>
@@ -7381,11 +7450,20 @@
<li>If <var title="">node</var> is an <a href=#inline-node>inline node</a>, abort these steps.
<li>If <var title="">node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">offset</var> 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 a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> or <code class=external data-anolis-spec=html title="the hr element"><a href=http://www.whatwg.org/html/#the-hr-element>hr</a></code> or <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code>, call
- <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
- Then <a href=#delete-the-contents>delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>
- (<var title="">node</var>, <var title="">offset</var>) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> (<var title="">node</var>,
- <var title="">offset</var> + 1) and abort these steps.
+ 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 a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> or <code class=external data-anolis-spec=html title="the hr element"><a href=http://www.whatwg.org/html/#the-hr-element>hr</a></code> or <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code>, but is not a
+ <a href=#collapsed-block-prop>collapsed block prop</a>:
+
+ <ol>
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">node</var>, <var title="">offset</var> + 1)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>.
+
+ <li>Abort these steps.
+ </ol>
<li>
<p class=comments>No special list-item behavior for forwardDelete here,
@@ -7394,6 +7472,10 @@
<p>Let <var title="">end node</var> equal <var title="">node</var> and let <var title="">end
offset</var> equal <var title="">offset</var>.
+ <li>If <var title="">end node</var> has a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">end
+ offset</var>, and 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 a <a href=#collapsed-block-prop>collapsed block prop</a>, add
+ one to <var title="">end offset</var>.
+
<li>Repeat the following steps:
<ol>
@@ -7401,7 +7483,7 @@
<var title="">end offset</var> to one plus the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <var title="">end node</var> and
then set <var title="">end node</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
- <li>Otherwise, if <var title="">end node</var> has a an <a href=#editable>editable</a>
+ <li>Otherwise, if <var title="">end node</var> has an <a href=#editable>editable</a>
<a href=#invisible>invisible</a> <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">end offset</var>,
remove it from <var title="">end node</var>.
@@ -7437,13 +7519,17 @@
<code class=external data-anolis-spec=html title="the hr element"><a href=http://www.whatwg.org/html/#the-hr-element>hr</a></code> or <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>:
<ol>
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">end node</var>, <var title="">end offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">end node</var>, <var title="">end offset</var> + 1)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>.
+
<li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
<code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
- <li><a href=#delete-the-contents>Delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>
- (<var title="">end node</var>, <var title="">end offset</var>) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> (<var title="">end
- node</var>, <var title="">end offset</var> + 1).
-
<li>Abort these steps.
</ol>
@@ -7463,9 +7549,13 @@
<var title="">end offset</var> and set <var title="">end offset</var> to zero.
</ol>
- <li><a href=#delete-the-contents>Delete the contents</a> of the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>
- (<var title="">node</var>, <var title="">offset</var>) and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> (<var title="">end node</var>,
- <var title="">end offset</var>).
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">end node</var>, <var title="">end offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>.
</ol>
@@ -7590,19 +7680,26 @@
<p><a href=#action>Action</a>:
<ol>
- <li>Let <var title="">range</var> be the <a href=#active-range>active range</a>.
-
- <li>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-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-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>, <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>).
-
- <li>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-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-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 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>, 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>).
-
- <li><a href=#delete-the-contents>Delete the contents</a> of <var title="">range</var>, with <var title="">block
- merging</var> false.
+ <li>Let <var title="">start node</var>, <var title="">start offset</var>, <var title="">end node</var>,
+ and <var title="">end offset</var> be the <a href=#active-range>active range</a>'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>
+ and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>nodes</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offsets</a>.
+
+ <li>While <var title="">start offset</var> is 0 and <var title="">start node</var>'s
+ <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is not null, set <var title="">start offset</var> to <var title="">start
+ node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, then set <var title="">start node</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+ <li>While <var title="">end offset</var> is <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, and
+ <var title="">end node</var>'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="">end offset</var> to
+ one plus <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, then set <var title="">end node</var> to its
+ <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">start node</var>, <var title="">start offset</var>)</a></code> on
+ the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-extend><a href=http://html5.org/specs/dom-range.html#dom-selection-extend>extend(<var title="">end node</var>, <var title="">end offset</var>)</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
+
+ <li><a href=#delete-the-selection>Delete the selection</a>, with <var title="">block merging</var> false.
<li>If the <a href=#active-range>active range</a>'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 neither
<a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>, abort these steps.
@@ -7612,19 +7709,22 @@
text node, because that will leave an empty text node.
<p>If the <a href=#active-range>active range</a>'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 a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and
- its <a class=external data-anolis-spec=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 zero, set the <a href=#active-range>active range</a>'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> 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> 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>, <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>).
+ 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> is zero, call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s
+ <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>, with first argument the <a href=#active-range>active range</a>'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>'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> and second argument the <a href=#active-range>active
+ range</a>'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>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>.
<li>If the <a href=#active-range>active range</a>'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 a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node and
- its <a class=external data-anolis-spec=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>, set the
- <a href=#active-range>active range</a>'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> 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> 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>).
+ 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> 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>, call
+ <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>, with first
+ argument the <a href=#active-range>active range</a>'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>'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>, and the
+ second argument one plus the <a href=#active-range>active range</a>'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>'s
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>.
<li>Let <var title="">hr</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("hr")</a></code> on the
<a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.
- <li>Run <code class=external data-anolis-spec=domrange title=dom-Range-insertNode><a href=http://html5.org/specs/dom-range.html#dom-range-insertnode>insertNode(<var title="">hr</var>)</a></code> on <var title="">range</var>.
+ <li>Run <code class=external data-anolis-spec=domrange title=dom-Range-insertNode><a href=http://html5.org/specs/dom-range.html#dom-range-insertnode>insertNode(<var title="">hr</var>)</a></code> on the <a href=#active-range>active range</a>.
<li>
<p class=comments>IE9 and Chrome 13 dev seem to never break up any ancestors,
@@ -7637,12 +7737,9 @@
<p><a href=#fix-disallowed-ancestors>Fix disallowed ancestors</a> of <var title="">hr</var>.
- <li>Let <var title="">selection</var> be the result of running <code class=external data-anolis-spec=domrange title=dom-Document-getSelection><a href=http://html5.org/specs/dom-range.html#dom-document-getselection>getSelection()</a></code> on the
- <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.
-
- <li>Run <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse()</a></code> on <var title="">selection</var>, with first argument equal
- to 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="">hr</var> and the second argument equal to one plus
- the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of <var title="">hr</var>.
+ <li>Run <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>, with first
+ argument <var title="">hr</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> and the second argument equal to one plus
+ <var title="">hr</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>.
</ol>
@@ -7697,7 +7794,7 @@
true.
</div>
- <p><a href=#delete-the-contents>Delete the contents</a> of the <a href=#active-range>active range</a>.
+ <p><a href=#delete-the-selection>Delete the selection</a>.
<li>If the <a href=#active-range>active range</a>'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 neither
<a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>, abort these steps.
@@ -7800,8 +7897,6 @@
<p>If <var title="">value</var> is the empty string, abort these steps and do
nothing.
- <li>Let <var title="">range</var> be the <a href=#active-range>active range</a>.
-
<li>
<p class=comments>Firefox 7.0a2 seems to strip the wrapper or not depending
on the exact positioning of the selection: <b>{foo}</b> yes,
@@ -7811,8 +7906,9 @@
the board because they might be meaningful: e.g., a background-color when the
image is small or not fully opaque.
- <p><a href=#delete-the-contents>Delete the contents</a> of <var title="">range</var>, with <var title="">strip
- wrappers</var> false.
+ <p><a href=#delete-the-selection>Delete the selection</a>, with <var title="">strip wrappers</var> false.
+
+ <li>Let <var title="">range</var> be the <a href=#active-range>active range</a>.
<li>If the <a href=#active-range>active range</a>'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 neither
<a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>, abort these steps.
@@ -7882,8 +7978,7 @@
endpoints. Chrome 14 dev strips wrappers but recreates any styles using new
wrappers. Opera 11.50 strips all wrappers.
- <p><a href=#delete-the-contents>Delete the contents</a> of the <a href=#active-range>active range</a>, with
- <var title="">strip wrappers</var> false.
+ <p><a href=#delete-the-selection>Delete the selection</a>, with <var title="">strip wrappers</var> false.
<li>If the <a href=#active-range>active range</a>'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 neither
<a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>, abort these steps.
@@ -8011,7 +8106,7 @@
<p><a href=#action>Action</a>:
<ol>
- <li><a href=#delete-the-contents>Delete the contents</a> of the <a href=#active-range>active range</a>.
+ <li><a href=#delete-the-selection>Delete the selection</a>.
<li>If the <a href=#active-range>active range</a>'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 neither
<a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>, abort these steps.
@@ -8416,8 +8511,7 @@
deletion at all). This behavior seems to closely match IE9.
</div>
- <p><a href=#delete-the-contents>Delete the contents</a> of the <a href=#active-range>active range</a>, with
- <var title="">strip wrappers</var> false.
+ <p><a href=#delete-the-selection>Delete the selection</a>, with <var title="">strip wrappers</var> false.
<li>If the <a href=#active-range>active range</a>'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 neither
<a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>, abort these steps.
@@ -8815,11 +8909,11 @@
<p class=comments>See comment for <a href=#the-copy-command>copy</a>.
-<p><a href=#action>Action</a>: The user agent must either <a href=#delete-the-contents>delete the
-contents</a> of the <a href=#active-range>active range</a> and then paste the clipboard's
-contents to the current cursor position, as though the user had requested it,
-or raise a <code class=external data-anolis-spec=domcore title=dom-DOMException-SECURITY_ERR><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-security_err>SECURITY_ERR</a></code> exception. This specification does not define
-exactly how the clipboard is to be converted to HTML for pasting, but the <a href=http://dev.w3.org/2006/webapi/clipops/clipops.html>Clipboard API and
+<p><a href=#action>Action</a>: The user agent must either <a href=#delete-the-selection>delete the
+selection</a> and then paste the clipboard's contents to the current cursor
+position, as though the user had requested it, or raise a <code class=external data-anolis-spec=domcore title=dom-DOMException-SECURITY_ERR><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-security_err>SECURITY_ERR</a></code>
+exception. This specification does not define exactly how the clipboard is to
+be converted to HTML for pasting, but the <a href=http://dev.w3.org/2006/webapi/clipops/clipops.html>Clipboard API and
events</a> specification might be useful.
<p>User agents should exercise caution in respecting this command,
--- a/implementation.js Mon Aug 29 14:42:53 2011 -0600
+++ b/implementation.js Tue Aug 30 13:52:24 2011 -0600
@@ -1185,6 +1185,9 @@
///// Assorted common algorithms /////
//@{
+// Magic array of extra ranges whose endpoints we want to preserve.
+var extraRanges = [];
+
function movePreservingRanges(node, newParent, newIndex) {
// For convenience, I allow newIndex to be -1 to mean "insert at the end".
if (newIndex == -1) {
@@ -1202,10 +1205,10 @@
var oldParent = node.parentNode;
var oldIndex = getNodeIndex(node);
- // We only even attempt to preserve the global range object and the ranges
- // in the selection, not every range out there (the latter is probably
- // impossible).
- var ranges = [globalRange];
+ // We preserve the global range object, the ranges in the selection, and
+ // any range that's in the extraRanges array. Any other ranges won't get
+ // updated, because we have no references to them.
+ var ranges = [globalRange].concat(extraRanges);
for (var i = 0; i < getSelection().rangeCount; i++) {
ranges.push(getSelection().getRangeAt(i));
}
@@ -1256,8 +1259,13 @@
globalRange.setStart(boundaryPoints[0][0], boundaryPoints[0][1]);
globalRange.setEnd(boundaryPoints[1][0], boundaryPoints[1][1]);
+ for (var i = 0; i < extraRanges.length; i++) {
+ extraRanges[i].setStart(boundaryPoints[2*i + 2][0], boundaryPoints[2*i + 2][1]);
+ extraRanges[i].setEnd(boundaryPoints[2*i + 3][0], boundaryPoints[2*i + 3][1]);
+ }
+
getSelection().removeAllRanges();
- for (var i = 1; i < ranges.length; i++) {
+ for (var i = 1 + extraRanges.length; i < ranges.length; i++) {
var newRange = document.createRange();
newRange.setStart(boundaryPoints[2*i][0], boundaryPoints[2*i][1]);
newRange.setEnd(boundaryPoints[2*i + 1][0], boundaryPoints[2*i + 1][1]);
@@ -1350,10 +1358,17 @@
ref = previousNode(ref);
}
- // "If ref is an editable extraneous line break, remove it from its
- // parent."
+ // "If ref is an editable extraneous line break:"
if (isEditable(ref)
&& isExtraneousLineBreak(ref)) {
+ // "While ref's parent is editable and invisible, set ref to its
+ // parent."
+ while (isEditable(ref.parentNode)
+ && isInvisible(ref.parentNode)) {
+ ref = ref.parentNode;
+ }
+
+ // "Remove ref from its parent."
ref.parentNode.removeChild(ref);
}
}
@@ -4341,54 +4356,31 @@
}
//@}
-///// Deleting the contents of a range /////
+///// Deleting the selection /////
//@{
-function deleteContents() {
- // We accept several different calling conventions:
- //
- // 1) A single argument, which is a range.
- //
- // 2) Two arguments, the first being a range and the second flags.
- //
- // 3) Four arguments, the start and end of a range.
- //
- // 4) Five arguments, the start and end of a range plus flags.
- //
- // The flags argument is a dictionary that can have up to two keys,
- // blockMerging and stripWrappers, whose corresponding values are
- // interpreted as boolean. E.g., {stripWrappers: false}.
- var range;
- var flags = {};
-
- if (arguments.length < 3) {
- range = arguments[0];
- } else {
- range = document.createRange();
- range.setStart(arguments[0], arguments[1]);
- range.setEnd(arguments[2], arguments[3]);
- }
- if (arguments.length == 2) {
- flags = arguments[1];
- }
- if (arguments.length == 5) {
- flags = arguments[4];
- }
-
- var blockMerging = "blockMerging" in flags ? !!flags.blockMerging : true;
- var stripWrappers = "stripWrappers" in flags ? !!flags.stripWrappers : true;
-
- // "If range is null, abort these steps and do nothing."
- if (!range) {
+// The flags argument is a dictionary that can have blockMerging,
+// stripWrappers, and/or direction as keys.
+function deleteSelection(flags) {
+ if (flags === undefined) {
+ flags = {};
+ }
+
+ var blockMerging = "blockMerging" in flags ? Boolean(flags.blockMerging) : true;
+ var stripWrappers = "stripWrappers" in flags ? Boolean(flags.stripWrappers) : true;
+ var direction = "direction" in flags ? flags.direction : "forward";
+
+ // "If the active range is null, abort these steps and do nothing."
+ if (!getActiveRange()) {
return;
}
- // "Let start node, start offset, end node, and end offset be range's start
- // and end nodes and offsets."
- var startNode = range.startContainer;
- var startOffset = range.startOffset;
- var endNode = range.endContainer;
- var endOffset = range.endOffset;
+ // "Let start node, start offset, end node, and end offset be the active
+ // range's start and end nodes and offsets."
+ var startNode = getActiveRange().startContainer;
+ var startOffset = getActiveRange().startOffset;
+ var endNode = getActiveRange().endContainer;
+ var endOffset = getActiveRange().endOffset;
// "While start node has at least one child:"
while (startNode.hasChildNodes()) {
@@ -4467,10 +4459,21 @@
endOffset = getNodeLength(referenceNode);
}
- // "If (end node, end offset) is not after (start node, start offset), set
- // range's end to its start and abort these steps."
+ // "If (end node, end offset) is not after (start node, start offset):"
if (getPosition(endNode, endOffset, startNode, startOffset) !== "after") {
- range.setEnd(range.startContainer, range.startOffset);
+ // "If direction is "forward", call collapseToStart() on the context
+ // object's Selection."
+ if (direction == "forward") {
+ getSelection().collapseToStart();
+ getActiveRange().collapse(true);
+
+ // "Otherwise, call collapseToEnd() on the context object's Selection."
+ } else {
+ getSelection().collapseToEnd();
+ getActiveRange().collapse(false);
+ }
+
+ // "Abort these steps."
return;
}
@@ -4490,13 +4493,17 @@
endNode = endNode.parentNode;
}
- // "Set range's start to (start node, start offset) and its end to (end
- // node, end offset)."
- range.setStart(startNode, startOffset);
- range.setEnd(endNode, endOffset);
-
- // "Let start block be the start node of range."
- var startBlock = range.startContainer;
+ // "Call collapse(start node, start offset) on the context object's
+ // Selection."
+ getSelection().collapse(startNode, startOffset);
+ getActiveRange().setStart(startNode, startOffset);
+
+ // "Call extend(end node, end offset) on the context object's Selection."
+ getSelection().extend(endNode, endOffset);
+ getActiveRange().setEnd(endNode, endOffset);
+
+ // "Let start block be the active range's start node."
+ var startBlock = getActiveRange().startContainer;
// "While start block's parent is in the same editing host and start block
// is an inline node, set start block to its parent."
@@ -4514,8 +4521,8 @@
startBlock = null;
}
- // "Let end block be the end node of range."
- var endBlock = range.endContainer;
+ // "Let end block be the active range's end node."
+ var endBlock = getActiveRange().endContainer;
// "While end block's parent is in the same editing host and end block is
// an inline node, set end block to its parent."
@@ -4548,8 +4555,22 @@
// "Canonicalize whitespace at (start node, start offset)."
canonicalizeWhitespace(startNode, startOffset);
- // "Set range's end to its start."
- range.setEnd(range.startContainer, range.startOffset);
+ // "If direction is "forward", call collapseToStart() on the context
+ // object's Selection."
+ //
+ // Work around WebKit bug where the selection might have no ranges, by
+ // checking rangeCount.
+ if (direction == "forward") {
+ if (getSelection().rangeCount) {
+ getSelection().collapseToStart();
+ }
+ getActiveRange().collapse(true);
+
+ // "Otherwise, call collapseToEnd() on the context object's Selection."
+ } else {
+ getSelection().collapseToEnd();
+ getActiveRange().collapse(false);
+ }
// "Restore states and values from overrides."
restoreStatesAndValues(overrides);
@@ -4568,10 +4589,10 @@
// "Let node list be a list of nodes, initially empty."
//
- // "For each node contained in range, append node to node list if the last
- // member of node list (if any) is not an ancestor of node; node is
- // editable; and node is not a thead, tbody, tfoot, tr, th, or td."
- var nodeList = getContainedNodes(range,
+ // "For each node contained in the active range, append node to node list
+ // if the last member of node list (if any) is not an ancestor of node;
+ // node is editable; and node is not a thead, tbody, tfoot, tr, th, or td."
+ var nodeList = getContainedNodes(getActiveRange(),
function(node) {
return isEditable(node)
&& !isHtmlElement(node, ["thead", "tbody", "tfoot", "tr", "th", "td"]);
@@ -4620,11 +4641,11 @@
endNode.deleteData(0, endOffset);
}
- // "Canonicalize whitespace at range's start."
- canonicalizeWhitespace(range.startContainer, range.startOffset);
-
- // "Canonicalize whitespace at range's end."
- canonicalizeWhitespace(range.endContainer, range.endOffset);
+ // "Canonicalize whitespace at the active range's start."
+ canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset);
+
+ // "Canonicalize whitespace at the active range's end."
+ canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset);
// "If block merging is false, or start block or end block is null, or
// start block is not in the same editing host as end block, or start block
@@ -4634,8 +4655,23 @@
|| !endBlock
|| !inSameEditingHost(startBlock, endBlock)
|| startBlock == endBlock) {
- // "Set range's end to its start."
- range.setEnd(range.startContainer, range.startOffset);
+ // "If direction is "forward", call collapseToStart() on the context
+ // object's Selection."
+ if (direction == "forward") {
+ // Work around WebKit bug: sometimes it will remove the selection's
+ // range.
+ if (getSelection().rangeCount) {
+ getSelection().collapseToStart();
+ }
+ getActiveRange().collapse(true);
+
+ // "Otherwise, call collapseToEnd() on the context object's Selection."
+ } else {
+ if (getSelection().rangeCount) {
+ getSelection().collapseToEnd();
+ }
+ getActiveRange().collapse(false);
+ }
// "Restore states and values from overrides."
restoreStatesAndValues(overrides);
@@ -4651,13 +4687,6 @@
startBlock.removeChild(startBlock.firstChild);
}
- // "If end block has one child, which is a collapsed block prop, remove its
- // child from it."
- if (endBlock.children.length == 1
- && isCollapsedBlockProp(endBlock.firstChild)) {
- endBlock.removeChild(endBlock.firstChild);
- }
-
// "If start block is an ancestor of end block:"
if (isAncestor(startBlock, endBlock)) {
// "Let reference node be end block."
@@ -4669,10 +4698,12 @@
referenceNode = referenceNode.parentNode;
}
- // "Set the start and end of range to (start block, index of reference
- // node)."
- range.setStart(startBlock, getNodeIndex(referenceNode));
- range.setEnd(startBlock, getNodeIndex(referenceNode));
+ // "Call collapse() on the context object's Selection, with first
+ // argument start block and second argument the index of reference
+ // node."
+ getSelection().collapse(startBlock, getNodeIndex(referenceNode));
+ getActiveRange().setStart(startBlock, getNodeIndex(referenceNode));
+ getActiveRange().collapse(true);
// "If end block has no children:"
if (!endBlock.hasChildNodes()) {
@@ -4750,10 +4781,11 @@
// "Otherwise, if start block is a descendant of end block:"
} else if (isDescendant(startBlock, endBlock)) {
- // "Set the start and end of range to (start block, length of start
- // block)."
- range.setStart(startBlock, getNodeLength(startBlock));
- range.setEnd(startBlock, getNodeLength(startBlock));
+ // "Call collapse() on the context object's Selection, with first
+ // argument start block and second argument start block's length."
+ getSelection().collapse(startBlock, getNodeLength(startBlock));
+ getActiveRange().setStart(startBlock, getNodeLength(startBlock));
+ getActiveRange().collapse(true);
// "Let reference node be start block."
var referenceNode = startBlock;
@@ -4774,20 +4806,19 @@
// "Let nodes to move be a list of nodes, initially empty."
var nodesToMove = [];
- // "If reference node's nextSibling is neither null nor a br nor a
- // block node, append it to nodes to move."
+ // "If reference node's nextSibling is neither null nor a block node,
+ // append it to nodes to move."
if (referenceNode.nextSibling
- && !isHtmlElement(referenceNode.nextSibling, "br")
&& !isBlockNode(referenceNode.nextSibling)) {
nodesToMove.push(referenceNode.nextSibling);
}
- // "While nodes to move is nonempty and its last member's nextSibling
- // is neither null nor a br nor a block node, append it to nodes to
- // move."
+ // "While nodes to move is nonempty and its last member isn't a br and
+ // its last member's nextSibling is neither null nor a block node,
+ // append its last member's nextSibling to nodes to move."
if (nodesToMove.length
+ && !isHtmlElement(nodesToMove[nodesToMove.length - 1], "br")
&& nodesToMove[nodesToMove.length - 1].nextSibling
- && !isHtmlElement(nodesToMove[nodesToMove.length - 1].nextSibling, "br")
&& !isBlockNode(nodesToMove[nodesToMove.length - 1].nextSibling)) {
nodesToMove.push(nodesToMove[nodesToMove.length - 1].nextSibling);
}
@@ -4801,18 +4832,13 @@
movePreservingRanges(node, startBlock, -1);
});
- // "If the nextSibling of reference node is a br, remove it from its
- // parent."
- if (isHtmlElement(referenceNode.nextSibling, "br")) {
- referenceNode.parentNode.removeChild(referenceNode.nextSibling);
- }
-
// "Otherwise:"
} else {
- // "Set the start and end of range to (start block, length of start
- // block)."
- range.setStart(startBlock, getNodeLength(startBlock));
- range.setEnd(startBlock, getNodeLength(startBlock));
+ // "Call collapse() on the context object's Selection, with first
+ // argument start block and second argument start block's length."
+ getSelection().collapse(startBlock, getNodeLength(startBlock));
+ getActiveRange().setStart(startBlock, getNodeLength(startBlock));
+ getActiveRange().collapse(true);
// "If end block's firstChild is an inline node and start block's
// lastChild is a br, remove start block's lastChild from it."
@@ -4850,6 +4876,9 @@
startBlock.appendChild(document.createElement("br"));
}
+ // "Remove extraneous line breaks at the end of start block."
+ removeExtraneousLineBreaksAtTheEndOf(startBlock);
+
// "Restore states and values from overrides."
restoreStatesAndValues(overrides);
}
@@ -5834,10 +5863,10 @@
//@{
commands["delete"] = {
action: function() {
- // "If the active range is not collapsed, delete the contents of the
- // active range and abort these steps."
+ // "If the active range is not collapsed, delete the selection and
+ // abort these steps."
if (!getActiveRange().collapsed) {
- deleteContents(getActiveRange());
+ deleteSelection();
return;
}
@@ -5903,15 +5932,28 @@
}
}
- // "If node is a Text node and offset is not zero, call collapse(node,
- // offset) on the Selection. Then delete the contents of the range with
- // start (node, offset − 1) and end (node, offset) and abort these
- // steps."
- if (node.nodeType == Node.TEXT_NODE
- && offset != 0) {
- getActiveRange().setStart(node, offset);
+ // "If node is a Text node and offset is not zero, or if node is a
+ // block node that has a child with index offset − 1 and that child is
+ // a br or hr or img:"
+ if ((node.nodeType == Node.TEXT_NODE
+ && offset != 0)
+ || (isBlockNode(node)
+ && 0 <= offset - 1
+ && offset - 1 < node.childNodes.length
+ && isHtmlElement(node.childNodes[offset - 1], ["br", "hr", "img"]))) {
+ // "Call collapse(node, offset) on the context object's Selection."
+ getSelection().collapse(node, offset);
getActiveRange().setEnd(node, offset);
- deleteContents(node, offset - 1, node, offset);
+
+ // "Call extend(node, offset − 1) on the context object's
+ // Selection."
+ getSelection().extend(node, offset - 1);
+ getActiveRange().setStart(node, offset - 1);
+
+ // "Delete the selection."
+ deleteSelection();
+
+ // "Abort these steps."
return;
}
@@ -5920,19 +5962,6 @@
return;
}
- // "If node has a child with index offset − 1 and that child is a br or
- // hr or img, call collapse(node, offset) on the Selection. Then delete
- // the contents of the range with start (node, offset − 1) and end
- // (node, offset) and abort these steps."
- if (0 <= offset - 1
- && offset - 1 < node.childNodes.length
- && isHtmlElement(node.childNodes[offset - 1], ["br", "hr", "img"])) {
- getActiveRange().setStart(node, offset);
- getActiveRange().setEnd(node, offset);
- deleteContents(node, offset - 1, node, offset);
- return;
- }
-
// "If node is an li or dt or dd and is the first child of its parent,
// and offset is zero:"
if (isHtmlElement(node, ["li", "dt", "dd"])
@@ -6057,10 +6086,12 @@
&& isHtmlElement(startNode.childNodes[startOffset - 1], "table")) {
// "Call collapse(start node, start offset − 1) on the context
// object's Selection."
+ getSelection().collapse(startNode, startOffset - 1);
getActiveRange().setStart(startNode, startOffset - 1);
// "Call extend(start node, start offset) on the context object's
// Selection."
+ getSelection().extend(startNode, startOffset);
getActiveRange().setEnd(startNode, startOffset);
// "Abort these steps."
@@ -6080,13 +6111,23 @@
)
)
)) {
+ // "Call collapse(start node, start offset − 1) on the context
+ // object's Selection."
+ getSelection().collapse(startNode, startOffset - 1);
+ getActiveRange().setStart(startNode, startOffset - 1);
+
+ // "Call extend(start node, start offset) on the context object's
+ // Selection."
+ getSelection().extend(startNode, startOffset);
+ getActiveRange().setEnd(startNode, startOffset);
+
+ // "Delete the selection."
+ deleteSelection();
+
// "Call collapse(node, offset) on the Selection."
+ getSelection().collapse(node, offset);
getActiveRange().setStart(node, offset);
- getActiveRange().setEnd(node, offset);
-
- // "Delete the contents of the range with start (start node, start
- // offset − 1) and end (start node, start offset)."
- deleteContents(startNode, startOffset - 1, startNode, startOffset);
+ getActiveRange().collapse(true);
// "Abort these steps."
return;
@@ -6118,44 +6159,83 @@
}
}
- // "If the child of start node with index start offset is an li or dt
- // or dd, and its previousSibling is also an li or dt or dd, set start
- // node to its child with index start offset − 1, then set start offset
- // to start node's length, then set node to start node's nextSibling,
- // then set offset to 0."
+ // "If start node's child with index start offset is an li or dt or dd,
+ // and that child's previousSibling is also an li or dt or dd:"
if (isHtmlElement(startNode.childNodes[startOffset], ["li", "dt", "dd"])
- && isHtmlElement(startNode.childNodes[startOffset - 1], ["li", "dt", "dd"])) {
+ && isHtmlElement(startNode.childNodes[startOffset].previousSibling, ["li", "dt", "dd"])) {
+ // "Call cloneRange() on the active range, and let original range
+ // be the result."
+ //
+ // We need to add it to extraRanges so it will actually get updated
+ // when moving preserving ranges.
+ var originalRange = getActiveRange().cloneRange();
+ extraRanges.push(originalRange);
+
+ // "Set start node to its child with index start offset − 1."
startNode = startNode.childNodes[startOffset - 1];
+
+ // "Set start offset to start node's length."
startOffset = getNodeLength(startNode);
+
+ // "Set node to start node's nextSibling."
node = startNode.nextSibling;
- offset = 0;
-
- // "Otherwise, while start node has a child with index start offset
- // minus one:"
- } else {
- while (0 <= startOffset - 1
- && startOffset - 1 < startNode.childNodes.length) {
- // "If start node's child with index start offset minus one is
- // editable and invisible, remove it from start node, then
- // subtract one from start offset."
- if (isEditable(startNode.childNodes[startOffset - 1])
- && isInvisible(startNode.childNodes[startOffset - 1])) {
- startNode.removeChild(startNode.childNodes[startOffset - 1]);
- startOffset--;
-
- // "Otherwise, set start node to its child with index start
- // offset minus one, then set start offset to the length of
- // start node."
- } else {
- startNode = startNode.childNodes[startOffset - 1];
- startOffset = getNodeLength(startNode);
- }
+
+ // "Call collapse(start node, start offset) on the context object's
+ // Selection."
+ getSelection().collapse(startNode, startOffset);
+ getActiveRange().setStart(startNode, startOffset);
+
+ // "Call extend(node, 0) on the context object's Selection."
+ getSelection().extend(node, 0);
+ getActiveRange().setEnd(node, 0);
+
+ // "Delete the selection."
+ deleteSelection();
+
+ // "Call removeAllRanges() on the context object's Selection."
+ getSelection().removeAllRanges();
+
+ // "Call addRange(original range) on the context object's
+ // Selection."
+ getSelection().addRange(originalRange);
+ getActiveRange().setStart(originalRange.startContainer, originalRange.startOffset);
+ getActiveRange().setEnd(originalRange.endContainer, originalRange.endOffset);
+
+ // "Abort these steps."
+ extraRanges.pop();
+ return;
+ }
+
+ // "While start node has a child with index start offset minus one:"
+ while (0 <= startOffset - 1
+ && startOffset - 1 < startNode.childNodes.length) {
+ // "If start node's child with index start offset minus one is
+ // editable and invisible, remove it from start node, then subtract
+ // one from start offset."
+ if (isEditable(startNode.childNodes[startOffset - 1])
+ && isInvisible(startNode.childNodes[startOffset - 1])) {
+ startNode.removeChild(startNode.childNodes[startOffset - 1]);
+ startOffset--;
+
+ // "Otherwise, set start node to its child with index start offset
+ // minus one, then set start offset to the length of start node."
+ } else {
+ startNode = startNode.childNodes[startOffset - 1];
+ startOffset = getNodeLength(startNode);
}
}
- // "Delete the contents of the range with start (start node, start
- // offset) and end (node, offset)."
- deleteContents(startNode, startOffset, node, offset);
+ // "Call collapse(start node, start offset) on the context object's
+ // Selection."
+ getSelection().collapse(startNode, startOffset);
+ getActiveRange().setStart(startNode, startOffset);
+
+ // "Call extend(node, offset) on the context object's Selection."
+ getSelection().extend(node, offset);
+ getActiveRange().setEnd(node, offset);
+
+ // "Delete the selection, with direction "backward"."
+ deleteSelection({direction: "backward"});
}
};
@@ -6389,10 +6469,10 @@
//@{
commands.forwarddelete = {
action: function() {
- // "If the active range is not collapsed, delete the contents of the
- // active range and abort these steps."
+ // "If the active range is not collapsed, delete the selection and
+ // abort these steps."
if (!getActiveRange().collapsed) {
- deleteContents(getActiveRange());
+ deleteSelection();
return;
}
@@ -6421,12 +6501,6 @@
&& isInvisible(node.childNodes[offset])) {
node.removeChild(node.childNodes[offset]);
- // "Otherwise, if node has a child with index offset and that child
- // is a collapsed block prop, add one to offset."
- } else if (offset < node.childNodes.length
- && isCollapsedBlockProp(node.childNodes[offset])) {
- offset++;
-
// "Otherwise, if offset is the length of node and node is an
// inline node, or if node is invisible, set offset to one plus the
// index of node, then set node to its parent."
@@ -6437,11 +6511,12 @@
node = node.parentNode;
// "Otherwise, if node has a child with index offset and that child
- // is not a block node or a br or an img, set node to that child,
- // then set offset to zero."
+ // is neither a block node nor a br nor an img nor a collapsed
+ // block prop, set node to that child, then set offset to zero."
} else if (offset < node.childNodes.length
&& !isBlockNode(node.childNodes[offset])
- && !isHtmlElement(node.childNodes[offset], ["br", "img"])) {
+ && !isHtmlElement(node.childNodes[offset], ["br", "img"])
+ && !isCollapsedBlockProp(node.childNodes[offset])) {
node = node.childNodes[offset];
offset = 0;
@@ -6454,10 +6529,6 @@
// "If node is a Text node and offset is not node's length:"
if (node.nodeType == Node.TEXT_NODE
&& offset != getNodeLength(node)) {
- // "Call collapse(node, offset) on the Selection."
- getActiveRange().setStart(node, offset);
- getActiveRange().setEnd(node, offset);
-
// "Let end offset be offset plus one."
var endOffset = offset + 1;
@@ -6474,9 +6545,17 @@
endOffset++;
}
- // "Delete the contents of the range with start (node, offset) and
- // end (node, end offset)."
- deleteContents(node, offset, node, endOffset);
+ // "Call collapse(node, offset) on the context object's Selection."
+ getSelection().collapse(node, offset);
+ getActiveRange().setStart(node, offset);
+
+ // "Call extend(node, end offset) on the context object's
+ // Selection."
+ getSelection().extend(node, endOffset);
+ getActiveRange().setEnd(node, endOffset);
+
+ // "Delete the selection."
+ deleteSelection();
// "Abort these steps."
return;
@@ -6488,14 +6567,23 @@
}
// "If node has a child with index offset and that child is a br or hr
- // or img, call collapse(node, offset) on the Selection. Then delete
- // the contents of the range with start (node, offset) and end (node,
- // offset + 1) and abort these steps."
+ // or img, but is not a collapsed block prop:"
if (offset < node.childNodes.length
- && isHtmlElement(node.childNodes[offset], ["br", "hr", "img"])) {
+ && isHtmlElement(node.childNodes[offset], ["br", "hr", "img"])
+ && !isCollapsedBlockProp(node.childNodes[offset])) {
+ // "Call collapse(node, offset) on the context object's Selection."
+ getSelection().collapse(node, offset);
getActiveRange().setStart(node, offset);
- getActiveRange().setEnd(node, offset);
- deleteContents(node, offset, node, offset + 1);
+
+ // "Call extend(node, offset + 1) on the context object's
+ // Selection."
+ getSelection().extend(node, offset + 1);
+ getActiveRange().setEnd(node, offset + 1);
+
+ // "Delete the selection."
+ deleteSelection();
+
+ // "Abort these steps."
return;
}
@@ -6503,6 +6591,13 @@
var endNode = node;
var endOffset = offset;
+ // "If end node has a child with index end offset, and that child is a
+ // collapsed block prop, add one to end offset."
+ if (endOffset < endNode.childNodes.length
+ && isCollapsedBlockProp(endNode.childNodes[endOffset])) {
+ endOffset++;
+ }
+
// "Repeat the following steps:"
while (true) {
// "If end offset is the length of end node, set end offset to one
@@ -6534,10 +6629,12 @@
if (isHtmlElement(endNode.childNodes[endOffset], "table")) {
// "Call collapse(end node, end offset) on the context object's
// Selection."
+ getSelection().collapse(endNode, endOffset);
getActiveRange().setStart(endNode, endOffset);
// "Call extend(end node, end offset + 1) on the context object's
// Selection."
+ getSelection().extend(endNode, endOffset + 1);
getActiveRange().setEnd(endNode, endOffset + 1);
// "Abort these steps."
@@ -6548,13 +6645,23 @@
// index end offset is an hr or br:"
if (offset == getNodeLength(node)
&& isHtmlElement(endNode.childNodes[endOffset], ["br", "hr"])) {
+ // "Call collapse(end node, end offset) on the context object's
+ // Selection."
+ getSelection().collapse(endNode, endOffset);
+ getActiveRange().setStart(endNode, endOffset);
+
+ // "Call extend(end node, end offset + 1) on the context object's
+ // Selection."
+ getSelection().extend(endNode, endOffset + 1);
+ getActiveRange().setEnd(endNode, endOffset + 1);
+
+ // "Delete the selection."
+ deleteSelection();
+
// "Call collapse(node, offset) on the Selection."
+ getSelection().collapse(node, offset);
getActiveRange().setStart(node, offset);
- getActiveRange().setEnd(node, offset);
-
- // "Delete the contents of the range with end (end node, end
- // offset) and end (end node, end offset + 1)."
- deleteContents(endNode, endOffset, endNode, endOffset + 1);
+ getActiveRange().collapse(true);
// "Abort these steps."
return;
@@ -6576,9 +6683,17 @@
}
}
- // "Delete the contents of the range with start (node, offset) and end
- // (end node, end offset)."
- deleteContents(node, offset, endNode, endOffset);
+ // "Call collapse(node, offset) on the context object's Selection."
+ getSelection().collapse(node, offset);
+ getActiveRange().setStart(node, offset);
+
+ // "Call extend(end node, end offset) on the context object's
+ // Selection."
+ getSelection().extend(endNode, endOffset);
+ getActiveRange().setEnd(endNode, endOffset);
+
+ // "Delete the selection."
+ deleteSelection();
}
};
@@ -6665,27 +6780,43 @@
//@{
commands.inserthorizontalrule = {
action: function() {
- // "Let range be the active range."
- var range = getActiveRange();
-
- // "While range's start offset is 0 and its start node's parent is not
- // null, set range's start to (parent of start node, index of start
- // node)."
- while (range.startOffset == 0
- && range.startContainer.parentNode) {
- range.setStart(range.startContainer.parentNode, getNodeIndex(range.startContainer));
- }
-
- // "While range's end offset is the length of its end node, and its end
- // node's parent is not null, set range's end to (parent of end node, 1
- // + index of start node)."
- while (range.endOffset == getNodeLength(range.endContainer)
- && range.endContainer.parentNode) {
- range.setEnd(range.endContainer.parentNode, 1 + getNodeIndex(range.endContainer));
- }
-
- // "Delete the contents of range, with block merging false."
- deleteContents(range, {blockMerging: false});
+ // "Let start node, start offset, end node, and end offset be the
+ // active range's start and end nodes and offsets."
+ var startNode = getActiveRange().startContainer;
+ var startOffset = getActiveRange().startOffset;
+ var endNode = getActiveRange().endContainer;
+ var endOffset = getActiveRange().endOffset;
+
+ // "While start offset is 0 and start node's parent is not null, set
+ // start offset to start node's index, then set start node to its
+ // parent."
+ while (startOffset == 0
+ && startNode.parentNode) {
+ startOffset = getNodeIndex(startNode);
+ startNode = startNode.parentNode;
+ }
+
+ // "While end offset is end node's length, and end node's parent is not
+ // null, set end offset to one plus end node's index, then set end node
+ // to its parent."
+ while (endOffset == getNodeLength(endNode)
+ && endNode.parentNode) {
+ endOffset = 1 + getNodeIndex(endNode);
+ endNode = endNode.parentNode;
+ }
+
+ // "Call collapse(start node, start offset) on the context object's
+ // Selection."
+ getSelection().collapse(startNode, startOffset);
+ getActiveRange().setStart(startNode, startOffset);
+
+ // "Call extend(end node, end offset) on the context object's
+ // Selection."
+ getSelection().extend(endNode, endOffset);
+ getActiveRange().setEnd(endNode, endOffset);
+
+ // "Delete the selection, with block merging false."
+ deleteSelection({blockMerging: false});
// "If the active range's start node is neither editable nor an editing
// host, abort these steps."
@@ -6695,20 +6826,29 @@
}
// "If the active range's start node is a Text node and its start
- // offset is zero, set the active range's start and end to (parent of
- // start node, index of start node)."
+ // offset is zero, call collapse() on the context object's Selection,
+ // with first argument the active range's start node's parent and
+ // second argument the active range's start node's index."
if (getActiveRange().startContainer.nodeType == Node.TEXT_NODE
&& getActiveRange().startOffset == 0) {
- getActiveRange().setStart(getActiveRange().startContainer.parentNode, getNodeIndex(getActiveRange().startContainer));
+ var newNode = getActiveRange().startContainer.parentNode;
+ var newOffset = getNodeIndex(getActiveRange().startContainer);
+ getSelection().collapse(newNode, newOffset);
+ getActiveRange().setStart(newNode, newOffset);
getActiveRange().collapse(true);
}
// "If the active range's start node is a Text node and its start
- // offset is the length of its start node, set the active range's start
- // and end to (parent of start node, 1 + index of start node)."
+ // offset is the length of its start node, call collapse() on the
+ // context object's Selection, with first argument the active range's
+ // start node's parent, and the second argument one plus the active
+ // range's start node's index."
if (getActiveRange().startContainer.nodeType == Node.TEXT_NODE
&& getActiveRange().startOffset == getNodeLength(getActiveRange().startContainer)) {
- getActiveRange().setStart(getActiveRange().startContainer.parentNode, 1 + getNodeIndex(getActiveRange().startContainer));
+ var newNode = getActiveRange().startContainer.parentNode;
+ var newOffset = 1 + getNodeIndex(getActiveRange().startContainer);
+ getSelection().collapse(newNode, newOffset);
+ getActiveRange().setStart(newNode, newOffset);
getActiveRange().collapse(true);
}
@@ -6716,23 +6856,18 @@
// context object."
var hr = document.createElement("hr");
- // "Run insertNode(hr) on the range."
- range.insertNode(hr);
+ // "Run insertNode(hr) on the active range."
+ getActiveRange().insertNode(hr);
// "Fix disallowed ancestors of hr."
fixDisallowedAncestors(hr);
- // "Run collapse() on the Selection, with first argument equal to the
- // parent of hr and the second argument equal to one plus the index of
- // hr."
- //
- // Not everyone actually supports collapse(), so we do it manually
- // instead. Also, we need to modify the actual range we're given as
- // well, for the sake of autoimplementation.html's range-filling-in.
- range.setStart(hr.parentNode, 1 + getNodeIndex(hr));
- range.setEnd(hr.parentNode, 1 + getNodeIndex(hr));
- getSelection().removeAllRanges();
- getSelection().addRange(range);
+ // "Run collapse() on the context object's Selection, with first
+ // argument hr's parent and the second argument equal to one plus hr's
+ // index."
+ getSelection().collapse(hr.parentNode, 1 + getNodeIndex(hr));
+ getActiveRange().setStart(hr.parentNode, 1 + getNodeIndex(hr));
+ getActiveRange().collapse(true);
}
};
@@ -6741,8 +6876,8 @@
//@{
commands.inserthtml = {
action: function(value) {
- // "Delete the contents of the active range."
- deleteContents(getActiveRange());
+ // "Delete the selection."
+ deleteSelection();
// "If the active range's start node is neither editable nor an editing
// host, abort these steps."
@@ -6817,12 +6952,12 @@
return;
}
+ // "Delete the selection, with strip wrappers false."
+ deleteSelection({stripWrappers: false});
+
// "Let range be the active range."
var range = getActiveRange();
- // "Delete the contents of range, with strip wrappers false."
- deleteContents(range, {stripWrappers: false});
-
// "If the active range's start node is neither editable nor an editing
// host, abort these steps."
if (!isEditable(getActiveRange().startContainer)
@@ -6873,8 +7008,8 @@
//@{
commands.insertlinebreak = {
action: function(value) {
- // "Delete the contents of the active range, with strip wrappers false."
- deleteContents(getActiveRange(), {stripWrappers: false});
+ // "Delete the selection, with strip wrappers false."
+ deleteSelection({stripWrappers: false});
// "If the active range's start node is neither editable nor an editing
// host, abort these steps."
@@ -6971,8 +7106,8 @@
//@{
commands.insertparagraph = {
action: function() {
- // "Delete the contents of the active range."
- deleteContents(getActiveRange());
+ // "Delete the selection."
+ deleteSelection();
// "If the active range's start node is neither editable nor an editing
// host, abort these steps."
@@ -7276,9 +7411,8 @@
//@{
commands.inserttext = {
action: function(value) {
- // "Delete the contents of the active range, with strip wrappers
- // false."
- deleteContents(getActiveRange(), {stripWrappers: false});
+ // "Delete the selection, with strip wrappers false."
+ deleteSelection({stripWrappers: false});
// "If the active range's start node is neither editable nor an editing
// host, abort these steps."
--- a/preprocess Mon Aug 29 14:42:53 2011 -0600
+++ b/preprocess Tue Aug 30 13:52:24 2011 -0600
@@ -26,8 +26,10 @@
'cdlength': '<code data-anolis-spec=domcore title=dom-CharacterData-length>length</code>',
'child': '<span data-anolis-spec=domcore title=concept-tree-child>child</span>',
'children': '<span data-anolis-spec=domcore title=concept-tree-child>children</span>',
+ 'clonerange': '<code data-anolis-spec=domrange title=dom-Range-cloneRange>cloneRange()</code>',
'codeunit': '<a href=http://dev.w3.org/2006/webapi/WebIDL/#dfn-code-unit>code unit</a>',
'collapsetoend': '<code data-anolis-spec=domrange title=dom-Selection-collapseToEnd>collapseToEnd()</code>',
+ 'collapsetostart': '<code data-anolis-spec=domrange title=dom-Selection-collapseToStart>collapseToStart()</code>',
'collection': '<span data-anolis-spec=domcore title=concept-collection>collection</span>',
'contained': '<span data-anolis-spec=domrange>contained</span>',
'comment': '<code data-anolis-spec=domcore>Comment</code>',
@@ -132,6 +134,7 @@
s = s.replace("[[" + key.capitalize() + "]]", capreplace)
fnreplace = {
+ 'addrange': '<code data-anolis-spec=domrange title=dom-Selection-addRange>addRange(\\1)</code>',
'appendchild': '<code data-anolis-spec=domcore title=dom-Node-appendChild>appendChild(\\1)</code>',
'createelement': '<code data-anolis-spec=domcore title=dom-Document-createElement>createElement(\\1)</code>',
'deletedata': '<code data-anolis-spec=domcore title=dom-CharacterData-deleteData>deleteData(\\1)</code>',
--- a/source.html Mon Aug 29 14:42:53 2011 -0600
+++ b/source.html Tue Aug 30 13:52:24 2011 -0600
@@ -1269,7 +1269,18 @@
[[treeorder]].
<li>If <var>ref</var> is an <span>editable</span> <span>extraneous line
- break</span>, remove it from its [[parent]].
+ break</span>:
+
+ <ol>
+ <li>
+ <p class=comments>If the block ends with {{code|<span><br></span>}}, for
+ instance, we want to remove the span too.
+
+ <p>While <var>ref</var>'s [[parent]] is <span>editable</span> and
+ <span>invisible</span>, set <var>ref</var> to its [[parent]].
+
+ <li>Remove <var>ref</var> from its [[parent]].
+ </ol>
</ol>
<p>To <dfn>remove extraneous line breaks from</dfn> a [[node]], first
@@ -4432,35 +4443,33 @@
</ol>
<!--@}-->
-<h3>Deleting the contents of a range</h3>
+<h3>Deleting the selection</h3>
<!-- @{ -->
<p class=comments>TODO: Consider what should happen for block merging in corner
cases like display: inline-table.
-<p>To <dfn>delete the contents</dfn> of a [[range]] <var>range</var>, given a
-<var>block merging</var> flag that defaults to true and a <var>strip
-wrappers</var> flag that defaults to true:
+<p>To <dfn>delete the selection</dfn>, given a <var>block merging</var> flag
+that defaults to true, a <var>strip wrappers</var> flag that defaults to
+true, and a string <var>direction</var> that defaults to "forward":
<div class=note>
<p>The idea behind this algorithm is self-explanatory, but the details wind up
being remarkably complicated.
-<p>First, any editable nodes inside the range will be deleted, and the range
-will be collapsed. By way of contrast, <span>effectively contained</span>
-tries to expand the range to include as much as possible, so <code
-title><p>[foo]</p></code> contains the <code title><p></code>. What
-we do here is contract the range to include as little as possible, so <code
-title>{<p>foo</p>}</code> contains only <code title>foo</code> and
-doesn't delete the paragraph.
-
-<p>After that, if the range originally started and ended in different blocks,
-and the <var>block merging</var> flag is true, the end block will get merged
-into the start block. This is needed so if the user selects text on several
-lines and deletes it, the text immediately that was before the selection winds
-up on the same line as the text immediately after it. For example, <code
-title><p>fo[o</p><div>b]ar</div></code> becomes <code
-title><p>fo[]ar</p></code>. This procedure winds up being tricky, and
-takes up a large chunk of the logic.
+<p>First, any editable nodes inside the selection will be deleted, and the
+selection will be collapsed. By way of contrast, <span>effectively
+contained</span> tries to expand the range to include as much as possible, so
+{{code|<p>[foo]</p>}} contains the {{code|<p>}}. What we do here is contract
+the range to include as little as possible, so {{code|{<p>foo</p>} }} contains
+only {{code|foo}} and doesn't delete the paragraph.
+
+<p>After that, if the selection originally started and ended in different
+blocks, and the <var>block merging</var> flag is true, the end block will get
+merged into the start block. This is needed so if the user selects text on
+several lines and deletes it, the text immediately that was before the
+selection winds up on the same line as the text immediately after it. For
+example, {{code|<p>fo[o</p><div>b]ar</div>}} becomes {{code|<p>fo[]ar</p>}}.
+This procedure winds up being tricky, and takes up a large chunk of the logic.
<p>Tables are a notable special case. If an entire table is contained in the
range, it will be deleted. If it's anything less, only the contents of the
@@ -4482,11 +4491,12 @@
</div>
<ol>
- <li>If <var>range</var> is null, abort these steps and do nothing.
+ <li>If the <span>active range</span> is null, abort these steps and do
+ nothing.
<li>Let <var>start node</var>, <var>start offset</var>, <var>end node</var>,
- and <var>end offset</var> be <var>range</var>'s [[rangestart]] and
- [[rangeend]] [[bpnodes]] and [[bpoffsets]].
+ and <var>end offset</var> be the <span>active range</span>'s [[rangestart]]
+ and [[rangeend]] [[bpnodes]] and [[bpoffsets]].
<li>
<div class=comments>
@@ -4502,7 +4512,7 @@
-> foo<br />{bar]
-> foo<br />[bar]</pre>
- <p>and we deselected the <br>.
+ <p>and we deselected the {{code|<br>}}.
</div>
<p>While <var>start node</var> has at least one [[child]]:
@@ -4516,7 +4526,7 @@
-> <b>foo{</b><i>bar]</i>
-> <b>foo</b>{<i>bar]</i></pre>
- <p>Then the next step will make it <b>foo</b><i>[bar]</i>.
+ <p>Then the next step will make it {{code|<b>foo</b><i>[bar]</i>}}.
<p>We don't want to do this for block nodes, because that would lead to
something like
@@ -4524,7 +4534,7 @@
<pre><p>foo[</p><p>]bar<p></pre>
<p>ultimately collapsing, which is wrong. Once we do the deletion, it
- needs to wind up <p>foo[]bar</p>, whereas an actually collapsed
+ needs to wind up {{code|<p>foo[]bar</p>}}, whereas an actually collapsed
selection should do nothing.
</div>
@@ -4589,8 +4599,17 @@
</ol>
<li>If (<var>end node</var>, <var>end offset</var>) is not [[bpafter]]
- (<var>start node</var>, <var>start offset</var>), set <var>range</var>'s
- [[rangeend]] to its [[rangestart]] and abort these steps.
+ (<var>start node</var>, <var>start offset</var>):
+
+ <ol>
+ <li>If <var>direction</var> is "forward", call [[collapsetostart]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Otherwise, call [[collapsetoend]] on the [[contextobject]]'s
+ [[selection]].
+
+ <li>Abort these steps.
+ </ol>
<li>If <var>start node</var> is a [[text]] node and <var>start offset</var>
is 0, set <var>start offset</var> to the [[index]] of <var>start node</var>,
@@ -4600,9 +4619,11 @@
its [[nodelength]], set <var>end offset</var> to one plus the [[index]] of
<var>end node</var>, then set <var>end node</var> to its [[parent]].
- <li>Set <var>range</var>'s [[rangestart]] to (<var>start node</var>,
- <var>start offset</var>) and its [[rangeend]] to (<var>end node</var>,
- <var>end offset</var>).
+ <li>Call [[selcollapse|<var>start node</var>, <var>start offset</var>]] on
+ the [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>end node</var>, <var>end offset</var>]] on the
+ [[contextobject]]'s [[selection]].
<li>
<div class=comments>
@@ -4616,8 +4637,8 @@
anything.
</div>
- <p>Let <var>start block</var> be the [[rangestart]] [[bpnode]] of
- <var>range</var>.
+ <p>Let <var>start block</var> be the <span>active range</span>'s
+ [[startnode]].
<li>While <var>start block</var>'s [[parent]] is <span>in the same editing
host</span> and <var>start block</var> is an <span>inline node</span>, set
@@ -4653,8 +4674,7 @@
<var>start block</var>, or <var>start block</var> is a [[td]] or [[th]], set
<var>start block</var> to null.
- <li>Let <var>end block</var> be the [[rangeend]] [[bpnode]] of
- <var>range</var>.
+ <li>Let <var>end block</var> be the <span>active range</span>'s [[endnode]].
<li>While <var>end block</var>'s [[parent]] is <span>in the same editing
host</span> and <var>end block</var> is an <span>inline node</span>, set
@@ -4696,7 +4716,11 @@
<li><span>Canonicalize whitespace</span> at (<var>start node</var>,
<var>start offset</var>).
- <li>Set <var>range</var>'s [[rangeend]] to its [[rangestart]].
+ <li>If <var>direction</var> is "forward", call [[collapsetostart]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Otherwise, call [[collapsetoend]] on the [[contextobject]]'s
+ [[selection]].
<li>
<p class=comments>This is needed to restore any overrides that would
@@ -4724,9 +4748,9 @@
cell-selection mode when you try to select between cells, at least in some
cases, instead of selecting letter-by-letter.
- <p>For each <var>node</var> [[contained]] in <var>range</var>, append
- <var>node</var> to <var>node list</var> if the last member of <var>node
- list</var> (if any) is not an [[ancestor]] of <var>node</var>;
+ <p>For each <var>node</var> [[contained]] in the <span>active range</span>,
+ append <var>node</var> to <var>node list</var> if the last member of
+ <var>node list</var> (if any) is not an [[ancestor]] of <var>node</var>;
<var>node</var> is <span>editable</span>; and <var>node</var> is not a
[[thead]], [[tbody]], [[tfoot]], [[tr]], [[th]], or [[td]].
@@ -4765,10 +4789,11 @@
<li>If <var>end node</var> is an <span>editable</span> [[text]] node, call
[[deletedata|0, <var>end offset</var>]] on it.
- <li><span>Canonicalize whitespace</span> at <var>range</var>'s
+ <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s
[[rangestart]].
- <li><span>Canonicalize whitespace</span> at <var>range</var>'s [[rangeend]].
+ <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s
+ [[rangeend]].
<li>
<div class=comments>
@@ -4801,7 +4826,11 @@
and <var>end block</var> are the same:
<ol>
- <li>Set <var>range</var>'s [[rangeend]] to its [[rangestart]].
+ <li>If <var>direction</var> is "forward", call [[collapsetostart]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Otherwise, call [[collapsetoend]] on the [[contextobject]]'s
+ [[selection]].
<li><span>Restore states and values</span> from <var>overrides</var>.
@@ -4818,9 +4847,6 @@
<p>If <var>start block</var> has one [[child]], which is a <span>collapsed
block prop</span>, remove its [[child]] from it.
- <li>If <var>end block</var> has one [[child]], which is a <span>collapsed
- block prop</span>, remove its [[child]] from it.
-
<li>
<p class=comments>Just repeatedly blow up the end block in this case.
@@ -4832,8 +4858,9 @@
<li>While <var>reference node</var> is not a [[child]] of <var>start
block</var>, set <var>reference node</var> to its [[parent]].
- <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
- (<var>start block</var>, [[index]] of <var>reference node</var>).
+ <li>Call [[selcollapse|]] on the [[contextobject]]'s [[selection]], with
+ first argument <var>start block</var> and second argument the [[index]] of
+ <var>reference node</var>.
<li>If <var>end block</var> has no [[children]]:
@@ -4890,8 +4917,9 @@
block</var>:
<ol>
- <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
- (<var>start block</var>, [[nodelength]] of <var>start block</var>).
+ <li>Call [[selcollapse|]] on the [[contextobject]]'s [[selection]], with
+ first argument <var>start block</var> and second argument <var>start
+ block</var>'s [[nodelength]].
<li>Let <var>reference node</var> be <var>start block</var>.
@@ -4905,12 +4933,12 @@
<li>Let <var>nodes to move</var> be a list of [[nodes]], initially empty.
<li>If <var>reference node</var>'s [[nextsibling]] is neither null nor a
- [[br]] nor a <span>block node</span>, append it to <var>nodes to
- move</var>.
-
- <li>While <var>nodes to move</var> is nonempty and its last member's
- [[nextsibling]] is neither null nor a [[br]] nor a <span>block node</span>,
- append it to <var>nodes to move</var>.
+ <span>block node</span>, append it to <var>nodes to move</var>.
+
+ <li>While <var>nodes to move</var> is nonempty and its last member isn't a
+ [[br]] and its last member's [[nextsibling]] is neither null nor a
+ <span>block node</span>, append its last member's [[nextsibling]] to
+ <var>nodes to move</var>.
<li><span>Record the values</span> of <var>nodes to move</var>, and let
<var>values</var> be the result.
@@ -4918,9 +4946,6 @@
<li>For each <var>node</var> in <var>nodes to move</var>, append
<var>node</var> as the last [[child]] of <var>start block</var>,
<span>preserving ranges</span>.
-
- <li>If the [[nextsibling]] of <var>reference node</var> is a [[br]], remove
- it from its [[parent]].
</ol>
<li>
@@ -4931,8 +4956,9 @@
<p>Otherwise:
<ol>
- <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
- (<var>start block</var>, [[nodelength]] of <var>start block</var>).
+ <li>Call [[selcollapse|]] on the [[contextobject]]'s [[selection]], with
+ first argument <var>start block</var> and second argument <var>start
+ block</var>'s [[nodelength]].
<li>If <var>end block</var>'s [[firstchild]] is an <span>inline node</span>
and <var>start block</var>'s [[lastchild]] is a [[br]], remove <var>start
@@ -4956,6 +4982,9 @@
[[createelement|"br"]] on the [[contextobject]] and append the result as the
last [[child]] of <var>start block</var>.
+ <li><span>Remove extraneous line breaks at the end of</span> <var>start
+ block</var>.
+
<li><span>Restore states and values</span> from <var>overrides</var>.
</ol>
@@ -6607,7 +6636,7 @@
<div class=note>
<p>This is the same as hitting backspace (see <a
href=#additional-requirements>Additional requirements</a>). The easy part is
-if the selection isn't collapsed: just <span>delete the contents</span>. But
+if the selection isn't collapsed: just <span>delete the selection</span>. But
it turns out rich-text editors have a lot of special behaviors for hitting
backspace with a collapsed selection. Most obviously, if there's a text node
right before the cursor (maybe wrapped in some inline elements), we delete its
@@ -6651,8 +6680,8 @@
<ol>
<li>If the <span>active range</span> is not <code data-anolis-spec=domrange
- title=dom-Range-collapsed>collapsed</code>, <span>delete the contents</span>
- of the <span>active range</span> and abort these steps.
+ title=dom-Range-collapsed>collapsed</code>, <span>delete the selection</span>
+ and abort these steps.
<li>
<p class=comments>Needed so that if there are multiple consecutive spaces we
@@ -6742,10 +6771,21 @@
</div>
<p>If <var>node</var> is a [[text]] node and <var>offset</var> is not zero,
- call [[selcollapse|<var>node</var>, <var>offset</var>]] on the [[selection]].
- Then <span>delete the contents</span> of the [[range]] with [[rangestart]]
- (<var>node</var>, <var>offset</var> − 1) and [[rangeend]]
- (<var>node</var>, <var>offset</var>) and abort these steps.
+ or if <var>node</var> is a <span>block node</span> that has a [[child]] with
+ [[index]] <var>offset</var> − 1 and that [[child]] is a [[br]] or
+ [[hr]] or [[img]]:
+
+ <ol>
+ <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>node</var>, <var>offset</var> − 1]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>.
+
+ <li>Abort these steps.
+ </ol>
<li>
<p class=comments>At the time of this writing, this should be impossible.
@@ -6753,13 +6793,6 @@
<p>If <var>node</var> is an <span>inline node</span>, abort these steps.
- <li>If <var>node</var> has a [[child]] with [[index]] <var>offset</var>
- − 1 and that [[child]] is a [[br]] or [[hr]] or [[img]], call
- [[selcollapse|<var>node</var>, <var>offset</var>]] on the [[selection]].
- Then <span>delete the contents</span> of the [[range]] with [[rangestart]]
- (<var>node</var>, <var>offset</var> − 1) and [[rangeend]]
- (<var>node</var>, <var>offset</var>) and abort these steps.
-
<li>
<p class=comments> If we're at the beginning of a list, we want to outdent
the first list item. This doesn't actually match anyone or anything. Word
@@ -6906,13 +6939,17 @@
an <span>inline node</span>:
<ol>
+ <li>Call [[selcollapse|<var>start node</var>, <var>start offset</var>
+ − 1]] on the [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>start node</var>, <var>start offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>.
+
<li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
[[selection]].
- <li><span>Delete the contents</span> of the [[range]] with [[rangestart]]
- (<var>start node</var>, <var>start offset</var> − 1) and [[rangeend]]
- (<var>start node</var>, <var>start offset</var>).
-
<li>Abort these steps.
</ol>
@@ -6961,22 +6998,49 @@
<li>
<p class=comments>When merging adjacent list items, make sure we only merge
the items themselves, not any block children. We want
- <li><p>foo<li><p>bar to become <li><p>foo<p>bar, not
- <li><p>foo<br>bar or <li><p>foobar.
-
- <p>If the [[child]] of <var>start node</var> with [[index]] <var>start
- offset</var> is an [[li]] or [[dt]] or [[dd]], and its [[previoussibling]] is
- also an [[li]] or [[dt]] or [[dd]], set <var>start node</var> to its
- [[child]] with [[index]] <var>start offset</var> − 1, then set
- <var>start offset</var> to <var>start node</var>'s [[nodelength]], then set
- <var>node</var> to <var>start node</var>'s [[nextsibling]], then set
- <var>offset</var> to 0.
+ {{code|<li><p>foo<li><p>[]bar}} to become {{code|<li><p>foo<p>[]bar}}, not
+ {{code|<li><p>foo<br>[]bar}} or {{code|<li><p>foo[]bar}}. To do the
+ deletion, we need to wipe out the current selection, so we save it as a
+ range. Saving it as a node/offset pair isn't enough, because it might be
+ invalid after we do the deletion. A range will update according to the range
+ mutation rules.
+
+ <p>If <var>start node</var>'s [[child]] with [[index]] <var>start
+ offset</var> is an [[li]] or [[dt]] or [[dd]], and that [[child]]'s
+ [[previoussibling]] is also an [[li]] or [[dt]] or [[dd]]:
+
+ <ol>
+ <li>Call [[clonerange]] on the <span>active range</span>, and let
+ <var>original range</var> be the result.
+
+ <li>Set <var>start node</var> to its [[child]] with [[index]] <var>start
+ offset</var> − 1.
+
+ <li>Set <var>start offset</var> to <var>start node</var>'s [[nodelength]].
+
+ <li>Set <var>node</var> to <var>start node</var>'s [[nextsibling]].
+
+ <li>Call [[selcollapse|<var>start node</var>, <var>start offset</var>]] on
+ the [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>node</var>, 0]] on the [[contextobject]]'s
+ [[selection]].
+
+ <li><span>Delete the selection</span>.
+
+ <li>Call [[removeallranges]] on the [[contextobject]]'s [[selection]].
+
+ <li>Call [[addrange|<var>original range</var>]] on the [[contextobject]]'s
+ [[selection]].
+
+ <li>Abort these steps.
+ </ol>
<li>
<p class=comments>General block-merging case.
- <p>Otherwise, while <var>start node</var> has a [[child]] with [[index]]
- <var>start offset</var> minus one:
+ <p>While <var>start node</var> has a [[child]] with [[index]] <var>start
+ offset</var> minus one:
<ol>
<li>If <var>start node</var>'s [[child]] with [[index]] <var>start
@@ -6989,9 +7053,13 @@
[[nodelength]] of <var>start node</var>.
</ol>
- <li><span>Delete the contents</span> of the [[range]] with [[rangestart]]
- (<var>start node</var>, <var>start offset</var>) and [[rangeend]]
- (<var>node</var>, <var>offset</var>).
+ <li>Call [[selcollapse|<var>start node</var>, <var>start offset</var>]] on
+ the [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>node</var>, <var>offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>, with <var>direction</var> "backward".
</ol>
<!-- @} -->
@@ -7347,8 +7415,8 @@
<ol>
<li>If the <span>active range</span> is not <code data-anolis-spec=domrange
- title=dom-Range-collapsed>collapsed</code>, <span>delete the contents</span>
- of the <span>active range</span> and abort these steps.
+ title=dom-Range-collapsed>collapsed</code>, <span>delete the selection</span>
+ and abort these steps.
<li><span>Canonicalize whitespace</span> at (<span>active range</span>'s
[[startnode]], <span>active range</span>'s [[startoffset]]).
@@ -7369,10 +7437,6 @@
<span>invisible</span> [[node]], remove that [[child]] from
<var>node</var>.
- <li>Otherwise, if <var>node</var> has a [[child]] with [[index]]
- <var>offset</var> and that [[child]] is a <span>collapsed block
- prop</span>, add one to <var>offset</var>.
-
<li>Otherwise, if <var>offset</var> is the [[nodelength]] of
<var>node</var> and <var>node</var> is an <span>inline node</span>, or if
<var>node</var> is <span>invisible</span>, set <var>offset</var> to one
@@ -7384,9 +7448,9 @@
delete.
<p>Otherwise, if <var>node</var> has a [[child]] with [[index]]
- <var>offset</var> and that [[child]] is not a <span>block node</span> or a
- [[br]] or an [[img]], set <var>node</var> to that [[child]], then set
- <var>offset</var> to zero.
+ <var>offset</var> and that [[child]] is neither a <span>block node</span>
+ nor a [[br]] nor an [[img]] nor a <span>collapsed block prop</span>, set
+ <var>node</var> to that [[child]], then set <var>offset</var> to zero.
<li>Otherwise, break from this loop.
</ol>
@@ -7395,9 +7459,6 @@
<var>node</var>'s [[nodelength]]:
<ol>
- <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
- [[selection]].
-
<li>Let <var>end offset</var> be <var>offset</var> plus one.
<li>
@@ -7428,9 +7489,13 @@
general category M when interpreted as a Unicode code point, add one to
<var>end offset</var>.
- <li><span>Delete the contents</span> of the [[range]] with [[rangestart]]
- (<var>node</var>, <var>offset</var>) and [[rangeend]] (<var>node</var>,
- <var>end offset</var>).
+ <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>node</var>, <var>end offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>.
<li>Abort these steps.
</ol>
@@ -7438,11 +7503,20 @@
<li>If <var>node</var> is an <span>inline node</span>, abort these steps.
<li>If <var>node</var> has a [[child]] with [[index]] <var>offset</var> and
- that [[child]] is a [[br]] or [[hr]] or [[img]], call
- [[selcollapse|<var>node</var>, <var>offset</var>]] on the [[selection]].
- Then <span>delete the contents</span> of the [[range]] with [[rangestart]]
- (<var>node</var>, <var>offset</var>) and [[rangeend]] (<var>node</var>,
- <var>offset</var> + 1) and abort these steps.
+ that [[child]] is a [[br]] or [[hr]] or [[img]], but is not a
+ <span>collapsed block prop</span>:
+
+ <ol>
+ <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>node</var>, <var>offset</var> + 1]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>.
+
+ <li>Abort these steps.
+ </ol>
<li>
<p class=comments>No special list-item behavior for forwardDelete here,
@@ -7451,6 +7525,10 @@
<p>Let <var>end node</var> equal <var>node</var> and let <var>end
offset</var> equal <var>offset</var>.
+ <li>If <var>end node</var> has a [[child]] with [[index]] <var>end
+ offset</var>, and that [[child]] is a <span>collapsed block prop</span>, add
+ one to <var>end offset</var>.
+
<li>Repeat the following steps:
<ol>
@@ -7458,7 +7536,7 @@
<var>end offset</var> to one plus the [[index]] of <var>end node</var> and
then set <var>end node</var> to its [[parent]].
- <li>Otherwise, if <var>end node</var> has a an <span>editable</span>
+ <li>Otherwise, if <var>end node</var> has an <span>editable</span>
<span>invisible</span> [[child]] with [[index]] <var>end offset</var>,
remove it from <var>end node</var>.
@@ -7494,13 +7572,17 @@
[[hr]] or [[br]]:
<ol>
+ <li>Call [[selcollapse|<var>end node</var>, <var>end offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>end node</var>, <var>end offset</var> + 1]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>.
+
<li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
[[selection]].
- <li><span>Delete the contents</span> of the [[range]] with [[rangeend]]
- (<var>end node</var>, <var>end offset</var>) and [[rangeend]] (<var>end
- node</var>, <var>end offset</var> + 1).
-
<li>Abort these steps.
</ol>
@@ -7520,9 +7602,13 @@
<var>end offset</var> and set <var>end offset</var> to zero.
</ol>
- <li><span>Delete the contents</span> of the [[range]] with [[rangestart]]
- (<var>node</var>, <var>offset</var>) and [[rangeend]] (<var>end node</var>,
- <var>end offset</var>).
+ <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>end node</var>, <var>end offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>.
</ol>
<!-- @} -->
@@ -7647,19 +7733,26 @@
<p><span>Action</span>:
<ol>
- <li>Let <var>range</var> be the <span>active range</span>.
-
- <li>While <var>range</var>'s [[startoffset]] is 0 and its [[startnode]]'s
- [[parent]] is not null, set <var>range</var>'s [[rangestart]] to ([[parent]]
- of [[startnode]], [[index]] of [[startnode]]).
-
- <li>While <var>range</var>'s [[endoffset]] is the [[nodelength]] of its
- [[endnode]], and its [[endnode]]'s [[parent]] is not null, set
- <var>range</var>'s [[rangeend]] to ([[parent]] of [[endnode]], 1 + [[index]]
- of [[startnode]]).
-
- <li><span>Delete the contents</span> of <var>range</var>, with <var>block
- merging</var> false.
+ <li>Let <var>start node</var>, <var>start offset</var>, <var>end node</var>,
+ and <var>end offset</var> be the <span>active range</span>'s [[rangestart]]
+ and [[rangeend]] [[bpnodes]] and [[bpoffsets]].
+
+ <li>While <var>start offset</var> is 0 and <var>start node</var>'s
+ [[parent]] is not null, set <var>start offset</var> to <var>start
+ node</var>'s [[index]], then set <var>start node</var> to its [[parent]].
+
+ <li>While <var>end offset</var> is <var>end node</var>'s [[nodelength]], and
+ <var>end node</var>'s [[parent]] is not null, set <var>end offset</var> to
+ one plus <var>end node</var>'s [[index]], then set <var>end node</var> to its
+ [[parent]].
+
+ <li>Call [[selcollapse|<var>start node</var>, <var>start offset</var>]] on
+ the [[contextobject]]'s [[selection]].
+
+ <li>Call [[extend|<var>end node</var>, <var>end offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li><span>Delete the selection</span>, with <var>block merging</var> false.
<li>If the <span>active range</span>'s [[startnode]] is neither
<span>editable</span> nor an <span>editing host</span>, abort these steps.
@@ -7669,19 +7762,22 @@
text node, because that will leave an empty text node.
<p>If the <span>active range</span>'s [[startnode]] is a [[text]] node and
- its [[startoffset]] is zero, set the <span>active range</span>'s
- [[rangestart]] and [[rangeend]] to ([[parent]] of [[startnode]], [[index]] of
- [[startnode]]).
+ its [[startoffset]] is zero, call [[selcollapse|]] on the [[contextobject]]'s
+ [[selection]], with first argument the <span>active range</span>'s
+ [[startnode]]'s [[parent]] and second argument the <span>active
+ range</span>'s [[startnode]]'s [[index]].
<li>If the <span>active range</span>'s [[startnode]] is a [[text]] node and
- its [[startoffset]] is the [[length]] of its [[startnode]], set the
- <span>active range</span>'s [[rangestart]] and [[rangeend]] to ([[parent]] of
- [[startnode]], 1 + [[index]] of [[startnode]]).
+ its [[startoffset]] is the [[length]] of its [[startnode]], call
+ [[selcollapse|]] on the [[contextobject]]'s [[selection]], with first
+ argument the <span>active range</span>'s [[startnode]]'s [[parent]], and the
+ second argument one plus the <span>active range</span>'s [[startnode]]'s
+ [[index]].
<li>Let <var>hr</var> be the result of calling [[createelement|"hr"]] on the
[[contextobject]].
- <li>Run [[insertnode|<var>hr</var>]] on <var>range</var>.
+ <li>Run [[insertnode|<var>hr</var>]] on the <span>active range</span>.
<li>
<p class=comments>IE9 and Chrome 13 dev seem to never break up any ancestors,
@@ -7694,12 +7790,9 @@
<p><span>Fix disallowed ancestors</span> of <var>hr</var>.
- <li>Let <var>selection</var> be the result of running [[getselection]] on the
- [[contextobject]].
-
- <li>Run [[selcollapse|]] on <var>selection</var>, with first argument equal
- to the [[parent]] of <var>hr</var> and the second argument equal to one plus
- the [[index]] of <var>hr</var>.
+ <li>Run [[selcollapse|]] on the [[contextobject]]'s [[selection]], with first
+ argument <var>hr</var>'s [[parent]] and the second argument equal to one plus
+ <var>hr</var>'s [[index]].
</ol>
<!-- @} -->
@@ -7754,7 +7847,7 @@
true.
</div>
- <p><span>Delete the contents</span> of the <span>active range</span>.
+ <p><span>Delete the selection</span>.
<li>If the <span>active range</span>'s [[startnode]] is neither
<span>editable</span> nor an <span>editing host</span>, abort these steps.
@@ -7859,8 +7952,6 @@
<p>If <var>value</var> is the empty string, abort these steps and do
nothing.
- <li>Let <var>range</var> be the <span>active range</span>.
-
<li>
<p class=comments>Firefox 7.0a2 seems to strip the wrapper or not depending
on the exact positioning of the selection: <b>{foo}</b> yes,
@@ -7870,8 +7961,9 @@
the board because they might be meaningful: e.g., a background-color when the
image is small or not fully opaque.
- <p><span>Delete the contents</span> of <var>range</var>, with <var>strip
- wrappers</var> false.
+ <p><span>Delete the selection</span>, with <var>strip wrappers</var> false.
+
+ <li>Let <var>range</var> be the <span>active range</span>.
<li>If the <span>active range</span>'s [[startnode]] is neither
<span>editable</span> nor an <span>editing host</span>, abort these steps.
@@ -7942,8 +8034,7 @@
endpoints. Chrome 14 dev strips wrappers but recreates any styles using new
wrappers. Opera 11.50 strips all wrappers.
- <p><span>Delete the contents</span> of the <span>active range</span>, with
- <var>strip wrappers</var> false.
+ <p><span>Delete the selection</span>, with <var>strip wrappers</var> false.
<li>If the <span>active range</span>'s [[startnode]] is neither
<span>editable</span> nor an <span>editing host</span>, abort these steps.
@@ -8073,7 +8164,7 @@
<p><span>Action</span>:
<ol>
- <li><span>Delete the contents</span> of the <span>active range</span>.
+ <li><span>Delete the selection</span>.
<li>If the <span>active range</span>'s [[startnode]] is neither
<span>editable</span> nor an <span>editing host</span>, abort these steps.
@@ -8481,8 +8572,7 @@
deletion at all). This behavior seems to closely match IE9.
</div>
- <p><span>Delete the contents</span> of the <span>active range</span>, with
- <var>strip wrappers</var> false.
+ <p><span>Delete the selection</span>, with <var>strip wrappers</var> false.
<li>If the <span>active range</span>'s [[startnode]] is neither
<span>editable</span> nor an <span>editing host</span>, abort these steps.
@@ -8887,10 +8977,10 @@
<p class=comments>See comment for <a href=#the-copy-command>copy</a>.
<p><span>Action</span>: The user agent must either <span>delete the
-contents</span> of the <span>active range</span> and then paste the clipboard's
-contents to the current cursor position, as though the user had requested it,
-or raise a [[SECURITY_ERR]] exception. This specification does not define
-exactly how the clipboard is to be converted to HTML for pasting, but the <a
+selection</span> and then paste the clipboard's contents to the current cursor
+position, as though the user had requested it, or raise a [[SECURITY_ERR]]
+exception. This specification does not define exactly how the clipboard is to
+be converted to HTML for pasting, but the <a
href=http://dev.w3.org/2006/webapi/clipops/clipops.html>Clipboard API and
events</a> specification might be useful.