--- a/autoimplementation.html Sun Jun 19 10:59:43 2011 -0600
+++ b/autoimplementation.html Sun Jun 19 12:33:21 2011 -0600
@@ -63,14 +63,22 @@
for (var i = 0; i < tests[command].length; i++) {
// This code actually focuses and clicks everything because for some
// reason, anything else doesn't work in IE9 . . .
+ //
+ // In case the input contains something unpleasant like newlines, we
+ // smuggle in the string as a data attribute, not just the value. This
+ // is probably unnecessarily magic.
if (typeof tests[command][i] == "string") {
inputs[0].value = tests[command][i];
+ inputs[0].setAttribute("data-input", tests[command][i]);
if (inputs.length == 2) {
inputs[1].value = defaultValues[command];
+ inputs[1].setAttribute("data-input", defaultValues[command]);
}
} else {
inputs[0].value = tests[command][i][1];
+ inputs[0].setAttribute("data-input", tests[command][i][1]);
inputs[1].value = tests[command][i][0];
+ inputs[1].setAttribute("data-input", tests[command][i][0]);
}
inputs[0].focus();
addTestButton.click();
@@ -97,11 +105,22 @@
var test;
var inputs = document.getElementById(command).getElementsByTagName("input");
+
if (inputs.length == 1) {
- test = inputs[0].value;
+ if (inputs[0].hasAttribute("data-input")) {
+ test = inputs[0].getAttribute("data-input");
+ } else {
+ test = inputs[0].value;
+ }
} else {
- test = [inputs[1].value, inputs[0].value];
+ if (inputs[0].hasAttribute("data-input")) {
+ test = [inputs[1].getAttribute("data-input"), inputs[0].getAttribute("data-input")];
+ inputs[1].removeAttribute("data-input");
+ } else {
+ test = [inputs[1].value, inputs[0].value];
+ }
}
+ inputs[0].removeAttribute("data-input");
doInputCell(tr, test);
doSpecCell(tr, test, command, false);
--- a/editcommands.html Sun Jun 19 10:59:43 2011 -0600
+++ b/editcommands.html Sun Jun 19 12:33:21 2011 -0600
@@ -5043,10 +5043,17 @@
<ol>
<li><a href=#delete-the-contents>Delete the contents</a> of the <a href=#active-range>active range</a>.
+ <!-- Firefox 5.0a2 seems to not do this if value is empty; Chrome 14 dev and
+ Opera 11.11 do. -->
<li>Let <var title="">frag</var> be the result of calling <code class=external data-anolis-spec=domps title=dom-Range-createContextualFragment><a href=http://html5.org/specs/dom-parsing.html#dom-range-createcontextualfragment>createContextualFragment(<var title="">value</var>)</a></code>
on the <a href=#active-range>active range</a>.
+ <p class=XXX>This has some interesting consequences. For instance, table
+ cells and similar will just vanish if they're not in an appropriate place;
+ and inside a script or style or xmp or such, the argument will effectively be
+ HTML-escaped before use. Some of these consequences might be undesirable.
+
<li>Let <var title="">last child</var> be the <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> of <var title="">frag</var>.
<li>If <var title="">last child</var> is null, abort these steps.
@@ -5452,15 +5459,53 @@
<li>If <var title="">value</var> is the empty string, abort these steps.
+ <p class=XXX>WebKit does magic for tabs, and actually handles newlines as
+ newlines.
+
+ <p class=XXX>This doesn't work well if the input contains things that aren't
+ supposed to appear in HTML, like carriage returns or nulls. Nor is it going
+ to work well if the current cursor position is in between two halves of a
+ non-BMP character. This will result in unserializability. The current spec
+ disregards this, as Chrome 14 dev does.
+
+ <li>Let <var title="">node</var> and <var title="">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> <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 <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>.
+
+ <!--
+ Just to be tidy, add to an existing text node if there is one. Firefox 5.0a2
+ only adds to an existing one if the range is in a text node. IE9, Chrome 14
+ dev, and Opera 11.11 also add to an existing text node if the range is in an
+ element adjacent to a text node. If there are two text nodes and it's in
+ between, like foo{}bar, IE and Opera add to the first, Chrome adds to the
+ second, although it probably doesn't matter in practice exactly which we
+ choose.
+ -->
+ <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> whose <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> is <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=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, 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 <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>.
+
+ <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> whose <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> is <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=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, 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>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:
+
+ <ol>
+ <li>Call <code class=external data-anolis-spec=domcore title=dom-CharacterData-insertData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-insertdata>insertData(<var title="">offset</var>, <var title="">value</var>)</a></code> on
+ <var title="">node</var>.
+
+ <li>Add the <a href=http://es5.github.com/#x15.5.5.1>length</a> of
+ <var title="">value</var> to <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="">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>Abort these steps.
+ </ol>
+
<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/implementation.js Sun Jun 19 10:59:43 2011 -0600
+++ b/implementation.js Sun Jun 19 12:33:21 2011 -0600
@@ -5600,6 +5600,45 @@
return;
}
+ // "Let node and offset be the active range's start node and offset."
+ var node = getActiveRange().startContainer;
+ var offset = getActiveRange().startOffset;
+
+ // "If node has a child whose index is offset − 1, and that child is a
+ // Text node, set node to that child, then set offset to node's
+ // length."
+ if (0 <= offset - 1
+ && offset - 1 < node.childNodes.length
+ && node.childNodes[offset - 1].nodeType == Node.TEXT_NODE) {
+ node = node.childNodes[offset - 1];
+ offset = getNodeLength(node);
+ }
+
+ // "If node has a child whose index is offset, and that child is a Text
+ // node, set node to that child, then set offset to zero."
+ if (0 <= offset
+ && offset < node.childNodes.length
+ && node.childNodes[offset].nodeType == Node.TEXT_NODE) {
+ node = node.childNodes[offset];
+ offset = 0;
+ }
+
+ // "If node is a Text node:"
+ if (node.nodeType == Node.TEXT_NODE) {
+ // "Call insertData(offset, value) on node."
+ node.insertData(offset, value);
+
+ // "Add the length of value to offset."
+ offset += value.length;
+
+ // "Call collapse(node, offset) on the context object's Selection."
+ getActiveRange().setStart(node, offset);
+ getActiveRange().setEnd(node, offset);
+
+ // "Abort these steps."
+ return;
+ }
+
// "Let text be the result of calling createTextNode(value) on the
// context object."
var text = document.createTextNode(value);
--- a/preprocess Sun Jun 19 10:59:43 2011 -0600
+++ b/preprocess Sun Jun 19 12:33:21 2011 -0600
@@ -116,6 +116,7 @@
'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>',
'extend': '<code data-anolis-spec=domrange title=dom-Selection-extend>extend(\\1)</code>',
+ 'insertdata': '<code data-anolis-spec=domcore title=dom-CharacterData-insertData>insertData(\\1)</code>',
'insertnode': '<code data-anolis-spec=domrange title=dom-Range-insertNode>insertNode(\\1)</code>',
'selcollapse': '<code data-anolis-spec=domrange title=dom-Selection-collapse>collapse(\\1)</code>',
'setattribute': '<code data-anolis-spec=domcore title=dom-Element-setAttribute>setAttribute(\\1)</code>',
--- a/source.html Sun Jun 19 10:59:43 2011 -0600
+++ b/source.html Sun Jun 19 12:33:21 2011 -0600
@@ -5048,11 +5048,18 @@
<ol>
<li><span>Delete the contents</span> of the <span>active range</span>.
+ <!-- Firefox 5.0a2 seems to not do this if value is empty; Chrome 14 dev and
+ Opera 11.11 do. -->
<li>Let <var>frag</var> be the result of calling <code data-anolis-spec=domps
title=dom-Range-createContextualFragment>createContextualFragment(<var>value</var>)</code>
on the <span>active range</span>.
+ <p class=XXX>This has some interesting consequences. For instance, table
+ cells and similar will just vanish if they're not in an appropriate place;
+ and inside a script or style or xmp or such, the argument will effectively be
+ HTML-escaped before use. Some of these consequences might be undesirable.
+
<li>Let <var>last child</var> be the [[lastchild]] of <var>frag</var>.
<li>If <var>last child</var> is null, abort these steps.
@@ -5471,17 +5478,55 @@
<li>If <var>value</var> is the empty string, abort these steps.
+ <p class=XXX>WebKit does magic for tabs, and actually handles newlines as
+ newlines.
+
+ <p class=XXX>This doesn't work well if the input contains things that aren't
+ supposed to appear in HTML, like carriage returns or nulls. Nor is it going
+ to work well if the current cursor position is in between two halves of a
+ non-BMP character. This will result in unserializability. The current spec
+ disregards this, as Chrome 14 dev does.
+
+ <li>Let <var>node</var> and <var>offset</var> be the <span>active
+ range</span>'s [[startnode]] and [[bpoffset]].
+
+ <!--
+ Just to be tidy, add to an existing text node if there is one. Firefox 5.0a2
+ only adds to an existing one if the range is in a text node. IE9, Chrome 14
+ dev, and Opera 11.11 also add to an existing text node if the range is in an
+ element adjacent to a text node. If there are two text nodes and it's in
+ between, like foo{}bar, IE and Opera add to the first, Chrome adds to the
+ second, although it probably doesn't matter in practice exactly which we
+ choose.
+ -->
+ <li>If <var>node</var> has a [[child]] whose [[index]] is <var>offset</var>
+ − 1, and that [[child]] is a [[text]] node, set <var>node</var> to that
+ [[child]], then set <var>offset</var> to <var>node</var>'s [[length]].
+
+ <li>If <var>node</var> has a [[child]] whose [[index]] is <var>offset</var>,
+ and that [[child]] is a [[text]] node, set <var>node</var> to that [[child]],
+ then set <var>offset</var> to zero.
+
+ <li>If <var>node</var> is a [[text]] node:
+
+ <ol>
+ <li>Call [[insertdata|<var>offset</var>, <var>value</var>]] on
+ <var>node</var>.
+
+ <li>Add the <a href=http://es5.github.com/#x15.5.5.1>length</a> of
+ <var>value</var> to <var>offset</var>.
+
+ <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
+ [[contextobject]]'s [[selection]].
+
+ <li>Abort these steps.
+ </ol>
+
<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
--- a/tests.js Sun Jun 19 10:59:43 2011 -0600
+++ b/tests.js Sun Jun 19 12:33:21 2011 -0600
@@ -1378,6 +1378,11 @@
//@{
'foo[]bar',
'foo[bar]baz',
+ ['', 'foo[bar]baz'],
+ ['\0', 'foo[bar]baz'],
+ ['\x07', 'foo[bar]baz'],
+ ['\ud800', 'foo[bar]baz'],
+
['<b>', 'foo[bar]baz'],
['<b>abc', 'foo[bar]baz'],
['<p>abc', '<p>foo[bar]baz'],
@@ -1388,6 +1393,9 @@
['abc', '<xmp>f[o]o</xmp>'],
['<b>abc</b>', '<xmp>f[o]o</xmp>'],
+ ['abc', '<script>f[o]o</script>bar'],
+ ['<b>abc</b>', '<script>f[o]o</script>bar'],
+
['<a>abc</a>', '<a>f[o]o</a>'],
['<a href=/>abc</a>', '<a href=.>f[o]o</a>'],
['<hr>', '<p>f[o]o'],
@@ -1777,11 +1785,18 @@
//@{
'foo[bar]baz',
['', 'foo[bar]baz'],
+
['\t', 'foo[]bar'],
[' ', 'foo[]bar'],
+ ['&', 'foo[]bar'],
['\n', 'foo[]bar'],
['\r', 'foo[]bar'],
['\r\n', 'foo[]bar'],
+ ['abc\ndef', 'foo[]bar'],
+ ['\0', 'foo[]bar'],
+ ['\ud800', 'foo[]bar'],
+ ['\x07', 'foo[]bar'],
+
'foo[]bar',
'<p>foo[]',
'<p>foo</p>{}',
@@ -2790,6 +2805,7 @@
};
var defaultValues = {
+//@{
backcolor: "#FF8888",
createlink: "http://www.google.com/",
fontname: "sans-serif",
@@ -2802,6 +2818,7 @@
insertimage: "/img/lion.svg",
inserttext: "a",
};
+//@}
var notes = {
backcolor: '<strong>Note:</strong> No spec has yet been written, so the spec column does nothing.',
@@ -2810,6 +2827,7 @@
};
var doubleTestingCommands = [
+//@{
"backcolor",
"bold",
"fontname",
@@ -2825,6 +2843,52 @@
"superscript",
"underline",
];
+//@}
+
+function prettyPrint(value) {
+//@{
+ // Stolen from testharness.js
+ for (var i = 0; i < 32; i++) {
+ var replace = "\\";
+ switch (i) {
+ case 0: replace += "0"; break;
+ case 1: replace += "x01"; break;
+ case 2: replace += "x02"; break;
+ case 3: replace += "x03"; break;
+ case 4: replace += "x04"; break;
+ case 5: replace += "x05"; break;
+ case 6: replace += "x06"; break;
+ case 7: replace += "x07"; break;
+ case 8: replace += "b"; break;
+ case 9: replace += "t"; break;
+ case 10: replace += "n"; break;
+ case 11: replace += "v"; break;
+ case 12: replace += "f"; break;
+ case 13: replace += "r"; break;
+ case 14: replace += "x0e"; break;
+ case 15: replace += "x0f"; break;
+ case 16: replace += "x10"; break;
+ case 17: replace += "x11"; break;
+ case 18: replace += "x12"; break;
+ case 19: replace += "x13"; break;
+ case 20: replace += "x14"; break;
+ case 21: replace += "x15"; break;
+ case 22: replace += "x16"; break;
+ case 23: replace += "x17"; break;
+ case 24: replace += "x18"; break;
+ case 25: replace += "x19"; break;
+ case 26: replace += "x1a"; break;
+ case 27: replace += "x1b"; break;
+ case 28: replace += "x1c"; break;
+ case 29: replace += "x1d"; break;
+ case 30: replace += "x1e"; break;
+ case 31: replace += "x1f"; break;
+ }
+ value = value.replace(String.fromCharCode(i), replace);
+ }
+ return value;
+}
+//@}
function doSetup(selector, idx) {
//@{
@@ -2849,6 +2913,7 @@
inputCell.firstChild.innerHTML = test;
inputCell.lastChild.textContent = inputCell.firstChild.innerHTML;
if (value !== null) {
+ value = prettyPrint(value);
inputCell.lastChild.textContent += ' (value: "' + value + '")';
}
tr.appendChild(inputCell);