--- a/autoimplementation.html Fri Jun 03 13:08:06 2011 -0600
+++ b/autoimplementation.html Fri Jun 03 15:20:13 2011 -0600
@@ -298,6 +298,56 @@
'<a name=abc>foo[bar]baz</a>',
'<a name=abc><b>foo[bar]baz</b></a>',
],
+ // Opera requires this to be quoted, contrary to ES5 11.1.5 which allows
+ // PropertyName to be any IdentifierName, and see 7.6 which defines
+ // IdentifierName to include ReservedWord; Identifier excludes it.
+ "delete": [
+ 'foo[]bar',
+ '<span>foo</span>{}<span>bar</span>',
+ '<span>foo[</span><span>]bar</span>',
+ 'foo[bar]baz',
+
+ 'foo<b>[bar]</b>baz',
+ 'foo<b>{bar}</b>baz',
+ 'foo{<b>bar</b>}baz',
+ 'foo<span>[bar]</span>baz',
+ 'foo<span>{bar}</span>baz',
+ 'foo{<span>bar</span>}baz',
+ '<b>foo[bar</b><i>baz]quz</i>',
+ '<p>foo</p><p>[bar]</p><p>baz</p>',
+ '<p>foo</p><p>{bar}</p><p>baz</p>',
+ '<p>foo</p>{<p>bar</p>}<p>baz</p>',
+
+ '<p>foo[bar<p>baz]quz',
+ '<p>foo[bar<div>baz]quz</div>',
+ '<p>foo[bar<h1>baz]quz</h1>',
+ '<div>foo[bar</div><p>baz]quz',
+ '<blockquote>foo[bar</blockquote><pre>baz]quz</pre>',
+
+ '<p><b>foo[bar</b><p>baz]quz',
+ '<div><p>foo[bar</div><p>baz]quz',
+ '<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote',
+ '<p>foo[bar<p style=color:red>baz]quz',
+ '<p>foo[bar<p><b>baz]quz</b>',
+
+ '<div><p>foo<p>[bar<p>baz]</div>',
+
+ 'foo[<br>]bar',
+ '<p>foo[</p><p>]bar</p>',
+ '<p>foo[</p><p>]bar<br>baz</p>',
+ 'foo[<p>]bar</p>',
+ 'foo[<p>]bar<br>baz</p>',
+ 'foo[<p>]bar</p>baz',
+ '<p>foo[</p>]bar',
+ '<p>foo[</p>]bar<br>baz',
+ '<p>foo[</p>]bar<p>baz</p>',
+ 'foo[<div><p>]bar</div>',
+ '<div><p>foo[</p></div>]bar',
+ 'foo[<div><p>]bar</p>baz</div>',
+ 'foo[<div>]bar<p>baz</p></div>',
+ '<div><p>foo</p>bar[</div>]baz',
+ '<div>foo<p>bar[</p></div>]baz',
+ ],
fontname: [
'foo[]bar',
'<span>foo</span>{}<span>bar</span>',
--- a/editcommands.html Fri Jun 03 13:08:06 2011 -0600
+++ b/editcommands.html Fri Jun 03 15:20:13 2011 -0600
@@ -83,19 +83,20 @@
<li><a href=#the-backcolor-command><span class=secno>6.8 </span>The <code title="">backColor</code> command</a></li>
<li><a href=#the-bold-command><span class=secno>6.9 </span>The <code title="">bold</code> command</a></li>
<li><a href=#the-createlink-command><span class=secno>6.10 </span>The <code title="">createLink</code> command</a></li>
- <li><a href=#the-fontname-command><span class=secno>6.11 </span>The <code title="">fontName</code> command</a></li>
- <li><a href=#the-fontsize-command><span class=secno>6.12 </span>The <code title="">fontSize</code> command</a></li>
- <li><a href=#the-forecolor-command><span class=secno>6.13 </span>The <code title="">foreColor</code> command</a></li>
- <li><a href=#the-hilitecolor-command><span class=secno>6.14 </span>The <code title="">hiliteColor</code> command</a></li>
- <li><a href=#the-inserthtml-command><span class=secno>6.15 </span>The <code title="">insertHTML</code> command</a></li>
- <li><a href=#the-insertimage-command><span class=secno>6.16 </span>The <code title="">insertImage</code> command</a></li>
- <li><a href=#the-italic-command><span class=secno>6.17 </span>The <code title="">italic</code> command</a></li>
- <li><a href=#the-removeformat-command><span class=secno>6.18 </span>The <code title="">removeFormat</code> command</a></li>
- <li><a href=#the-strikethrough-command><span class=secno>6.19 </span>The <code title="">strikethrough</code> command</a></li>
- <li><a href=#the-subscript-command><span class=secno>6.20 </span>The <code title="">subscript</code> command</a></li>
- <li><a href=#the-superscript-command><span class=secno>6.21 </span>The <code title="">superscript</code> command</a></li>
- <li><a href=#the-underline-command><span class=secno>6.22 </span>The <code title="">underline</code> command</a></li>
- <li><a href=#the-unlink-command><span class=secno>6.23 </span>The <code title="">unlink</code> command</a></ol></li>
+ <li><a href=#the-delete-command><span class=secno>6.11 </span>The <code title="">delete</code> command</a></li>
+ <li><a href=#the-fontname-command><span class=secno>6.12 </span>The <code title="">fontName</code> command</a></li>
+ <li><a href=#the-fontsize-command><span class=secno>6.13 </span>The <code title="">fontSize</code> command</a></li>
+ <li><a href=#the-forecolor-command><span class=secno>6.14 </span>The <code title="">foreColor</code> command</a></li>
+ <li><a href=#the-hilitecolor-command><span class=secno>6.15 </span>The <code title="">hiliteColor</code> command</a></li>
+ <li><a href=#the-inserthtml-command><span class=secno>6.16 </span>The <code title="">insertHTML</code> command</a></li>
+ <li><a href=#the-insertimage-command><span class=secno>6.17 </span>The <code title="">insertImage</code> command</a></li>
+ <li><a href=#the-italic-command><span class=secno>6.18 </span>The <code title="">italic</code> command</a></li>
+ <li><a href=#the-removeformat-command><span class=secno>6.19 </span>The <code title="">removeFormat</code> command</a></li>
+ <li><a href=#the-strikethrough-command><span class=secno>6.20 </span>The <code title="">strikethrough</code> command</a></li>
+ <li><a href=#the-subscript-command><span class=secno>6.21 </span>The <code title="">subscript</code> command</a></li>
+ <li><a href=#the-superscript-command><span class=secno>6.22 </span>The <code title="">superscript</code> command</a></li>
+ <li><a href=#the-underline-command><span class=secno>6.23 </span>The <code title="">underline</code> command</a></li>
+ <li><a href=#the-unlink-command><span class=secno>6.24 </span>The <code title="">unlink</code> command</a></ol></li>
<li><a href=#block-formatting-commands><span class=secno>7 </span>Block formatting commands</a>
<ol>
<li><a href=#block-formatting-command-definitions><span class=secno>7.1 </span>Block formatting command definitions</a></li>
@@ -1031,6 +1032,9 @@
<li>If (<var title="">end node</var>, <var title="">end offset</var>) is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-before title=concept-bp-before>before</a> (<var title="">start
node</var>, <var title="">start offset</var>), call <code class=external data-anolis-spec=domrange title=dom-Range-deleteContents><a href=http://html5.org/specs/dom-range.html#dom-range-deletecontents>deleteContents()</a></code> on <var title="">range</var>
and abort these steps.
+ <!-- This actually will have no effect other than collapsing the selection to
+ whatever point deleteContents() likes to collapse it to. It might make more
+ sense to collapse to the start or end, though. -->
<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>,
@@ -1051,6 +1055,7 @@
<var title="">end block</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
<li>Call <code class=external data-anolis-spec=domrange title=dom-Range-deleteContents><a href=http://html5.org/specs/dom-range.html#dom-range-deletecontents>deleteContents()</a></code> on <var title="">range</var>.
+
<!--
Now we need to merge blocks. The simplest case is something like
@@ -1072,12 +1077,43 @@
where one descends from the other.
-->
+ <!-- The deletions might have left some empty elements. We want to remove
+ empty inline nodes, and add a <br> child to empty blocks. We remove the
+ empty inline nodes first, and only add the <br>s later, because we don't want
+ to add the brs to blocks that we're about to merge. -->
+ <li>While <var title="">start node</var> is an <a href=#editable>editable</a> <a href=#inline-node>inline
+ node</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> 0, let <var title="">parent</var> be 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>,
+ then remove <var title="">start node</var> from <var title="">parent</var>, then set <var title="">start
+ node</var> to <var title="">parent</var>.
+
+ <li>While <var title="">end node</var> is an <a href=#editable>editable</a> <a href=#inline-node>inline
+ node</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> 0, let <var title="">parent</var> be 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>,
+ then remove <var title="">end node</var> from <var title="">parent</var>, then set <var title="">end
+ node</var> to <var title="">parent</var>.
+
<li>If <var title="">start block</var> is not <a href=#in-the-same-editing-host>in the same editing host</a> as
<var title="">end block</var>, or <var title="">start block</var> is neither an <a href=#editing-host>editing
host</a> nor a <a href=#prohibited-paragraph-child>prohibited paragraph child</a>, or <var title="">end
block</var> is neither an <a href=#editing-host>editing host</a> nor a <a href=#prohibited-paragraph-child>prohibited
paragraph child</a>, or <var title="">start block</var> and <var title="">end block</var>
- are the same, abort these steps.
+ are the same:
+ <!-- Then we don't try to merge anything. -->
+
+ <ol>
+ <li>If <var title="">start node</var> is an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> with no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, is
+ either <a href=#editable>editable</a> or an <a href=#editing-host>editing host</a>, and is not an
+ <a href=#inline-node>inline node</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and 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
+ node</var>.
+
+ <li>If <var title="">end node</var> is an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> with no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, is
+ either <a href=#editable>editable</a> or an <a href=#editing-host>editing host</a>, and is not an
+ <a href=#inline-node>inline node</a>, call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
+ <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and 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="">end
+ node</var>.
+
+ <li>Abort these steps.
+ </ol>
<li>If <var title="">start block</var> is an <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-ancestor title=concept-tree-ancestor>ancestor</a> of <var title="">end block</var>:
<!-- Just repeatedly blow up the end block. -->
@@ -1110,18 +1146,17 @@
<li>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="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>
equal to its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a> is a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> and is not the first member of
<var title="">children</var>, remove that <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code> from its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
-
- <li>Abort these steps.
</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>If <var title="">start block</var> is a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendant</a> of <var title="">end block</var>:
+ <li>Otherwise, if <var title="">start block</var> is a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendant</a> of <var title="">end
+ block</var>:
<!-- Pull in everything that comes after <var title>start block</var>, until we hit
a br or prohibited paragraph child. -->
<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>Let <var title="">reference node</var> be <var title="">start block</var>.
<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="">end
@@ -1134,19 +1169,28 @@
<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>.
-
- <li>Abort these steps.
</ol>
+ <li>Otherwise:
<!-- In the last case, just move all the children of the end block to the
start block, and then get rid of any elements we emptied that way. -->
- <li>While <var title="">end block</var> has <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, append the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>
- of <var title="">end block</var> to <var title="">start block</var>, <a href=#preserving-ranges>preserving
- ranges</a>.
-
- <li>While <var title="">end block</var> has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, let <var title="">parent</var> be
- the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of <var title="">end block</var>, then remove <var title="">end block</var> from
- <var title="">parent</var>, then set <var title="">end block</var> to <var title="">parent</var>.
+
+ <ol>
+ <li>Set the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> of <var title="">range</var> to
+ (<var title="">start block</var>, <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of <var title="">start block</var>).
+
+ <li>While <var title="">end block</var> has <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, append the first <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>
+ of <var title="">end block</var> to <var title="">start block</var>, <a href=#preserving-ranges>preserving
+ ranges</a>.
+
+ <li>While <var title="">end block</var> has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, let <var title="">parent</var> be
+ the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> of <var title="">end block</var>, then remove <var title="">end block</var> from
+ <var title="">parent</var>, then set <var title="">end block</var> to <var title="">parent</var>.
+ </ol>
+
+ <li>If <var title="">start 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>, call
+ <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and 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>.
</ol>
<p>To move a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> to a new location, <dfn id=preserving-ranges>preserving ranges</dfn>, remove
@@ -2298,7 +2342,25 @@
<!-- I'd have expected the value to be the URL, but guess not. -->
-<h3 id=the-fontname-command><span class=secno>6.11 </span><dfn>The <code title="">fontName</code> command</dfn></h3>
+<h3 id=the-delete-command><span class=secno>6.11 </span><dfn>The <code title="">delete</code> command</dfn></h3>
+<!-- Not really specifically "inline", but I didn't want to create a new
+section just for it. -->
+
+<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-selection>delete the selection</a>
+ and abort these steps.
+
+ <p class=XXX>Maybe we sometimes want to do the following even if it isn't
+ collapsed? WebKit seems to do some normalization on the range before
+ deciding whether it's collapsed, and that sounds like a good idea.
+
+ <li class=XXX>The stuff where we delete the previous character goes here.
+</ol>
+
+
+<h3 id=the-fontname-command><span class=secno>6.12 </span><dfn>The <code title="">fontName</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#decompose>Decompose</a> the <a href=#active-range>active range</a>,
then <a href=#set-the-value>set the value</a> of each returned <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> to <var title="">value</var>.
@@ -2347,7 +2409,7 @@
<p><a href=#relevant-css-property>Relevant CSS property</a>: "font-family"
-<h3 id=the-fontsize-command><span class=secno>6.12 </span><dfn>The <code title="">fontSize</code> command</dfn></h3>
+<h3 id=the-fontsize-command><span class=secno>6.13 </span><dfn>The <code title="">fontSize</code> command</dfn></h3>
<p><a href=#action>Action</a>:
@@ -2454,7 +2516,7 @@
<p><a href=#relevant-css-property>Relevant CSS property</a>: "font-size"
-<h3 id=the-forecolor-command><span class=secno>6.13 </span><dfn>The <code title="">foreColor</code> command</dfn></h3>
+<h3 id=the-forecolor-command><span class=secno>6.14 </span><dfn>The <code title="">foreColor</code> command</dfn></h3>
<p><a href=#action>Action</a>:
@@ -2539,7 +2601,7 @@
<p><a href=#relevant-css-property>Relevant CSS property</a>: "color"
-<h3 id=the-hilitecolor-command><span class=secno>6.14 </span><dfn>The <code title="">hiliteColor</code> command</dfn></h3>
+<h3 id=the-hilitecolor-command><span class=secno>6.15 </span><dfn>The <code title="">hiliteColor</code> command</dfn></h3>
<!-- IE 9 RC doesn't support this. It uses backColor instead, but Gecko and
Opera treat that differently, while all non-IE browsers treat hiliteColor the
same, so I'm standardizing hiliteColor as the way to highlight text.
@@ -2578,7 +2640,7 @@
<p><a href=#relevant-css-property>Relevant CSS property</a>: "background-color"
-<h3 id=the-inserthtml-command><span class=secno>6.15 </span><dfn>The <code title="">insertHTML</code> command</dfn></h3>
+<h3 id=the-inserthtml-command><span class=secno>6.16 </span><dfn>The <code title="">insertHTML</code> command</dfn></h3>
<!-- Not supported by IE9. -->
<p><a href=#action>Action</a>:
@@ -2608,7 +2670,7 @@
</ol>
-<h3 id=the-insertimage-command><span class=secno>6.16 </span><dfn>The <code title="">insertImage</code> command</dfn></h3>
+<h3 id=the-insertimage-command><span class=secno>6.17 </span><dfn>The <code title="">insertImage</code> command</dfn></h3>
<p><a href=#action>Action</a>:
@@ -2644,7 +2706,7 @@
</ol>
-<h3 id=the-italic-command><span class=secno>6.17 </span><dfn>The <code title="">italic</code> command</dfn></h3>
+<h3 id=the-italic-command><span class=secno>6.18 </span><dfn>The <code title="">italic</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#decompose>Decompose</a> the <a href=#active-range>active range</a>.
If the <a href=#state>state</a> is then false, <a href=#set-the-value>set the value</a> of each
@@ -2660,7 +2722,7 @@
<p><a href=#relevant-css-property>Relevant CSS property</a>: "font-style"
-<h3 id=the-removeformat-command><span class=secno>6.18 </span><dfn>The <code title="">removeFormat</code> command</dfn></h3>
+<h3 id=the-removeformat-command><span class=secno>6.19 </span><dfn>The <code title="">removeFormat</code> command</dfn></h3>
<!--
Tested in IE 9, Firefox 4.0, Chrome 12 dev, Opera 11.00.
@@ -2781,7 +2843,7 @@
</ol>
-<h3 id=the-strikethrough-command><span class=secno>6.19 </span><dfn>The <code title="">strikethrough</code> command</dfn></h3>
+<h3 id=the-strikethrough-command><span class=secno>6.20 </span><dfn>The <code title="">strikethrough</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#decompose>Decompose</a> the <a href=#active-range>active range</a>.
If the <a href=#state>state</a> is then false, <a href=#set-the-value>set the value</a> of each
@@ -2797,7 +2859,7 @@
<p><a href=#value>Value</a>: Always the empty string.
-<h3 id=the-subscript-command><span class=secno>6.20 </span><dfn>The <code title="">subscript</code> command</dfn></h3>
+<h3 id=the-subscript-command><span class=secno>6.21 </span><dfn>The <code title="">subscript</code> command</dfn></h3>
<p><a href=#action>Action</a>:
@@ -2822,7 +2884,7 @@
<p><a href=#relevant-css-property>Relevant CSS property</a>: "vertical-align"
-<h3 id=the-superscript-command><span class=secno>6.21 </span><dfn>The <code title="">superscript</code> command</dfn></h3>
+<h3 id=the-superscript-command><span class=secno>6.22 </span><dfn>The <code title="">superscript</code> command</dfn></h3>
<p><a href=#action>Action</a>:
@@ -2847,7 +2909,7 @@
<p><a href=#relevant-css-property>Relevant CSS property</a>: "vertical-align"
-<h3 id=the-underline-command><span class=secno>6.22 </span><dfn>The <code title="">underline</code> command</dfn></h3>
+<h3 id=the-underline-command><span class=secno>6.23 </span><dfn>The <code title="">underline</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#decompose>Decompose</a> the <a href=#active-range>active range</a>.
If the <a href=#state>state</a> is then false, <a href=#set-the-value>set the value</a> of each
@@ -2909,7 +2971,7 @@
<p><a href=#value>Value</a>: Always the empty string.
-<h3 id=the-unlink-command><span class=secno>6.23 </span><dfn>The <code title="">unlink</code> command</dfn></h3>
+<h3 id=the-unlink-command><span class=secno>6.24 </span><dfn>The <code title="">unlink</code> command</dfn></h3>
<p><a href=#action>Action</a>:
@@ -4943,12 +5005,24 @@
<h2 id=additional-requirements><span class=secno>9 </span>Additional requirements</h2>
+<p class=XXX>It has been <a href=http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-December/024628.html>suggested</a>
+that some things here need to be platform-dependent, not fully standardized.
+For now I'm standardizing them anyway, because the large majority of behavior
+should be platform-agnostic. If anyone has suggestions as to particular things
+that should be left up to platform behavior, please say so.
+
<p>When the user instructs the user agent to insert a line break inside an
<a href=#editing-host>editing host</a>, such as by pressing the Return key while the cursor
is in an <a href=#editable>editable</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>, the user agent must take the
<a href=#action>action</a> for <a href=#the-insertparagraph-command>the <code title="">insertParagraph</code>
command</a>.
+<p>When the user instructs the user agent to delete the previous character
+inside an <a href=#editing-host>editing host</a>, such as by pressing the Backspace key
+while the cursor is in an <a href=#editable>editable</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>, the user agent must
+take the <a href=#action>action</a> for <a href=#the-delete-command>the <code title="">delete</code>
+command</a>.
+
<h2 class=no-num id=acknowledgements>Acknowledgements</h2>
<p>Thanks to:
--- a/implementation.js Fri Jun 03 13:08:06 2011 -0600
+++ b/implementation.js Fri Jun 03 15:20:13 2011 -0600
@@ -894,14 +894,59 @@
// "Call deleteContents() on range."
range.deleteContents();
+ // "While start node is an editable inline node with length 0, let parent
+ // be its parent, then remove start node from parent, then set start node
+ // to parent."
+ while (isEditable(startNode)
+ && isInlineNode(startNode)
+ && getNodeLength(startNode) == 0) {
+ var parent_ = startNode.parentNode;
+ parent_.removeChild(startNode);
+ startNode = parent_;
+ }
+
+ // "While end node is an editable inline node with length 0, let parent be
+ // its parent, then remove end node from parent, then set end node to
+ // parent."
+ while (isEditable(endNode)
+ && isInlineNode(endNode)
+ && getNodeLength(endNode) == 0) {
+ var parent_ = endNode.parentNode;
+ parent_.removeChild(endNode);
+ endNode = parent_;
+ }
+
// "If start block is not in the same editing host as end block, or start
// block is neither an editing host nor a prohibited paragraph child, or
// end block is neither an editing host nor a prohibited paragraph child,
- // or start block and end block are the same, abort these steps."
+ // or start block and end block are the same:"
if (!inSameEditingHost(startBlock, endBlock)
|| (!isEditingHost(startBlock) && !isProhibitedParagraphChild(startBlock))
|| (!isEditingHost(endBlock) && !isProhibitedParagraphChild(endBlock))
|| startBlock == endBlock) {
+ // "If start node is an Element with no children, is either editable or
+ // an editing host, and is not an inline node, call createElement("br")
+ // on the context object and append the result as the last child of
+ // start node."
+ if ((isEditable(startNode) || isEditingHost(startNode))
+ && startNode.nodeType == Node.ELEMENT_NODE
+ && !startNode.hasChildNodes()
+ && !isInlineNode(startNode)) {
+ startNode.appendChild(document.createElement("br"));
+ }
+
+ // "If end node is an Element with no children, is either editable or
+ // an editing host, and is not an inline node, call createElement("br")
+ // on the context object and append the result as the last child of end
+ // node."
+ if ((isEditable(endNode) || isEditingHost(endNode))
+ && endNode.nodeType == Node.ELEMENT_NODE
+ && !endNode.hasChildNodes()
+ && !isInlineNode(endNode)) {
+ endNode.appendChild(document.createElement("br"));
+ }
+
+ // "Abort these steps."
return;
}
@@ -955,17 +1000,13 @@
range.startContainer.removeChild(range.startContainer.childNodes[range.startOffset]);
}
- // "Abort these steps."
- return;
- }
-
- // "Set the start and end of range to (start block, length of start
- // block)."
- range.setStart(startBlock, getNodeLength(startBlock));
- range.setEnd(startBlock, getNodeLength(startBlock));
-
- // "If start block is a descendant of end block:"
- if (isDescendant(startBlock, endBlock)) {
+ // "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));
+
// "Let reference node be start block."
var referenceNode = startBlock;
@@ -990,22 +1031,33 @@
referenceNode.parentNode.removeChild(referenceNode.nextSibling);
}
- // "Abort these steps."
- return;
- }
-
- // "While end block has children, append the first child of end block to
- // start block, preserving ranges."
- while (endBlock.hasChildNodes()) {
- movePreservingRanges(endBlock.firstChild, startBlock, -1);
- }
-
- // "While end block has no children, let parent be the parent of end block,
- // then remove end block from parent, then set end block to parent."
- while (!endBlock.hasChildNodes()) {
- var parent_ = endBlock.parentNode;
- parent_.removeChild(endBlock);
- endBlock = parent_;
+ // "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));
+
+ // "While end block has children, append the first child of end block
+ // to start block, preserving ranges."
+ while (endBlock.hasChildNodes()) {
+ movePreservingRanges(endBlock.firstChild, startBlock, -1);
+ }
+
+ // "While end block has no children, let parent be the parent of end
+ // block, then remove end block from parent, then set end block to
+ // parent."
+ while (!endBlock.hasChildNodes()) {
+ var parent_ = endBlock.parentNode;
+ parent_.removeChild(endBlock);
+ endBlock = parent_;
+ }
+ }
+
+ // "If start block has no children, call createElement("br") on the context
+ // object and append the result as the last child of start block."
+ if (!startBlock.hasChildNodes()) {
+ startBlock.appendChild(document.createElement("br"));
}
}
@@ -2984,6 +3036,15 @@
}
break;
+ case "delete":
+ // "If the active range is not collapsed, delete the selection and
+ // abort these steps."
+ if (!range.collapsed) {
+ deleteSelection();
+ return;
+ }
+ break;
+
case "fontname":
// "Decompose the range, then set the value of each returned node with
// new value equal to value."
--- a/source.html Fri Jun 03 13:08:06 2011 -0600
+++ b/source.html Fri Jun 03 15:20:13 2011 -0600
@@ -994,6 +994,9 @@
node</var>, <var>start offset</var>), call <code data-anolis-spec=domrange
title=dom-Range-deleteContents>deleteContents()</code> on <var>range</var>
and abort these steps.
+ <!-- This actually will have no effect other than collapsing the selection to
+ whatever point deleteContents() likes to collapse it to. It might make more
+ sense to collapse to the start or end, though. -->
<li>Set <var>range</var>'s [[rangestart]] to (<var>start node</var>,
<var>start offset</var>) and its [[rangeend]] to (<var>end node</var>,
@@ -1015,6 +1018,7 @@
<li>Call <code data-anolis-spec=domrange
title=dom-Range-deleteContents>deleteContents()</code> on <var>range</var>.
+
<!--
Now we need to merge blocks. The simplest case is something like
@@ -1036,12 +1040,43 @@
where one descends from the other.
-->
+ <!-- The deletions might have left some empty elements. We want to remove
+ empty inline nodes, and add a <br> child to empty blocks. We remove the
+ empty inline nodes first, and only add the <br>s later, because we don't want
+ to add the brs to blocks that we're about to merge. -->
+ <li>While <var>start node</var> is an <span>editable</span> <span>inline
+ node</span> with [[nodelength]] 0, let <var>parent</var> be its [[parent]],
+ then remove <var>start node</var> from <var>parent</var>, then set <var>start
+ node</var> to <var>parent</var>.
+
+ <li>While <var>end node</var> is an <span>editable</span> <span>inline
+ node</span> with [[nodelength]] 0, let <var>parent</var> be its [[parent]],
+ then remove <var>end node</var> from <var>parent</var>, then set <var>end
+ node</var> to <var>parent</var>.
+
<li>If <var>start block</var> is not <span>in the same editing host</span> as
<var>end block</var>, or <var>start block</var> is neither an <span>editing
host</span> nor a <span>prohibited paragraph child</span>, or <var>end
block</var> is neither an <span>editing host</span> nor a <span>prohibited
paragraph child</span>, or <var>start block</var> and <var>end block</var>
- are the same, abort these steps.
+ are the same:
+ <!-- Then we don't try to merge anything. -->
+
+ <ol>
+ <li>If <var>start node</var> is an [[element]] with no [[children]], is
+ either <span>editable</span> or an <span>editing host</span>, and is not an
+ <span>inline node</span>, call [[createelement|"br"]] on the
+ [[contextobject]] and append the result as the last [[child]] of <var>start
+ node</var>.
+
+ <li>If <var>end node</var> is an [[element]] with no [[children]], is
+ either <span>editable</span> or an <span>editing host</span>, and is not an
+ <span>inline node</span>, call [[createelement|"br"]] on the
+ [[contextobject]] and append the result as the last [[child]] of <var>end
+ node</var>.
+
+ <li>Abort these steps.
+ </ol>
<li>If <var>start block</var> is an [[ancestor]] of <var>end block</var>:
<!-- Just repeatedly blow up the end block. -->
@@ -1074,18 +1109,17 @@
<li>If the [[child]] of <var>range</var>'s [[startnode]] with [[index]]
equal to its [[startoffset]] is a [[br]] and is not the first member of
<var>children</var>, remove that [[br]] from its [[parent]].
-
- <li>Abort these steps.
</ol>
- <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
- (<var>start block</var>, [[nodelength]] of <var>start block</var>).
-
- <li>If <var>start block</var> is a [[descendant]] of <var>end block</var>:
+ <li>Otherwise, if <var>start block</var> is a [[descendant]] of <var>end
+ block</var>:
<!-- Pull in everything that comes after <var>start block</var>, until we hit
a br or prohibited paragraph child. -->
<ol>
+ <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
+ (<var>start block</var>, [[nodelength]] of <var>start block</var>).
+
<li>Let <var>reference node</var> be <var>start block</var>.
<li>While <var>reference node</var> is not a [[child]] of <var>end
@@ -1098,19 +1132,28 @@
<li>If the [[nextsibling]] of <var>reference node</var> is a [[br]], remove
it from its [[parent]].
-
- <li>Abort these steps.
</ol>
+ <li>Otherwise:
<!-- In the last case, just move all the children of the end block to the
start block, and then get rid of any elements we emptied that way. -->
- <li>While <var>end block</var> has [[children]], append the first [[child]]
- of <var>end block</var> to <var>start block</var>, <span>preserving
- ranges</span>.
-
- <li>While <var>end block</var> has no [[children]], let <var>parent</var> be
- the [[parent]] of <var>end block</var>, then remove <var>end block</var> from
- <var>parent</var>, then set <var>end block</var> to <var>parent</var>.
+
+ <ol>
+ <li>Set the [[rangestart]] and [[rangeend]] of <var>range</var> to
+ (<var>start block</var>, [[nodelength]] of <var>start block</var>).
+
+ <li>While <var>end block</var> has [[children]], append the first [[child]]
+ of <var>end block</var> to <var>start block</var>, <span>preserving
+ ranges</span>.
+
+ <li>While <var>end block</var> has no [[children]], let <var>parent</var> be
+ the [[parent]] of <var>end block</var>, then remove <var>end block</var> from
+ <var>parent</var>, then set <var>end block</var> to <var>parent</var>.
+ </ol>
+
+ <li>If <var>start block</var> has no [[children]], call
+ [[createelement|"br"]] on the [[contextobject]] and append the result as the
+ last [[child]] of <var>start block</var>.
</ol>
<p>To move a [[node]] to a new location, <dfn>preserving ranges</dfn>, remove
@@ -2285,6 +2328,25 @@
<!-- I'd have expected the value to be the URL, but guess not. -->
+<h3><dfn>The <code title>delete</code> command</dfn></h3>
+<!-- Not really specifically "inline", but I didn't want to create a new
+section just for it. -->
+
+<p><span>Action</span>:
+
+<ol>
+ <li>If the <span>active range</span> is not <code data-anolis-spec=domrange
+ title=dom-Range-collapsed>collapsed</code>, <span>delete the selection</span>
+ and abort these steps.
+
+ <p class=XXX>Maybe we sometimes want to do the following even if it isn't
+ collapsed? WebKit seems to do some normalization on the range before
+ deciding whether it's collapsed, and that sounds like a good idea.
+
+ <li class=XXX>The stuff where we delete the previous character goes here.
+</ol>
+
+
<h3><dfn>The <code title>fontName</code> command</dfn></h3>
<p><span>Action</span>: <span>Decompose</span> the <span>active range</span>,
@@ -4980,12 +5042,25 @@
<h2>Additional requirements</h2>
+<p class=XXX>It has been <a
+href=http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-December/024628.html>suggested</a>
+that some things here need to be platform-dependent, not fully standardized.
+For now I'm standardizing them anyway, because the large majority of behavior
+should be platform-agnostic. If anyone has suggestions as to particular things
+that should be left up to platform behavior, please say so.
+
<p>When the user instructs the user agent to insert a line break inside an
<span>editing host</span>, such as by pressing the Return key while the cursor
is in an <span>editable</span> [[node]], the user agent must take the
<span>action</span> for <span>the <code title>insertParagraph</code>
command</span>.
+<p>When the user instructs the user agent to delete the previous character
+inside an <span>editing host</span>, such as by pressing the Backspace key
+while the cursor is in an <span>editable</span> [[node]], the user agent must
+take the <span>action</span> for <span>the <code title>delete</code>
+command</span>.
+
<h2 class=no-num>Acknowledgements</h2>
<p>Thanks to: