--- a/editcommands.html Sun Jun 19 10:41:54 2011 -0600
+++ b/editcommands.html Sun Jun 19 10:59:43 2011 -0600
@@ -117,12 +117,13 @@
<li><a href=#the-inserthorizontalrule-command><span class=secno>7.15 </span>The <code title="">insertHorizontalRule</code> command</a></li>
<li><a href=#the-insertorderedlist-command><span class=secno>7.16 </span>The <code title="">insertOrderedList</code> command</a></li>
<li><a href=#the-insertparagraph-command><span class=secno>7.17 </span>The <code title="">insertParagraph</code> command</a></li>
- <li><a href=#the-insertunorderedlist-command><span class=secno>7.18 </span>The <code title="">insertUnorderedList</code> command</a></li>
- <li><a href=#the-justifycenter-command><span class=secno>7.19 </span>The <code title="">justifyCenter</code> command</a></li>
- <li><a href=#the-justifyfull-command><span class=secno>7.20 </span>The <code title="">justifyFull</code> command</a></li>
- <li><a href=#the-justifyleft-command><span class=secno>7.21 </span>The <code title="">justifyLeft</code> command</a></li>
- <li><a href=#the-justifyright-command><span class=secno>7.22 </span>The <code title="">justifyRight</code> command</a></li>
- <li><a href=#the-outdent-command><span class=secno>7.23 </span>The <code title="">outdent</code> command</a></ol></li>
+ <li><a href=#the-inserttext-command><span class=secno>7.18 </span>The <code title="">insertText</code> command</a></li>
+ <li><a href=#the-insertunorderedlist-command><span class=secno>7.19 </span>The <code title="">insertUnorderedList</code> command</a></li>
+ <li><a href=#the-justifycenter-command><span class=secno>7.20 </span>The <code title="">justifyCenter</code> command</a></li>
+ <li><a href=#the-justifyfull-command><span class=secno>7.21 </span>The <code title="">justifyFull</code> command</a></li>
+ <li><a href=#the-justifyleft-command><span class=secno>7.22 </span>The <code title="">justifyLeft</code> command</a></li>
+ <li><a href=#the-justifyright-command><span class=secno>7.23 </span>The <code title="">justifyRight</code> command</a></li>
+ <li><a href=#the-outdent-command><span class=secno>7.24 </span>The <code title="">outdent</code> command</a></ol></li>
<li><a href=#miscellaneous-commands><span class=secno>8 </span>Miscellaneous commands</a>
<ol>
<li><a href=#the-selectall-command><span class=secno>8.1 </span>The <code title="">selectAll</code> command</a></li>
@@ -5434,36 +5435,70 @@
</ol>
-<h3 id=the-insertunorderedlist-command><span class=secno>7.18 </span><dfn>The <code title="">insertUnorderedList</code> command</dfn></h3>
+<h3 id=the-inserttext-command><span class=secno>7.18 </span><dfn>The <code title="">insertText</code> command</dfn></h3>
+
+<!--
+Supported only by WebKit. Tests in other browsers were manual. In the manual
+tests, where the value was always "a", IE9 and Firefox 5.0a2 match the spec
+exactly as far as I can tell; Chrome 14 dev and Opera 11.11 might match it in
+theory, but normalize the selection first, so they don't match it in practice.
+-->
+
+<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>.
+ <!-- Chrome 14 dev does this even if passed the empty string. -->
+
+ <li>If <var title="">value</var> is the empty string, abort these steps.
+
+ <li>Let <var title="">text</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createTextNode><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createtextnode>createTextNode(<var title="">value</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>.
+
+ <p class=XXX>We should actually add to existing text nodes if present, just
+ to be tidy.
+
+ <p class=XXX>WebKit seems to strip newlines from programmatic input, and does
+ magic for tabs.
+
+ <li>Call <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="">text</var>)</a></code> on the <a href=#active-range>active range</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="">text</var>, <var title="">length</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>, where <var title="">length</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="">text</var>.
+</ol>
+
+
+<h3 id=the-insertunorderedlist-command><span class=secno>7.19 </span><dfn>The <code title="">insertUnorderedList</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#toggle-lists>Toggle lists</a> with <var title="">tag name</var>
"ul".
-<h3 id=the-justifycenter-command><span class=secno>7.19 </span><dfn>The <code title="">justifyCenter</code> command</dfn></h3>
+<h3 id=the-justifycenter-command><span class=secno>7.20 </span><dfn>The <code title="">justifyCenter</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
<var title="">alignment</var> "center".
-<h3 id=the-justifyfull-command><span class=secno>7.20 </span><dfn>The <code title="">justifyFull</code> command</dfn></h3>
+<h3 id=the-justifyfull-command><span class=secno>7.21 </span><dfn>The <code title="">justifyFull</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
<var title="">alignment</var> "justify".
-<h3 id=the-justifyleft-command><span class=secno>7.21 </span><dfn>The <code title="">justifyLeft</code> command</dfn></h3>
+<h3 id=the-justifyleft-command><span class=secno>7.22 </span><dfn>The <code title="">justifyLeft</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
<var title="">alignment</var> "left".
-<h3 id=the-justifyright-command><span class=secno>7.22 </span><dfn>The <code title="">justifyRight</code> command</dfn></h3>
+<h3 id=the-justifyright-command><span class=secno>7.23 </span><dfn>The <code title="">justifyRight</code> command</dfn></h3>
<p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
<var title="">alignment</var> "right".
-<h3 id=the-outdent-command><span class=secno>7.23 </span><dfn>The <code title="">outdent</code> command</dfn></h3>
+<h3 id=the-outdent-command><span class=secno>7.24 </span><dfn>The <code title="">outdent</code> command</dfn></h3>
<p><a href=#action>Action</a>:
@@ -5666,6 +5701,23 @@
take the <a href=#action>action</a> for <a href=#the-delete-command>the <code title="">delete</code>
command</a>.
+<p>When the user instructs the user agent to delete the next character inside
+an <a href=#editing-host>editing host</a>, such as by pressing the Delete 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-forwarddelete-command>the <code title="">forwardDelete</code>
+command</a>.
+
+<p>When the user instructs the user agent to insert text inside an
+<a href=#editing-host>editing host</a>, such as by typing on the keyboard 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-inserttext-command>the <code title="">insertText</code> command</a>,
+with <var title="">value</var> equal to the text the user provided. If the user inserts
+multiple characters at once or in quick succession, this specification does not
+define whether it is treated as one insertion or several consecutive
+insertions. If the inserted text includes line breaks, the user agent must not
+process those as part of this paragraph, but instead according to the
+instructions above for processing line breaks.
+
<h2 class=no-num id=acknowledgements>Acknowledgements</h2>
<p>Thanks to:
--- a/implementation.js Sun Jun 19 10:41:54 2011 -0600
+++ b/implementation.js Sun Jun 19 10:59:43 2011 -0600
@@ -5588,6 +5588,33 @@
};
//@}
+///// The insertText command /////
+//@{
+commands.inserttext = {
+ action: function(value) {
+ // "Delete the contents of the active range."
+ deleteContents(getActiveRange());
+
+ // "If value is the empty string, abort these steps."
+ if (value == "") {
+ return;
+ }
+
+ // "Let text be the result of calling createTextNode(value) on the
+ // context object."
+ var text = document.createTextNode(value);
+
+ // "Call insertNode(text) on the active range."
+ getActiveRange().insertNode(text);
+
+ // "Call collapse(text, length) on the context object's Selection,
+ // where length is the length of text."
+ getActiveRange().setStart(text, text.length);
+ getActiveRange().setEnd(text, text.length);
+ }
+};
+//@}
+
///// The insertUnorderedList command /////
commands.insertunorderedlist = {
// "Toggle lists with tag name "ul"."
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/inserttexttest.html Sun Jun 19 10:59:43 2011 -0600
@@ -0,0 +1,34 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Text insertion tests</title>
+<link rel=stylesheet href=tests.css>
+<p>Legend: {[ are the selection anchor, }] are the selection focus, {}
+represent an element boundary point, [] represent a text node boundary point.
+Syntax and some of the tests taken from <a
+href=http://www.browserscope.org/richtext2/test>Browserscope</a>. data-start
+and data-end attributes also represent element boundary points, with the node
+being the element with the attribute and the offset given as the attribute
+value, for cases where HTML parsing doesn't allow text nodes. Currently we
+don't really pay attention to reversed selections at all, so they might get
+displayed as forwards or such.
+
+<p><input type=button value="Clear cached results" onclick="clearCachedResults()">
+
+<div id=tests>
+ <input type=button value="Run tests" onclick="runTests()">
+ <table border=1><tr><th>Input<th>Spec<th>Browser<th>Same</table>
+ <p><label>New test input: <input></label> <input type=button value="Add test" onclick="addTest()">
+</div>
+
+<div id=overlay>Tap the A key repeatedly until this annoying message
+disappears! (But not too quickly. And don't hit any other keys or click with
+the mouse anywhere, it will mess it up.<span id=testcount> <span></span>
+manual test(s) remain.</span>)</div>
+
+<script src=implementation.js></script>
+<script src=tests.js></script>
+<script>
+var command = "inserttext";
+var keyname = "textinsertion";
+</script>
+<script src=manualtest.js></script>
--- a/manualtest.js Sun Jun 19 10:41:54 2011 -0600
+++ b/manualtest.js Sun Jun 19 10:59:43 2011 -0600
@@ -1,4 +1,6 @@
-var tests = tests[command];
+// We don't support non-default values for manual tests, so only strings need
+// apply.
+var tests = tests[command].filter(function(test) { return typeof test == "string"});
var testsRunning = false;
@@ -38,8 +40,16 @@
var tr = doSetup("#tests table", 0);
var input = document.querySelector("#tests label input");
var test = input.value;
+ if (command == "inserttext") {
+ // Yay hack
+ test = ["a", test];
+ }
doInputCell(tr, test);
doSpecCell(tr, test, command, false);
+ if (typeof test != "string") {
+ // Yay hack
+ test = test[1];
+ }
if (localStorage.getItem(keyname + "test-" + test) !== null) {
// Yay, I get to cheat. Remove the overlay div so the user doesn't
// keep hitting the key, in case it takes a while.
--- a/source.html Sun Jun 19 10:41:54 2011 -0600
+++ b/source.html Sun Jun 19 10:59:43 2011 -0600
@@ -5454,6 +5454,42 @@
</ol>
<!-- @} -->
+<h3><dfn>The <code title>insertText</code> command</dfn></h3>
+<!-- @{ -->
+<!--
+Supported only by WebKit. Tests in other browsers were manual. In the manual
+tests, where the value was always "a", IE9 and Firefox 5.0a2 match the spec
+exactly as far as I can tell; Chrome 14 dev and Opera 11.11 might match it in
+theory, but normalize the selection first, so they don't match it in practice.
+-->
+
+<p><span>Action</span>:
+
+<ol>
+ <li><span>Delete the contents</span> of the <span>active range</span>.
+ <!-- Chrome 14 dev does this even if passed the empty string. -->
+
+ <li>If <var>value</var> is the empty string, abort these steps.
+
+ <li>Let <var>text</var> be the result of calling <code
+ data-anolis-spec=domcore
+ title=dom-Document-createTextNode>createTextNode(<var>value</var>)</code> on
+ the [[contextobject]].
+
+ <p class=XXX>We should actually add to existing text nodes if present, just
+ to be tidy.
+
+ <p class=XXX>WebKit seems to strip newlines from programmatic input, and does
+ magic for tabs.
+
+ <li>Call [[insertnode|<var>text</var>]] on the <span>active range</span>.
+
+ <li>Call [[selcollapse|<var>text</var>, <var>length</var>]] on the
+ [[contextobject]]'s [[selection]], where <var>length</var> is the [[length]]
+ of <var>text</var>.
+</ol>
+<!-- @} -->
+
<h3><dfn>The <code title>insertUnorderedList</code> command</dfn></h3>
<p><span>Action</span>: <span>Toggle lists</span> with <var>tag name</var>
"ul".
@@ -5692,6 +5728,23 @@
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>.
+
+<p>When the user instructs the user agent to delete the next character inside
+an <span>editing host</span>, such as by pressing the Delete 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>forwardDelete</code>
+command</span>.
+
+<p>When the user instructs the user agent to insert text inside an
+<span>editing host</span>, such as by typing on the keyboard while the cursor
+is in an <span>editable</span> [[node]], the user agent must take the
+<span>action</span> for <span>the <code title>insertText</code> command</span>,
+with <var>value</var> equal to the text the user provided. If the user inserts
+multiple characters at once or in quick succession, this specification does not
+define whether it is treated as one insertion or several consecutive
+insertions. If the inserted text includes line breaks, the user agent must not
+process those as part of this paragraph, but instead according to the
+instructions above for processing line breaks.
<!-- @} -->
<h2 class=no-num>Acknowledgements</h2>
--- a/tests.js Sun Jun 19 10:41:54 2011 -0600
+++ b/tests.js Sun Jun 19 10:59:43 2011 -0600
@@ -1773,6 +1773,33 @@
'foo<a href=foo>[]bar</a>',
],
//@}
+ inserttext: [
+ //@{
+ 'foo[bar]baz',
+ ['', 'foo[bar]baz'],
+ ['\t', 'foo[]bar'],
+ [' ', 'foo[]bar'],
+ ['\n', 'foo[]bar'],
+ ['\r', 'foo[]bar'],
+ ['\r\n', 'foo[]bar'],
+ 'foo[]bar',
+ '<p>foo[]',
+ '<p>foo</p>{}',
+ '<p>[]foo',
+ '<p>{}foo',
+ '{}<p>foo',
+ '<p>foo</p>{}<p>bar</p>',
+ '<b>foo[]</b>bar',
+ '<b>foo</b>[]bar',
+ 'foo<b>{}</b>bar',
+ '<a>foo[]</a>bar',
+ '<a>foo</a>[]bar',
+ '<a href=/>foo[]</a>bar',
+ '<a href=/>foo</a>[]bar',
+ '<p>fo[o<p>b]ar',
+ '<p>fo[o<p>bar<p>b]az',
+ ],
+ //@}
insertunorderedlist: [
//@{
'foo[]bar',
@@ -2773,6 +2800,7 @@
inserthorizontalrule: "",
inserthtml: "ab<b>c</b>d",
insertimage: "/img/lion.svg",
+ inserttext: "a",
};
var notes = {