--- a/autoimplementation.html Wed Jul 13 13:55:04 2011 -0600
+++ b/autoimplementation.html Thu Jul 14 12:24:49 2011 -0600
@@ -156,11 +156,6 @@
test = test[1];
}
- if (command == "hilitecolor" && navigator.userAgent.indexOf("MSIE") != -1) {
- // IE behaves differently, and I want to see how it works.
- command = "backcolor";
- }
-
if (command == "hilitecolor") {
// Firefox refuses to do anything unless styleWithCSS is true.
styleWithCss = true;
@@ -187,8 +182,23 @@
try {
document.execCommand("styleWithCSS", false, styleWithCss);
} catch (e) {}
+
+ try { var beforeIndeterm = document.queryCommandIndeterm(command) }
+ catch(e) { beforeIndeterm = "Exception" }
+ try { var beforeState = document.queryCommandState(command) }
+ catch(e) { beforeState = "Exception" }
+ try { var beforeValue = document.queryCommandValue(command) }
+ catch(e) { beforeValue = "Exception" }
+
document.execCommand(command, false, value);
+ try { var afterIndeterm = document.queryCommandIndeterm(command) }
+ catch(e) { afterIndeterm = "Exception" }
+ try { var afterState = document.queryCommandState(command) }
+ catch(e) { afterState = "Exception" }
+ try { var afterValue = document.queryCommandValue(command) }
+ catch(e) { afterValue = "Exception" }
+
testDiv.contentEditable = "inherit";
testDiv.removeAttribute("spellcheck");
var compareDiv1 = testDiv.cloneNode(true);
@@ -230,7 +240,17 @@
browserCell.innerHTML.replace(/<div><\/div>$/, "");
}
+ if (document.body.hasAttribute("bgcolor")) {
+ var bgColor = document.body.getAttribute("bgcolor");
+ document.body.removeAttribute("bgcolor");
+ throw 'bgcolor="' + bgColor +'" added to body!';
+ }
+
browserCell.lastChild.textContent = browserCell.firstChild.innerHTML;
+ browserCell.lastChild.appendChild(queryOutputHelper(
+ beforeIndeterm, beforeState, beforeValue,
+ afterIndeterm, afterState, afterValue,
+ command, value));
} catch (e) {
browserCellException(e, testDiv, browserCell);
}
--- a/editcommands.html Wed Jul 13 13:55:04 2011 -0600
+++ b/editcommands.html Thu Jul 14 12:24:49 2011 -0600
@@ -60,7 +60,7 @@
<body class=draft>
<div class=head id=head>
<h1>HTML Editing Commands</h1>
-<h2 class="no-num no-toc" id=work-in-progress-—-last-update-13-july-2011>Work in Progress — Last Update 13 July 2011</h2>
+<h2 class="no-num no-toc" id=work-in-progress-—-last-update-14-july-2011>Work in Progress — Last Update 14 July 2011</h2>
<dl>
<dt>Editor
<dd>Aryeh Gregor <<a href=mailto:ayg@aryeh.name>ayg@aryeh.name</a>>
@@ -658,6 +658,9 @@
<li>If <var title="">command</var> is not <a href=#enabled>enabled</a>, return false.
+ <li>If the <a href=#state-override>state override</a> for <var title="">command</var> is set, return
+ it.
+
<li>Return true if <var title="">command</var>'s <a href=#state>state</a> is true, otherwise
false.
</ol>
@@ -694,12 +697,36 @@
seems to return the string "false", and IE9 seems to return boolean false.
-->
+ <li>If the <a href=#value-override>value override</a> for <var title="">command</var> is set, return
+ it.
+
<li>Return <var title="">command</var>'s <a href=#value>value</a>.
</ol>
<p>All of these methods must treat their <var title="">command</var> argument <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#ascii-case-insensitive title="ASCII case-insensitive">ASCII
case-insensitively</a>.
+<p>The methods in this section have been designed so that the following
+invariants hold after <code><a href=#execcommand()>execCommand()</a></code> is called, assuming it didn't
+throw an exception:
+
+<ul>
+ <li><code><a href=#querycommandindeterm()>queryCommandIndeterm()</a></code> will return false (or throw an
+ exception).
+
+ <li><code><a href=#querycommandstate()>queryCommandState()</a></code> will return the opposite of what it did
+ before <code><a href=#execcommand()>execCommand()</a></code> was called (or throw an exception).
+
+ <li><code><a href=#querycommandvalue()>queryCommandValue()</a></code> will return something equivalent to the
+ value passed to <code><a href=#execcommand()>execCommand()</a></code> (or throw an exception).
+ "Equivalent" here needs to be construed broadly in some cases, such as
+ <a href=#the-fontsize-command>the <code title="">fontSize</code> command</a>.
+</ul>
+
+<p>The first two points do not always hold for <a href=#the-strikethrough-command>the <code title="">strikethrough</code> command</a> or <a href=#the-underline-command>the <code title="">underline</code> command</a>, because it can be impossible to unset
+text-decoration in CSS, but all three points otherwise hold in all cases
+barring bugs.
+
<h2 id=common-definitions><span class=secno>5 </span>Common definitions</h2>
@@ -824,6 +851,17 @@
means of the <code><a href=#execcommand()>execCommand()</a></code> and <code><a href=#querycommandstate()>queryCommandState()</a></code>
methods.)
+<p>For some <a href=#command title=command>commands</a>, each <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> must
+have a boolean <dfn id=state-override>state override</dfn> and/or a string <dfn id=value-override>value
+override</dfn>. These do not change the <a href=#command>command</a>'s
+<a href=#state>state</a> or <a href=#value>value</a>, but change the way some algorithms
+behave, as specified in those algorithms' definitions. Initially, both must be
+unset for every <a href=#command>command</a>. Whenever the number of <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>ranges</a> in the
+<code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code> changes to something different, and whenever a <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point title=concept-boundary-point>boundary point</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> at a given index in the <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code> changes to something
+different, the <a href=#state-override>state override</a> and <a href=#value-override>value override</a> must
+be unset for every <a href=#command>command</a>.
+
<p>When the user agent is instructed to run a particular method, it must follow
the steps defined for that method in the appropriate specification, not act as
though the method had actually been called from JavaScript. In particular,
@@ -1961,14 +1999,18 @@
<li>If <var title="">command</var> is "foreColor", and <var title="">new value</var> is fully
opaque with red, green, and blue components in the range 0 to 255:
+ <!-- See comment for foreColor for discussion. -->
+
+ <p class=XXX>Check this more carefully for what happens if the components
+ are not integers or are out-of-range.
<ol>
<li>Let <var title="">new parent</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("font")</a></code> on the
<code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
- <li>If <var title="">new value</var> is one of the colors listed in the SVG color
- keywords section of CSS3 Color, set the <code class=external data-anolis-spec=html title=dom-font-color><a href=http://www.whatwg.org/html/#dom-font-color>color</a></code> attribute of
- <var title="">new parent</var> to <var title="">new value</var>.
+ <li>If <var title="">new value</var> is an <a href=http://www.w3.org/TR/css3-color/#svg-color>extended color
+ keyword</a>, set the <code class=external data-anolis-spec=html title=dom-font-color><a href=http://www.whatwg.org/html/#dom-font-color>color</a></code> attribute of <var title="">new parent</var> to
+ <var title="">new value</var>.
<li>Otherwise, set the <code class=external data-anolis-spec=html title=dom-font-color><a href=http://www.whatwg.org/html/#dom-font-color>color</a></code> attribute of <var title="">new parent</var>
to the result of applying the <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#rules-for-serializing-simple-color-values>rules for
@@ -2197,6 +2239,39 @@
<ol>
<li>Let <var title="">command</var> be the current <a href=#command>command</a>.
+ <li>If there is no <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 <a href=#effectively-contained>effectively
+ contained</a> in the <a href=#active-range>active range</a>:
+
+ <ol>
+ <li>If <var title="">command</var> is in the following list, set the <a href=#state-override>state
+ override</a> appropriately:
+
+ <dl class=compact>
+ <dt>bold<dd>True if <var title="">new value</var> is not null and is greater than or equal
+ to 600, false otherwise.
+
+ <dt>italic<dd>True if <var title="">new value</var> is "italic" or "oblique", false
+ otherwise.
+
+ <dt>strikethrough<dd>True if <var title="">new value</var> is "line-through", false otherwise.
+
+ <dt>subscript<dd>True if <var title="">new value</var> is "sub", false otherwise.
+
+ <dt>superscript<dd>True if <var title="">new value</var> is "super", false otherwise.
+
+ <dt>underline<dd>True if <var title="">new value</var> is "underline", false otherwise.
+ </dl>
+
+ <li>If <var title="">command</var> has a <a href=#value>value</a> specified, unset the
+ <a href=#value-override>value override</a> if <var title="">new value</var> is null, and set the
+ <a href=#value-override>value override</a> to <var title="">new value</var> if it is not null.
+
+ <p class=XXX>This doesn't work as-is for fontSize, because that uses a
+ different format for the value.
+
+ <li>Abort these steps.
+ </ol>
+
<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 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, 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 neither zero
nor its <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, call <code class=external data-anolis-spec=domcore title=dom-Text-splitText><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-text-splittext>splitText()</a></code> on the <a href=#active-range>active
@@ -2324,11 +2399,15 @@
range</a>, there are two that have distinct <a href=#effective-command-value title="effective command
value">effective command values</a>. Otherwise false.
-<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of 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>.
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
+<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of the first
+<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 that is <a href=#effectively-contained>effectively contained</a>
+in the <a href=#active-range>active range</a>, or if there is no such node, the
+<a href=#effective-command-value>effective command value</a> of 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>.
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
<p><a href=#relevant-css-property>Relevant CSS property</a>: "background-color"
@@ -2341,9 +2420,9 @@
(fontName, italic, etc.). Except not for strikethrough, where it just does
nothing if the selection is empty. Why strikethrough? I don't know. -->
-<p><a href=#action>Action</a>: If the <a href=#state>state</a> is false, <a href="#set-the-selection's-value">set the
-selection's value</a> to "bold", otherwise <a href="#set-the-selection's-value">set the selection's
-value</a> to "normal".
+<p><a href=#action>Action</a>: If <code title=queryCommandState()><a href=#querycommandstate()>queryCommandState("bold")</a></code> returns true,
+<a href="#set-the-selection's-value">set the selection's value</a> to "normal". Otherwise <a href="#set-the-selection's-value">set the
+selection's value</a> to "bold".
<p><a href=#indeterminate>Indeterminate</a>: True if among <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>
nodes that are <a href=#effectively-contained>effectively contained</a> in the <a href=#active-range>active
@@ -2440,15 +2519,7 @@
<li><a href="#set-the-selection's-value">Set the selection's value</a> to <var title="">value</var>.
</ol>
-<!--
-The state is always false in Chrome 14 dev and Opera 11.11. Firefox 6.0a2
-throws an exception, and IE9 seems to always either return false or throw an
-exception. Therefore we make the state always false, although this doesn't
-seem very useful.
--->
-
-<!-- I'd have expected the value to be the URL, but guess not: it's always
-false. -->
+<p class=XXX>Define state and value, although browsers don't.
<h3 id=the-fontname-command><span class=secno>7.10 </span><dfn>The <code title="">fontName</code> command</dfn></h3>
@@ -2482,12 +2553,17 @@
value">effective command values</a>. Otherwise false.
<!-- This follows Firefox 6.0a2. Chrome 14 dev always returns false. -->
-<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of 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>.
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
-<!-- Complicated.
+<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of the first
+<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 that is <a href=#effectively-contained>effectively contained</a>
+in the <a href=#active-range>active range</a>, or if there is no such node, the
+<a href=#effective-command-value>effective command value</a> of 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>.
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
+<!--
+Complicated.
IE 9 RC: Always the empty string. Not very useful.
Firefox 4b11: Confusing. Sometimes it returns generic family names, like
@@ -2502,7 +2578,10 @@
I'm just going to punt on this and say it should be the resolved value of
font-family. I'll leave CSSOM to decide what that means if there are no
-applicable style rules. -->
+applicable style rules.
+
+For deciding which node should be checked, see comment for hiliteColor.
+-->
<p><a href=#relevant-css-property>Relevant CSS property</a>: "font-family"
@@ -2644,11 +2723,16 @@
-->
<ol>
<li>Let <var title="">pixel size</var> be the <a href=#effective-command-value>effective command value</a> of
- 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>, as a number of pixels.
-
- <p class=note>The active range's start node cannot be null, since the
- boundary point node of a selection must always be either an element or a text
- node that's the child of an element.
+ the first <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 that is <a href=#effectively-contained>effectively
+ contained</a> in the <a href=#active-range>active range</a>, or if there is no such
+ node, the <a href=#effective-command-value>effective command value</a> of 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>, in either case interpreted as a number of
+ pixels.
+ <!-- See comment for hiliteColor on how I decided on this choice of node. -->
+
+ <p class=note>The effective command value of the active range's start node
+ cannot be null, since the boundary point node of a selection must always be
+ either an element or a text node that's the child of an element.
<li>Let <var title="">returned size</var> be 1.
@@ -2684,29 +2768,29 @@
<!-- Color interpretations (wide screen recommended):
- IE9 Firefox 4.0 Chrome 12 dev Opera 11.00
-red red red #ff0000 #ff0000
+ IE10PP2 Firefox 7.0a2 Chrome 14 dev Opera 11.50
+blue blue blue #0000ff #0000ff
f #f - - #f00000
#f #f - - #f00000
-f00 #f00 - #ff0000 #0f0000
-#f00 #f00 rgb(255, 0, 0) #ff0000 #0f0000
-ff0000 #ff0000 - #ff0000 #ff0000
-#ff0000 #ff0000 rgb(255, 0, 0) #ff0000 #ff0000
-fff000000 #ff0000 - - #fff000
-#fff000000 #ff0000 - - #fff000
-rgb(255, 0, 0) rgb(255,0,0) rgb(255, 0, 0) #ff0000 #00b025
-rgb(100%, 0, 0) rgb(255,0,0) - - #00b010
-rgb( 255 ,0 ,0) rgb(255,0,0) rgb(255, 0, 0) #ff0000 #00b025
-rgba(255, 0, 0, 0.0) #005000 rgba(255, 0, 0, 0) rgba(255, 0, 0, 0.0) #00ba02
-rgb(375, -10, 15) rgb(255,0,15) rgb(255, 0, 15) #ff000f #00b037
+00f #00f - #0000ff #00000f
+#00f #00f rgb(0, 0, 255) #0000ff #00000f
+0000ff #0000ff - #0000ff #0000ff
+#0000ff #0000ff rgb(0, 0, 255) #0000ff #0000ff
+000000fff #0000ff - - -
+#000000fff #0000ff - - -
+rgb(0, 0, 255) rgb(0,0,255) rgb(0, 0, 255) #0000ff #00b000
+rgb(0%, 0%, 100%) rgb(0,0,255) rgb(0, 0, 255) #0000ff #00b000
+rgb( 0 ,0 ,255) rgb(0,0,255) rgb(0, 0, 255) #0000ff #00b000
+rgba(0, 0, 255, 0.0) #ba0000 rgba(0, 0, 255, 0) rgba(0, 0, 255, 0) #00ba00
+rgb(15, -10, 375) rgb(15,0,255) rgb(15, 0, 255) #0f00ff #00b015
rgba(0, 0, 0, 1) #ba0010 rgb(0, 0, 0) - #00ba00
rgba(255, 255, 255, 1) #000055 rgb(255, 255, 255) #ffffff #00ba02
-rgba(255, 0, 0, 0.5) #005000 rgba(255, 255, 255, 0.5) rgba(255, 0, 0, 0.49804) #00ba02
-hsl(0%, 100%, 50%) #001050 - - -
+rgba(0, 0, 255, 0.5) #ba0000 rgba(0, 0, 255, 0.5) rgba(0, 0, 255, 0.5) #00ba00
+hsl(240, 100%, 50%) #000150 rgb(0, 0, 255) #0000ff #000024
cornsilk cornsilk cornsilk #fff8dc #fff8dc
potato quiche #0000c0 - - #000a00
-transparent transparent - rgba(0, 0, 0.0) #00a000
-currentColor #c0e000 currentcolor rgba(0, 0, 0.0) #c000e0
+transparent transparent - rgba(0, 0, 0, 0) #00a000
+currentColor #c0e000 currentcolor rgba(0, 0, 0, 0) #c000e0
The interpretations given for Firefox are only in styleWithCSS mode. In
non-styleWithCSS mode, it just outputs the string literally as the <font color>
@@ -2721,8 +2805,8 @@
* Opera mangles #xxx, but everyone else handles it fine.
* The leading # is optional in all browsers but Gecko.
* rgb() is accepted by everyone but Opera.
-* rgba() is accepted by Gecko and WebKit, but rejected by IE and Opera.
-* hsl() isn't accepted by anyone.
+* rgba() and hsl() are accepted by Gecko and WebKit, but rejected by IE and
+ Opera.
* IE and Opera mangle unrecognized stuff, Gecko and WebKit ignore.
* Browsers will happily output stuff like "transparent" and "rgba()" into <font
color> even though it won't be uniformly accepted there.
@@ -2759,18 +2843,25 @@
value">effective command values</a>. Otherwise false.
<!-- This follows Firefox 6.0a2. Chrome 14 dev always returns false. -->
-<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of 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>.
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
+<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of the first
+<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 that is <a href=#effectively-contained>effectively contained</a>
+in the <a href=#active-range>active range</a>, or if there is no such node, the
+<a href=#effective-command-value>effective command value</a> of 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>.
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
<!--
-The spec essentially matches Firefox 6.0a2 and Chrome 14 dev. IE9 seems to
-always return the number 0 for some bizarre reason. There are some cases where
-Firefox returns the empty string for some reason, and it seems to select the
-active node a little differently. Opera uses #xxxxxx format for
-getComputedStyle() but rgb() here, and also drops the transparent part of the
-color if there is any.
+The spec essentially matches Firefox 6.0a2 and Chrome 14 dev, as far as how to
+decide what color the node has. IE9 seems to always return the number 0 for
+some bizarre reason. There are some cases where Firefox returns the empty
+string for some reason, and it seems to select the active node a little
+differently. Opera uses #xxxxxx format for getComputedStyle() but rgb() here,
+and also drops the transparent part of the color if there is any.
+
+For why I chose this node to key the color off of, see the comment for
+hiliteColor.
-->
<p><a href=#relevant-css-property>Relevant CSS property</a>: "color"
@@ -2817,19 +2908,28 @@
<!-- This follows no one. Firefox 6.0a2 and Chrome 14 dev both always return
false. However, it makes sense. -->
-<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of 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>.
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
+<p><a href=#value>Value</a>: The <a href=#effective-command-value>effective command value</a> of the first
+<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 that is <a href=#effectively-contained>effectively contained</a>
+in the <a href=#active-range>active range</a>, or if there is no such node, the
+<a href=#effective-command-value>effective command value</a> of 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>.
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
<!--
-This seems to match Opera 11.11 exactly. Chrome 14 dev returns boolean false
-consistently, bizarrely enough. Firefox 6.0a2 seems to follow the same idea as
-the spec, but it likes to return "transparent", including sometimes when the
-answer really clearly should not be "transparent". IE9 throws exceptions most
-of the time for backColor, so I can't say for sure, but in the few cases where
-it doesn't throw it returns a random-looking number, so I'll assume it's crazy
-like for foreColor.
+Opera 11.11 seems to always return the effective command value of the active
+range's start node. Chrome 14 dev returns boolean false consistently,
+bizarrely enough. Firefox 6.0a2 seems to follow the same idea as the spec, but
+it likes to return "transparent", including sometimes when the answer really
+clearly should not be "transparent". IE9 throws exceptions most of the time
+for backColor, so I can't say for sure, but in the few cases where it doesn't
+throw it returns a random-looking number, so I'll assume it's crazy like for
+foreColor.
+
+I decided on something that would guarantee the following invariant: whenever
+you execute a command with a value provided (assuming value is relevant),
+queryCommandValue() will always return something equivalent to what you set.
-->
<p><a href=#relevant-css-property>Relevant CSS property</a>: "background-color"
@@ -2837,9 +2937,9 @@
<h3 id=the-italic-command><span class=secno>7.14 </span><dfn>The <code title="">italic</code> command</dfn></h3>
-<p><a href=#action>Action</a>: If the <a href=#state>state</a> is false, <a href="#set-the-selection's-value">set the
-selection's value</a> to "italic", otherwise <a href="#set-the-selection's-value">set the selection's
-value</a> to "normal".
+<p><a href=#action>Action</a>: If <code title=queryCommandState()><a href=#querycommandstate()>queryCommandState("italic")</a></code> returns true,
+<a href="#set-the-selection's-value">set the selection's value</a> to "normal". Otherwise <a href="#set-the-selection's-value">set the
+selection's value</a> to "italic".
<p><a href=#indeterminate>Indeterminate</a>: True if among <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>
nodes that are <a href=#effectively-contained>effectively contained</a> in the <a href=#active-range>active
@@ -2983,9 +3083,9 @@
<h3 id=the-strikethrough-command><span class=secno>7.16 </span><dfn>The <code title="">strikethrough</code> command</dfn></h3>
-<p><a href=#action>Action</a>: If the <a href=#state>state</a> is false, <a href="#set-the-selection's-value">set the
-selection's value</a> to "line-through", otherwise <a href="#set-the-selection's-value">set the selection's
-value</a> to null.
+<p><a href=#action>Action</a>: If <code title=queryCommandState()><a href=#querycommandstate()>queryCommandState("strikethrough")</a></code> returns
+true, <a href="#set-the-selection's-value">set the selection's value</a> to null. Otherwise <a href="#set-the-selection's-value">set the
+selection's value</a> to "line-through".
<!-- TODO: See underline TODO. -->
@@ -3006,7 +3106,8 @@
<p><a href=#action>Action</a>:
<ol>
- <li>Let <var title="">state</var> be the <a href=#state>state</a>.
+ <li>Call <code title=queryCommandState()><a href=#querycommandstate()>queryCommandState("subscript")</a></code>, and let
+ <var title="">state</var> be the result.
<li><a href="#set-the-selection's-value">Set the selection's value</a> to "baseline".
@@ -3046,7 +3147,8 @@
<p><a href=#action>Action</a>:
<ol>
- <li>Let <var title="">state</var> be the <a href=#state>state</a>.
+ <li>Call <code title=queryCommandState()><a href=#querycommandstate()>queryCommandState("superscript")</a></code>, and let
+ <var title="">state</var> be the result.
<li><a href="#set-the-selection's-value">Set the selection's value</a> to "baseline".
@@ -3072,9 +3174,9 @@
<h3 id=the-underline-command><span class=secno>7.19 </span><dfn>The <code title="">underline</code> command</dfn></h3>
-<p><a href=#action>Action</a>: If the <a href=#state>state</a> is false, <a href="#set-the-selection's-value">set the
-selection's value</a> to "underline", otherwise <a href="#set-the-selection's-value">set the selection's
-value</a> to null.
+<p><a href=#action>Action</a>: If <code title=queryCommandState()><a href=#querycommandstate()>queryCommandState("underline")</a></code> returns true,
+<a href="#set-the-selection's-value">set the selection's value</a> to null. Otherwise <a href="#set-the-selection's-value">set the
+selection's value</a> to "underline".
<!--
TODO: There are a lot of problems with underline color and thickness, because
@@ -6671,6 +6773,8 @@
theory, but normalize the selection first, so they don't match it in practice.
-->
+<p class=XXX>Needs to handle overridden state/value.
+
<p><a href=#action>Action</a>:
<!--
--- a/implementation.js Wed Jul 13 13:55:04 2011 -0600
+++ b/implementation.js Thu Jul 14 12:24:49 2011 -0600
@@ -149,6 +149,16 @@
|| (val1.toLowerCase() == "normal" && val2 == "400")
|| (val2.toLowerCase() == "normal" && val1 == "400");
}
+
+ // This code path should probably only be hit by queryOutputHelper() in
+ // tests.js. Anything else is most likely a bug.
+ if (command == "fontname" && /^[1-7]$/.test(val1)) {
+ val1 = [, "xx-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"][val1];
+ }
+ if (command == "fontname" && /^[1-7]$/.test(val2)) {
+ val2 = [, "xx-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"][val2];
+ }
+
var property = commands[command].relevantCssProperty;
var test1 = document.createElement("span");
test1.style[property] = val1;
@@ -479,38 +489,81 @@
return nodeList;
}
-
+// Returns either null, or something of the form #xxxxxx, or the color itself
+// if it's a valid keyword.
function parseSimpleColor(color) {
- // This is stupid, but otherwise my automated tests will have places where
- // they're known to contradict the spec, which is annoying, so . . . I
- // don't aim for correctness, beyond my own provisional tests. Real tests
- // will have to be more exhaustive.
-
- if (color.length == 7 && color[0] == "#") {
+ color = color.toLowerCase();
+ // Yay for Gecko allowing you to select a column of a table without
+ // selecting anything from other columns.
+ if (["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
+ "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
+ "burlywood", "cadetblue", "chartreuse", "chocolate", "coral",
+ "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
+ "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki",
+ "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred",
+ "darksalmon", "darkseagreen", "darkslateblue", "darkslategray",
+ "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue",
+ "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite",
+ "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod",
+ "gray", "green", "greenyellow", "grey", "honeydew", "hotpink", "indianred",
+ "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen",
+ "lemonchiffon", "lightblue", "lightcoral", "lightcyan",
+ "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey",
+ "lightpink", "lightsalmon", "lightseagreen", "lightskyblue",
+ "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
+ "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine",
+ "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
+ "mediumslateblue", "mediumspringgreen", "mediumturquoise",
+ "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
+ "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange",
+ "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise",
+ "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum",
+ "powderblue", "purple", "red", "rosybrown", "royalblue", "saddlebrown",
+ "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver",
+ "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen",
+ "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet",
+ "wheat", "white", "whitesmoke", "yellow", "yellowgreen"].indexOf(color) != -1) {
return color;
}
- if (color.length == 4 && color[0] == "#") {
- return "#" + color[1] + color[1] + color[2] + color[2] + color[3] + color[3];
- }
-
- // Otherwise, don't even try.
- return {
- "red": "red",
- "blue": "blue",
- "rgb(255, 0, 0)": "#ff0000",
- "rgb(100%, 0, 0)": "#ff0000",
- "rgb( 255 ,0 ,0)": "#ff0000",
- "rgba(255, 0, 0, 0.0)": false,
- "rgb(375, -10, 15)": false,
- "rgba(0, 0, 0, 1)": "#000000",
- "rgba(255, 255, 255, 1)": "#ffffff",
- "rgba(255, 0, 0, 0.5)": false,
- "hsl(0%, 100%, 50%)": "#ff0000",
- "cornsilk": "cornsilk",
- "transparent": false,
- "currentColor": false,
- }[color];
+ var outerSpan = document.createElement("span");
+ document.body.appendChild(outerSpan);
+ outerSpan.style.color = "black";
+
+ var innerSpan = document.createElement("span");
+ outerSpan.appendChild(innerSpan);
+ innerSpan.style.color = color;
+ color = getComputedStyle(innerSpan).color;
+
+ if (color == "rgb(0, 0, 0)") {
+ // Maybe it's really black, maybe it's invalid.
+ outerSpan.color = "white";
+ color = getComputedStyle(innerSpan).color;
+ if (color == "rgb(0, 0, 0)") {
+ return null;
+ }
+ }
+
+ document.body.removeChild(outerSpan);
+
+ if (/^rgba\([0-9]+, [0-9]+, [0-9]+, 1\)$/.test(color)) {
+ // IE10PP2 seems to do this sometimes.
+ color = color.replace("rgba", "rgb").replace(", 1)", ")");
+ }
+ // I rely on the fact that browsers generally provide consistent syntax for
+ // getComputedStyle(), although it's not standardized. In particular, they
+ // seem to clamp the components to integers between 0 and 255, and use
+ // consistent spacing, and always return rgb() syntax. (Firefox 7.0a2
+ // sometimes returns "transparent", but we need to return null then
+ // anyway.)
+ var matches = /^rgb\(([0-9]+), ([0-9]+), ([0-9]+)\)$/.exec(color);
+ if (matches) {
+ return "#"
+ + parseInt(matches[1]).toString(16).replace(/^.$/, "0$&")
+ + parseInt(matches[2]).toString(16).replace(/^.$/, "0$&")
+ + parseInt(matches[3]).toString(16).replace(/^.$/, "0$&");
+ }
+ return null;
}
//@}
@@ -642,6 +695,11 @@
return false;
}
+ // "If the state override for command is set, return it."
+ if (typeof getStateOverride(command) != "undefined") {
+ return getStateOverride(command);
+ }
+
// "Return true if command's state is true, otherwise false."
return commands[command].state();
}
@@ -672,6 +730,11 @@
return "";
}
+ // "If the value override for command is set, return it."
+ if (typeof getValueOverride(command) != "undefined") {
+ return getValueOverride(command);
+ }
+
// "Return command's value."
return commands[command].value();
}
@@ -938,6 +1001,72 @@
}
return ret;
}
+
+// "For some commands, each HTMLDocument must have a boolean state override
+// and/or a string value override. These do not change the command's state or
+// value, but change the way some algorithms behave, as specified in those
+// algorithms' definitions. Initially, both must be unset for every command.
+// Whenever the number of ranges in the Selection changes to something
+// different, and whenever a boundary point of the range at a given index in
+// the Selection changes to something different, the state override and value
+// override must be unset for every command."
+//
+// We implement this crudely by using setters and getters. To verify that the
+// selection hasn't changed, we copy the active range and just check the
+// endpoints match. This isn't really correct, but it's good enough for us.
+// Unset state/value overrides are undefined. We put everything in a function
+// so no one can access anything except via the provided functions, since
+// otherwise callers might mistakenly use outdated overrides (if the selection
+// has changed).
+var getStateOverride, setStateOverride, unsetStateOverride,
+ getValueOverride, setValueOverride, unsetValueOverride;
+(function() {
+ var stateOverrides = {};
+ var valueOverrides = {};
+ var storedRange = null;
+
+ function resetOverrides() {
+ if (!storedRange
+ || storedRange.startContainer != getActiveRange().startContainer
+ || storedRange.endContainer != getActiveRange().endContainer
+ || storedRange.startOffset != getActiveRange().startOffset
+ || storedRange.endOffset != getActiveRange().endOffset) {
+ stateOverrides = {};
+ valueOverrides = {};
+ storedRange = getActiveRange().cloneRange();
+ }
+ }
+
+ getStateOverride = function(command) {
+ resetOverrides();
+ return stateOverrides[command];
+ };
+
+ setStateOverride = function(command, newState) {
+ resetOverrides();
+ stateOverrides[command] = newState;
+ };
+
+ unsetStateOverride = function(command) {
+ resetOverrides();
+ delete stateOverrides[command];
+ }
+
+ getValueOverride = function(command) {
+ resetOverrides();
+ return valueOverrides[command];
+ }
+
+ setValueOverride = function(command, newValue) {
+ resetOverrides();
+ valueOverrides[command] = newValue;
+ }
+
+ unsetValueOverride = function(command) {
+ resetOverrides();
+ delete valueOverrides[command];
+ }
+})();
//@}
/////////////////////////////
@@ -2482,16 +2611,13 @@
// "If command is "foreColor", and new value is fully opaque with red,
// green, and blue components in the range 0 to 255:"
- //
- // Not going to do this properly, only well enough to pass tests.
if (command == "forecolor" && parseSimpleColor(newValue)) {
// "Let new parent be the result of calling createElement("font")
// on the ownerDocument of node."
newParent = node.ownerDocument.createElement("font");
- // "If new value is one of the colors listed in the SVG color
- // keywords section of CSS3 Color, set the color attribute of new
- // parent to new value."
+ // "If new value is an extended color keyword, set the color
+ // attribute of new parent to new value."
//
// "Otherwise, set the color attribute of new parent to the result
// of applying the rules for serializing simple color values to new
@@ -2697,6 +2823,51 @@
//@{
function setSelectionValue(command, newValue) {
+ // "If there is no editable text node effectively contained in the active
+ // range:"
+ if (!getAllEffectivelyContainedNodes(getActiveRange())
+ .filter(function(node) { return node.nodeType == Node.TEXT_NODE})
+ .some(isEditable)) {
+ // "If command is in the following list, set the state override
+ // appropriately:"
+ switch (command) {
+ // "bold: True if new value is not null and is greater than or
+ // equal to 600, false otherwise."
+ case "bold": setStateOverride(command, newValue === "bold"); break;
+
+ // "italic: True if new value is "italic" or "oblique", false
+ // otherwise."
+ case "italic": setStateOverride(command, newValue === "italic"); break;
+
+ // "strikethrough: True if new value is "line-through", false
+ // otherwise."
+ case "strikethrough": setStateOverride(command, newValue === "line-through"); break;
+
+ // "subscript: True if new value is "sub", false otherwise."
+ case "subscript": setStateOverride(command, newValue === "sub"); break;
+
+ // "superscript: True if new value is "super", false otherwise."
+ case "superscript": setStateOverride(command, newValue === "super"); break;
+
+ // "underline: True if new value is "underline", false otherwise."
+ case "underline": setStateOverride(command, newValue === "underline");
+ }
+
+ // "If command has a value specified, unset the value override if new
+ // value is null, and set the value override to new value if it is not
+ // null."
+ if ("value" in commands[command]) {
+ if (newValue === null) {
+ unsetValueOverride(command);
+ } else {
+ setValueOverride(command, newValue);
+ }
+ }
+
+ // "Abort these steps."
+ return;
+ }
+
// "If the active range's start node is an editable Text node, and its
// start offset is neither zero nor its start node's length, call
// splitText() on the active range's start node, with argument equal to the
@@ -2764,6 +2935,8 @@
commands.backcolor = {
// Copy-pasted, same as hiliteColor
action: function(value) {
+ // Action is further copy-pasted, same as foreColor
+
// "If value is not a valid CSS color, prepend "#" to it."
//
// "If value is still not a valid CSS color, or if it is currentColor,
@@ -2773,12 +2946,9 @@
if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) {
value = "#" + value;
}
- if (!/^#([0-9a-fA-F]{3}){1,2}$/.test(value)
- && !/^(rgba?|hsla?)\(.*\)$/.test(value)
- // Not gonna list all the keywords, only the ones I use.
- && value != "red"
- && value != "cornsilk"
- && value != "transparent") {
+ if (!/^(rgba?|hsla?)\(.*\)$/.test(value)
+ && !parseSimpleColor(value)
+ && value.toLowerCase() != "transparent") {
throw "SYNTAX_ERR";
}
@@ -2796,12 +2966,20 @@
return arr.slice(0, i).indexOf(value) == -1;
}).length >= 2;
}, value: function() {
- // "The effective command value of the active range's start node."
+ // "The effective command value of the first editable Text node that is
+ // effectively contained in the active range, or if there is no such
+ // node, the effective command value of the active range's start node."
//
// Opera uses a different format, so let's be nice and support that for
// the time being (since all this resolved value stuff is underdefined
// anyway).
- var value = getEffectiveCommandValue(getActiveRange().startContainer, "backcolor");
+ var node = getAllEffectivelyContainedNodes(getActiveRange(), function(node) {
+ return isEditable(node) && node.nodeType == Node.TEXT_NODE;
+ })[0];
+ if (node === undefined) {
+ node = getActiveRange().startContainer;
+ }
+ var value = getEffectiveCommandValue(node, "backcolor");
if (/^#[0-9a-f]{6}$/.test(value)) {
value = "rgb(" + parseInt(value.slice(1, 3), 16)
+ "," + parseInt(value.slice(3, 5), 16)
@@ -2816,12 +2994,12 @@
//@{
commands.bold = {
action: function() {
- // "If the state is false, set the selection's value to "bold",
- // otherwise set the selection's value to "normal"."
- if (!commands.bold.state()) {
+ // "If queryCommandState("bold") returns true, set the selection's
+ // value to "normal". Otherwise set the selection's value to "bold"."
+ if (myQueryCommandState("bold", getActiveRange())) {
+ setSelectionValue("bold", "normal");
+ } else {
setSelectionValue("bold", "bold");
- } else {
- setSelectionValue("bold", "normal");
}
}, indeterm: function() { return indetermHelper(function(node) {
// "True if among editable Text nodes that are effectively contained in
@@ -2897,8 +3075,16 @@
return arr.slice(0, i).indexOf(value) == -1;
}).length >= 2;
}, value: function() {
- // "The effective command value of the active range's start node."
- return getEffectiveCommandValue(getActiveRange().startContainer, "fontname");
+ // "The effective command value of the first editable Text node that is
+ // effectively contained in the active range, or if there is no such
+ // node, the effective command value of the active range's start node."
+ var node = getAllEffectivelyContainedNodes(getActiveRange(), function(node) {
+ return isEditable(node) && node.nodeType == Node.TEXT_NODE;
+ })[0];
+ if (node === undefined) {
+ node = getActiveRange().startContainer;
+ }
+ return getEffectiveCommandValue(node, "fontname");
}, relevantCssProperty: "fontFamily"
};
@@ -3002,9 +3188,18 @@
return arr.slice(0, i).indexOf(value) == -1;
}).length >= 2;
}, value: function() {
- // "Let pixel size be the effective command value of the active range's
- // start node, as a number of pixels."
- var pixelSize = parseInt(getEffectiveCommandValue(getActiveRange().startContainer, "fontsize"));
+ // "Let pixel size be the effective command value of the first editable
+ // Text node that is effectively contained in the active range, or if
+ // there is no such node, the effective command value of the active
+ // range's start node, in either case interpreted as a number of
+ // pixels."
+ var node = getAllEffectivelyContainedNodes(getActiveRange(), function(node) {
+ return isEditable(node) && node.nodeType == Node.TEXT_NODE;
+ })[0];
+ if (node === undefined) {
+ node = getActiveRange().startContainer;
+ }
+ var pixelSize = parseInt(getEffectiveCommandValue(node, "fontsize"));
// "Let returned size be 1."
var returnedSize = 1;
@@ -3048,7 +3243,7 @@
//@{
commands.forecolor = {
action: function(value) {
- // Copy-pasted, same as hiliteColor
+ // Copy-pasted, same as backColor and hiliteColor
// "If value is not a valid CSS color, prepend "#" to it."
//
@@ -3059,12 +3254,9 @@
if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) {
value = "#" + value;
}
- if (!/^#([0-9a-fA-F]{3}){1,2}$/.test(value)
- && !/^(rgba?|hsla?)\(.*\)$/.test(value)
- // Not gonna list all the keywords, only the ones I use.
- && value != "red"
- && value != "cornsilk"
- && value != "transparent") {
+ if (!/^(rgba?|hsla?)\(.*\)$/.test(value)
+ && !parseSimpleColor(value)
+ && value.toLowerCase() != "transparent") {
throw "SYNTAX_ERR";
}
@@ -3082,12 +3274,20 @@
return arr.slice(0, i).indexOf(value) == -1;
}).length >= 2;
}, value: function() {
- // "The effective command value of the active range's start node."
+ // "The effective command value of the first editable Text node that is
+ // effectively contained in the active range, or if there is no such
+ // node, the effective command value of the active range's start node."
//
// Opera uses a different format, so let's be nice and support that for
// the time being (since all this resolved value stuff is underdefined
// anyway).
- var value = getEffectiveCommandValue(getActiveRange().startContainer, "forecolor");
+ var node = getAllEffectivelyContainedNodes(getActiveRange(), function(node) {
+ return isEditable(node) && node.nodeType == Node.TEXT_NODE;
+ })[0];
+ if (node === undefined) {
+ node = getActiveRange().startContainer;
+ }
+ var value = getEffectiveCommandValue(node, "forecolor");
if (/^#[0-9a-f]{6}$/.test(value)) {
value = "rgb(" + parseInt(value.slice(1, 3), 16)
+ "," + parseInt(value.slice(3, 5), 16)
@@ -3101,8 +3301,9 @@
///// The hiliteColor command /////
//@{
commands.hilitecolor = {
+ // Copy-pasted, same as backColor
action: function(value) {
- // Copy-pasted, same as foreColor
+ // Action is further copy-pasted, same as foreColor
// "If value is not a valid CSS color, prepend "#" to it."
//
@@ -3113,12 +3314,9 @@
if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) {
value = "#" + value;
}
- if (!/^#([0-9a-fA-F]{3}){1,2}$/.test(value)
- && !/^(rgba?|hsla?)\(.*\)$/.test(value)
- // Not gonna list all the keywords, only the ones I use.
- && value != "red"
- && value != "cornsilk"
- && value != "transparent") {
+ if (!/^(rgba?|hsla?)\(.*\)$/.test(value)
+ && !parseSimpleColor(value)
+ && value.toLowerCase() != "transparent") {
throw "SYNTAX_ERR";
}
@@ -3136,12 +3334,20 @@
return arr.slice(0, i).indexOf(value) == -1;
}).length >= 2;
}, value: function() {
- // "The effective command value of the active range's start node."
+ // "The effective command value of the first editable Text node that is
+ // effectively contained in the active range, or if there is no such
+ // node, the effective command value of the active range's start node."
//
// Opera uses a different format, so let's be nice and support that for
// the time being (since all this resolved value stuff is underdefined
// anyway).
- var value = getEffectiveCommandValue(getActiveRange().startContainer, "hilitecolor");
+ var node = getAllEffectivelyContainedNodes(getActiveRange(), function(node) {
+ return isEditable(node) && node.nodeType == Node.TEXT_NODE;
+ })[0];
+ if (node === undefined) {
+ node = getActiveRange().startContainer;
+ }
+ var value = getEffectiveCommandValue(node, "hilitecolor");
if (/^#[0-9a-f]{6}$/.test(value)) {
value = "rgb(" + parseInt(value.slice(1, 3), 16)
+ "," + parseInt(value.slice(3, 5), 16)
@@ -3156,12 +3362,12 @@
//@{
commands.italic = {
action: function() {
- // "If the state is false, set the selection's value to "italic",
- // otherwise set the selection's value to "normal"."
- if (!commands.italic.state()) {
+ // "If queryCommandState("italic") returns true, set the selection's
+ // value to "normal". Otherwise set the selection's value to "italic"."
+ if (myQueryCommandState("italic", getActiveRange())) {
+ setSelectionValue("italic", "normal");
+ } else {
setSelectionValue("italic", "italic");
- } else {
- setSelectionValue("italic", "normal");
}
}, indeterm: function() { return indetermHelper(function(node) {
// "True if among editable Text nodes that are effectively contained in
@@ -3286,12 +3492,13 @@
//@{
commands.strikethrough = {
action: function() {
- // "If the state is false, set the selection's value to "line-through",
- // otherwise set the selection's value to null."
- if (!commands.strikethrough.state()) {
+ // "If queryCommandState("strikethrough") returns true, set the
+ // selection's value to null. Otherwise set the selection's value to
+ // "line-through"."
+ if (myQueryCommandState("strikethrough", getActiveRange())) {
+ setSelectionValue("strikethrough", null);
+ } else {
setSelectionValue("strikethrough", "line-through");
- } else {
- setSelectionValue("strikethrough", null);
}
}, indeterm: function() { return indetermHelper(function(node) {
// "True if among editable Text nodes that are effectively contained in
@@ -3312,8 +3519,8 @@
//@{
commands.subscript = {
action: function() {
- // "Let state be the state."
- var state = commands.subscript.state();
+ // "Call queryCommandState("subscript"), and let state be the result."
+ var state = myQueryCommandState("subscript", getActiveRange());
// "Set the selection's value to "baseline"."
setSelectionValue("subscript", "baseline");
@@ -3348,8 +3555,9 @@
//@{
commands.superscript = {
action: function() {
- // "Let state be the state."
- var state = commands.superscript.state();
+ // "Call queryCommandState("superscript"), and let state be the
+ // result."
+ var state = myQueryCommandState("superscript", getActiveRange());
// "Set the selection's value to "baseline"."
setSelectionValue("superscript", "baseline");
@@ -3385,12 +3593,12 @@
//@{
commands.underline = {
action: function() {
- // "If the state is false, set the selection's value to "underline",
- // otherwise set the selection's value to null."
- if (!commands.underline.state()) {
+ // "If queryCommandState("underline") returns true, set the selection's
+ // value to null. Otherwise set the selection's value to "underline"."
+ if (myQueryCommandState("underline", getActiveRange())) {
+ setSelectionValue("underline", null);
+ } else {
setSelectionValue("underline", "underline");
- } else {
- setSelectionValue("underline", null);
}
}, indeterm: function() { return indetermHelper(function(node) {
// "True if among editable Text nodes that are effectively contained in
--- a/source.html Wed Jul 13 13:55:04 2011 -0600
+++ b/source.html Thu Jul 14 12:24:49 2011 -0600
@@ -604,6 +604,9 @@
<li>If <var>command</var> is not <span>enabled</span>, return false.
+ <li>If the <span>state override</span> for <var>command</var> is set, return
+ it.
+
<li>Return true if <var>command</var>'s <span>state</span> is true, otherwise
false.
</ol>
@@ -642,12 +645,38 @@
seems to return the string "false", and IE9 seems to return boolean false.
-->
+ <li>If the <span>value override</span> for <var>command</var> is set, return
+ it.
+
<li>Return <var>command</var>'s <span>value</span>.
</ol>
<p>All of these methods must treat their <var>command</var> argument <span
data-anolis-spec=domcore title="ASCII case-insensitive">ASCII
case-insensitively</span>.
+
+<p>The methods in this section have been designed so that the following
+invariants hold after <code>execCommand()</code> is called, assuming it didn't
+throw an exception:
+
+<ul>
+ <li><code>queryCommandIndeterm()</code> will return false (or throw an
+ exception).
+
+ <li><code>queryCommandState()</code> will return the opposite of what it did
+ before <code>execCommand()</code> was called (or throw an exception).
+
+ <li><code>queryCommandValue()</code> will return something equivalent to the
+ value passed to <code>execCommand()</code> (or throw an exception).
+ "Equivalent" here needs to be construed broadly in some cases, such as
+ <span>the <code title>fontSize</code> command</span>.
+</ul>
+
+<p>The first two points do not always hold for <span>the <code
+title>strikethrough</code> command</span> or <span>the <code
+title>underline</code> command</span>, because it can be impossible to unset
+text-decoration in CSS, but all three points otherwise hold in all cases
+barring bugs.
<!-- @} -->
<h2>Common definitions</h2>
@@ -775,6 +804,17 @@
means of the <code>execCommand()</code> and <code>queryCommandState()</code>
methods.)
+<p>For some <span title=command>commands</span>, each [[htmldocument]] must
+have a boolean <dfn>state override</dfn> and/or a string <dfn>value
+override</dfn>. These do not change the <span>command</span>'s
+<span>state</span> or <span>value</span>, but change the way some algorithms
+behave, as specified in those algorithms' definitions. Initially, both must be
+unset for every <span>command</span>. Whenever the number of [[ranges]] in the
+[[selection]] changes to something different, and whenever a [[boundarypoint]]
+of the [[range]] at a given index in the [[selection]] changes to something
+different, the <span>state override</span> and <span>value override</span> must
+be unset for every <span>command</span>.
+
<p>When the user agent is instructed to run a particular method, it must follow
the steps defined for that method in the appropriate specification, not act as
though the method had actually been called from JavaScript. In particular,
@@ -1928,6 +1968,10 @@
<li>If <var>command</var> is "foreColor", and <var>new value</var> is fully
opaque with red, green, and blue components in the range 0 to 255:
+ <!-- See comment for foreColor for discussion. -->
+
+ <p class=XXX>Check this more carefully for what happens if the components
+ are not integers or are out-of-range.
<ol>
<li>Let <var>new parent</var> be the result of calling <code
@@ -1935,9 +1979,10 @@
title=dom-Document-createElement>createElement("font")</code> on the
[[ownerdocument]] of <var>node</var>.
- <li>If <var>new value</var> is one of the colors listed in the SVG color
- keywords section of CSS3 Color, set the [[fontcolor]] attribute of
- <var>new parent</var> to <var>new value</var>.
+ <li>If <var>new value</var> is an <a
+ href=http://www.w3.org/TR/css3-color/#svg-color>extended color
+ keyword</a>, set the [[fontcolor]] attribute of <var>new parent</var> to
+ <var>new value</var>.
<li>Otherwise, set the [[fontcolor]] attribute of <var>new parent</var>
to the result of applying the <span data-anolis-spec=html>rules for
@@ -2174,6 +2219,39 @@
<ol>
<li>Let <var>command</var> be the current <span>command</span>.
+ <li>If there is no <span>editable</span> [[text]] node <span>effectively
+ contained</span> in the <span>active range</span>:
+
+ <ol>
+ <li>If <var>command</var> is in the following list, set the <span>state
+ override</span> appropriately:
+
+ <dl class=compact>
+ <dt>bold<dd>True if <var>new value</var> is not null and is greater than or equal
+ to 600, false otherwise.
+
+ <dt>italic<dd>True if <var>new value</var> is "italic" or "oblique", false
+ otherwise.
+
+ <dt>strikethrough<dd>True if <var>new value</var> is "line-through", false otherwise.
+
+ <dt>subscript<dd>True if <var>new value</var> is "sub", false otherwise.
+
+ <dt>superscript<dd>True if <var>new value</var> is "super", false otherwise.
+
+ <dt>underline<dd>True if <var>new value</var> is "underline", false otherwise.
+ </dl>
+
+ <li>If <var>command</var> has a <span>value</span> specified, unset the
+ <span>value override</span> if <var>new value</var> is null, and set the
+ <span>value override</span> to <var>new value</var> if it is not null.
+
+ <p class=XXX>This doesn't work as-is for fontSize, because that uses a
+ different format for the value.
+
+ <li>Abort these steps.
+ </ol>
+
<li>If the <span>active range</span>'s [[startnode]] is an
<span>editable</span> [[text]] node, and its [[startoffset]] is neither zero
nor its [[startnode]]'s [[length]], call [[splittext|]] on the <span>active
@@ -2301,11 +2379,15 @@
range</span>, there are two that have distinct <span title="effective command
value">effective command values</span>. Otherwise false.
-<p><span>Value</span>: The <span>effective command value</span> of the
-<span>active range</span>'s [[startnode]].
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
+<p><span>Value</span>: The <span>effective command value</span> of the first
+<span>editable</span> [[text]] node that is <span>effectively contained</span>
+in the <span>active range</span>, or if there is no such node, the
+<span>effective command value</span> of the <span>active range</span>'s
+[[startnode]].
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
<p><span>Relevant CSS property</span>: "background-color"
@@ -2318,9 +2400,10 @@
(fontName, italic, etc.). Except not for strikethrough, where it just does
nothing if the selection is empty. Why strikethrough? I don't know. -->
-<p><span>Action</span>: If the <span>state</span> is false, <span>set the
-selection's value</span> to "bold", otherwise <span>set the selection's
-value</span> to "normal".
+<p><span>Action</span>: If <code
+title=queryCommandState()>queryCommandState("bold")</code> returns true,
+<span>set the selection's value</span> to "normal". Otherwise <span>set the
+selection's value</span> to "bold".
<p><span>Indeterminate</span>: True if among <span>editable</span> [[text]]
nodes that are <span>effectively contained</span> in the <span>active
@@ -2417,15 +2500,7 @@
<li><span>Set the selection's value</span> to <var>value</var>.
</ol>
-<!--
-The state is always false in Chrome 14 dev and Opera 11.11. Firefox 6.0a2
-throws an exception, and IE9 seems to always either return false or throw an
-exception. Therefore we make the state always false, although this doesn't
-seem very useful.
--->
-
-<!-- I'd have expected the value to be the URL, but guess not: it's always
-false. -->
+<p class=XXX>Define state and value, although browsers don't.
<!-- @} -->
<h3><dfn>The <code title>fontName</code> command</dfn></h3>
@@ -2459,12 +2534,17 @@
value">effective command values</span>. Otherwise false.
<!-- This follows Firefox 6.0a2. Chrome 14 dev always returns false. -->
-<p><span>Value</span>: The <span>effective command value</span> of the
-<span>active range</span>'s [[startnode]].
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
-<!-- Complicated.
+<p><span>Value</span>: The <span>effective command value</span> of the first
+<span>editable</span> [[text]] node that is <span>effectively contained</span>
+in the <span>active range</span>, or if there is no such node, the
+<span>effective command value</span> of the <span>active range</span>'s
+[[startnode]].
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
+<!--
+Complicated.
IE 9 RC: Always the empty string. Not very useful.
Firefox 4b11: Confusing. Sometimes it returns generic family names, like
@@ -2479,7 +2559,10 @@
I'm just going to punt on this and say it should be the resolved value of
font-family. I'll leave CSSOM to decide what that means if there are no
-applicable style rules. -->
+applicable style rules.
+
+For deciding which node should be checked, see comment for hiliteColor.
+-->
<p><span>Relevant CSS property</span>: "font-family"
@@ -2621,11 +2704,16 @@
-->
<ol>
<li>Let <var>pixel size</var> be the <span>effective command value</span> of
- the <span>active range</span>'s [[startnode]], as a number of pixels.
-
- <p class=note>The active range's start node cannot be null, since the
- boundary point node of a selection must always be either an element or a text
- node that's the child of an element.
+ the first <span>editable</span> [[text]] node that is <span>effectively
+ contained</span> in the <span>active range</span>, or if there is no such
+ node, the <span>effective command value</span> of the <span>active
+ range</span>'s [[startnode]], in either case interpreted as a number of
+ pixels.
+ <!-- See comment for hiliteColor on how I decided on this choice of node. -->
+
+ <p class=note>The effective command value of the active range's start node
+ cannot be null, since the boundary point node of a selection must always be
+ either an element or a text node that's the child of an element.
<li>Let <var>returned size</var> be 1.
@@ -2661,29 +2749,29 @@
<!-- Color interpretations (wide screen recommended):
- IE9 Firefox 4.0 Chrome 12 dev Opera 11.00
-red red red #ff0000 #ff0000
+ IE10PP2 Firefox 7.0a2 Chrome 14 dev Opera 11.50
+blue blue blue #0000ff #0000ff
f #f - - #f00000
#f #f - - #f00000
-f00 #f00 - #ff0000 #0f0000
-#f00 #f00 rgb(255, 0, 0) #ff0000 #0f0000
-ff0000 #ff0000 - #ff0000 #ff0000
-#ff0000 #ff0000 rgb(255, 0, 0) #ff0000 #ff0000
-fff000000 #ff0000 - - #fff000
-#fff000000 #ff0000 - - #fff000
-rgb(255, 0, 0) rgb(255,0,0) rgb(255, 0, 0) #ff0000 #00b025
-rgb(100%, 0, 0) rgb(255,0,0) - - #00b010
-rgb( 255 ,0 ,0) rgb(255,0,0) rgb(255, 0, 0) #ff0000 #00b025
-rgba(255, 0, 0, 0.0) #005000 rgba(255, 0, 0, 0) rgba(255, 0, 0, 0.0) #00ba02
-rgb(375, -10, 15) rgb(255,0,15) rgb(255, 0, 15) #ff000f #00b037
+00f #00f - #0000ff #00000f
+#00f #00f rgb(0, 0, 255) #0000ff #00000f
+0000ff #0000ff - #0000ff #0000ff
+#0000ff #0000ff rgb(0, 0, 255) #0000ff #0000ff
+000000fff #0000ff - - -
+#000000fff #0000ff - - -
+rgb(0, 0, 255) rgb(0,0,255) rgb(0, 0, 255) #0000ff #00b000
+rgb(0%, 0%, 100%) rgb(0,0,255) rgb(0, 0, 255) #0000ff #00b000
+rgb( 0 ,0 ,255) rgb(0,0,255) rgb(0, 0, 255) #0000ff #00b000
+rgba(0, 0, 255, 0.0) #ba0000 rgba(0, 0, 255, 0) rgba(0, 0, 255, 0) #00ba00
+rgb(15, -10, 375) rgb(15,0,255) rgb(15, 0, 255) #0f00ff #00b015
rgba(0, 0, 0, 1) #ba0010 rgb(0, 0, 0) - #00ba00
rgba(255, 255, 255, 1) #000055 rgb(255, 255, 255) #ffffff #00ba02
-rgba(255, 0, 0, 0.5) #005000 rgba(255, 255, 255, 0.5) rgba(255, 0, 0, 0.49804) #00ba02
-hsl(0%, 100%, 50%) #001050 - - -
+rgba(0, 0, 255, 0.5) #ba0000 rgba(0, 0, 255, 0.5) rgba(0, 0, 255, 0.5) #00ba00
+hsl(240, 100%, 50%) #000150 rgb(0, 0, 255) #0000ff #000024
cornsilk cornsilk cornsilk #fff8dc #fff8dc
potato quiche #0000c0 - - #000a00
-transparent transparent - rgba(0, 0, 0.0) #00a000
-currentColor #c0e000 currentcolor rgba(0, 0, 0.0) #c000e0
+transparent transparent - rgba(0, 0, 0, 0) #00a000
+currentColor #c0e000 currentcolor rgba(0, 0, 0, 0) #c000e0
The interpretations given for Firefox are only in styleWithCSS mode. In
non-styleWithCSS mode, it just outputs the string literally as the <font color>
@@ -2698,8 +2786,8 @@
* Opera mangles #xxx, but everyone else handles it fine.
* The leading # is optional in all browsers but Gecko.
* rgb() is accepted by everyone but Opera.
-* rgba() is accepted by Gecko and WebKit, but rejected by IE and Opera.
-* hsl() isn't accepted by anyone.
+* rgba() and hsl() are accepted by Gecko and WebKit, but rejected by IE and
+ Opera.
* IE and Opera mangle unrecognized stuff, Gecko and WebKit ignore.
* Browsers will happily output stuff like "transparent" and "rgba()" into <font
color> even though it won't be uniformly accepted there.
@@ -2736,18 +2824,25 @@
value">effective command values</span>. Otherwise false.
<!-- This follows Firefox 6.0a2. Chrome 14 dev always returns false. -->
-<p><span>Value</span>: The <span>effective command value</span> of the
-<span>active range</span>'s [[startnode]].
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
+<p><span>Value</span>: The <span>effective command value</span> of the first
+<span>editable</span> [[text]] node that is <span>effectively contained</span>
+in the <span>active range</span>, or if there is no such node, the
+<span>effective command value</span> of the <span>active range</span>'s
+[[startnode]].
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
<!--
-The spec essentially matches Firefox 6.0a2 and Chrome 14 dev. IE9 seems to
-always return the number 0 for some bizarre reason. There are some cases where
-Firefox returns the empty string for some reason, and it seems to select the
-active node a little differently. Opera uses #xxxxxx format for
-getComputedStyle() but rgb() here, and also drops the transparent part of the
-color if there is any.
+The spec essentially matches Firefox 6.0a2 and Chrome 14 dev, as far as how to
+decide what color the node has. IE9 seems to always return the number 0 for
+some bizarre reason. There are some cases where Firefox returns the empty
+string for some reason, and it seems to select the active node a little
+differently. Opera uses #xxxxxx format for getComputedStyle() but rgb() here,
+and also drops the transparent part of the color if there is any.
+
+For why I chose this node to key the color off of, see the comment for
+hiliteColor.
-->
<p><span>Relevant CSS property</span>: "color"
@@ -2794,19 +2889,28 @@
<!-- This follows no one. Firefox 6.0a2 and Chrome 14 dev both always return
false. However, it makes sense. -->
-<p><span>Value</span>: The <span>effective command value</span> of the
-<span>active range</span>'s [[startnode]].
-
-<p class=note>This cannot be null, since the boundary point node of a selection
-must always be either an element or a text node that's the child of an element.
+<p><span>Value</span>: The <span>effective command value</span> of the first
+<span>editable</span> [[text]] node that is <span>effectively contained</span>
+in the <span>active range</span>, or if there is no such node, the
+<span>effective command value</span> of the <span>active range</span>'s
+[[startnode]].
+
+<p class=note>The effective command value of the active range's start node
+cannot be null, since the boundary point node of a selection must always be
+either an element or a text node that's the child of an element.
<!--
-This seems to match Opera 11.11 exactly. Chrome 14 dev returns boolean false
-consistently, bizarrely enough. Firefox 6.0a2 seems to follow the same idea as
-the spec, but it likes to return "transparent", including sometimes when the
-answer really clearly should not be "transparent". IE9 throws exceptions most
-of the time for backColor, so I can't say for sure, but in the few cases where
-it doesn't throw it returns a random-looking number, so I'll assume it's crazy
-like for foreColor.
+Opera 11.11 seems to always return the effective command value of the active
+range's start node. Chrome 14 dev returns boolean false consistently,
+bizarrely enough. Firefox 6.0a2 seems to follow the same idea as the spec, but
+it likes to return "transparent", including sometimes when the answer really
+clearly should not be "transparent". IE9 throws exceptions most of the time
+for backColor, so I can't say for sure, but in the few cases where it doesn't
+throw it returns a random-looking number, so I'll assume it's crazy like for
+foreColor.
+
+I decided on something that would guarantee the following invariant: whenever
+you execute a command with a value provided (assuming value is relevant),
+queryCommandValue() will always return something equivalent to what you set.
-->
<p><span>Relevant CSS property</span>: "background-color"
@@ -2814,9 +2918,10 @@
<!-- @} -->
<h3><dfn>The <code title>italic</code> command</dfn></h3>
<!-- @{ -->
-<p><span>Action</span>: If the <span>state</span> is false, <span>set the
-selection's value</span> to "italic", otherwise <span>set the selection's
-value</span> to "normal".
+<p><span>Action</span>: If <code
+title=queryCommandState()>queryCommandState("italic")</code> returns true,
+<span>set the selection's value</span> to "normal". Otherwise <span>set the
+selection's value</span> to "italic".
<p><span>Indeterminate</span>: True if among <span>editable</span> [[text]]
nodes that are <span>effectively contained</span> in the <span>active
@@ -2960,9 +3065,10 @@
<!-- @} -->
<h3><dfn>The <code title>strikethrough</code> command</dfn></h3>
<!-- @{ -->
-<p><span>Action</span>: If the <span>state</span> is false, <span>set the
-selection's value</span> to "line-through", otherwise <span>set the selection's
-value</span> to null.
+<p><span>Action</span>: If <code
+title=queryCommandState()>queryCommandState("strikethrough")</code> returns
+true, <span>set the selection's value</span> to null. Otherwise <span>set the
+selection's value</span> to "line-through".
<!-- TODO: See underline TODO. -->
@@ -2983,7 +3089,9 @@
<p><span>Action</span>:
<ol>
- <li>Let <var>state</var> be the <span>state</span>.
+ <li>Call <code
+ title=queryCommandState()>queryCommandState("subscript")</code>, and let
+ <var>state</var> be the result.
<li><span>Set the selection's value</span> to "baseline".
@@ -3023,7 +3131,9 @@
<p><span>Action</span>:
<ol>
- <li>Let <var>state</var> be the <span>state</span>.
+ <li>Call <code
+ title=queryCommandState()>queryCommandState("superscript")</code>, and let
+ <var>state</var> be the result.
<li><span>Set the selection's value</span> to "baseline".
@@ -3049,9 +3159,10 @@
<!-- @} -->
<h3><dfn>The <code title>underline</code> command</dfn></h3>
<!-- @{ -->
-<p><span>Action</span>: If the <span>state</span> is false, <span>set the
-selection's value</span> to "underline", otherwise <span>set the selection's
-value</span> to null.
+<p><span>Action</span>: If <code
+title=queryCommandState()>queryCommandState("underline")</code> returns true,
+<span>set the selection's value</span> to null. Otherwise <span>set the
+selection's value</span> to "underline".
<!--
TODO: There are a lot of problems with underline color and thickness, because
@@ -6666,6 +6777,8 @@
theory, but normalize the selection first, so they don't match it in practice.
-->
+<p class=XXX>Needs to handle overridden state/value.
+
<p><span>Action</span>:
<!--
--- a/tests.css Wed Jul 13 13:55:04 2011 -0600
+++ b/tests.css Thu Jul 14 12:24:49 2011 -0600
@@ -15,6 +15,9 @@
color: red;
font-weight: bold;
}
+.extra-results { font-size: small }
+.good-result { color: green }
+.bad-result { color: red }
/* http://www.w3.org/Bugs/Public/show_bug.cgi?id=12154
* https://bugzilla.mozilla.org/show_bug.cgi?id=589124
* https://bugs.webkit.org/show_bug.cgi?id=56400 */
--- a/tests.js Wed Jul 13 13:55:04 2011 -0600
+++ b/tests.js Thu Jul 14 12:24:49 2011 -0600
@@ -187,7 +187,7 @@
'<i><b>foo</b></i>[bar]<i><b>baz</b></i>',
'<i><b>foo</b></i>[bar]<b>baz</b>',
'<b>foo</b>[bar]<i><b>baz</b></i>',
- '<font color=red face=monospace><b>foo</b></font>[bar]',
+ '<font color=blue face=monospace><b>foo</b></font>[bar]',
'foo<span style="font-weight: normal"><b>{bar}</b></span>baz',
'[foo<span class=notbold>bar</span>baz]',
@@ -393,11 +393,11 @@
'foo<blockquote>[]bar</blockquote>',
'foo<blockquote><blockquote>[]bar</blockquote></blockquote>',
'foo<blockquote><div>[]bar</div></blockquote>',
- 'foo<blockquote style="color: red">[]bar</blockquote>',
+ 'foo<blockquote style="color: blue">[]bar</blockquote>',
'foo<blockquote><blockquote><p>[]bar<p>baz</blockquote></blockquote>',
'foo<blockquote><div><p>[]bar<p>baz</div></blockquote>',
- 'foo<blockquote style="color: red"><p>[]bar<p>baz</blockquote>',
+ 'foo<blockquote style="color: blue"><p>[]bar<p>baz</blockquote>',
'foo<blockquote><p><b>[]bar</b><p>baz</blockquote>',
'foo<blockquote><p><strong>[]bar</strong><p>baz</blockquote>',
@@ -434,22 +434,22 @@
'<div><div><p>foo</p></div></div><div><div><div><!--abc-->[]bar</div></div></div>',
// Styled stuff with collapsed selection
- '<p style=color:red>foo<p>[]bar',
- '<p style=color:red>foo<p style=color:blue>[]bar',
- '<p>foo<p style=color:blue>[]bar',
- '<p><font color=red>foo</font><p>[]bar',
- '<p><font color=red>foo</font><p><font color=blue>[]bar</font>',
- '<p>foo<p><font color=blue>[]bar</font>',
- '<p><span style=color:red>foo</font><p>[]bar',
- '<p><span style=color:red>foo</font><p><span style=color:blue>[]bar</font>',
- '<p>foo<p><span style=color:blue>[]bar</font>',
-
- '<p style=background-color:salmon>foo<p>[]bar',
- '<p style=background-color:salmon>foo<p style=background-color:aqua>[]bar',
- '<p>foo<p style=background-color:aqua>[]bar',
- '<p><span style=background-color:salmon>foo</font><p>[]bar',
- '<p><span style=background-color:salmon>foo</font><p><span style=background-color:aqua>[]bar</font>',
- '<p>foo<p><span style=background-color:aqua>[]bar</font>',
+ '<p style=color:blue>foo<p>[]bar',
+ '<p style=color:blue>foo<p style=color:brown>[]bar',
+ '<p>foo<p style=color:brown>[]bar',
+ '<p><font color=blue>foo</font><p>[]bar',
+ '<p><font color=blue>foo</font><p><font color=brown>[]bar</font>',
+ '<p>foo<p><font color=brown>[]bar</font>',
+ '<p><span style=color:blue>foo</font><p>[]bar',
+ '<p><span style=color:blue>foo</font><p><span style=color:brown>[]bar</font>',
+ '<p>foo<p><span style=color:brown>[]bar</font>',
+
+ '<p style=background-color:aqua>foo<p>[]bar',
+ '<p style=background-color:aqua>foo<p style=background-color:tan>[]bar',
+ '<p>foo<p style=background-color:tan>[]bar',
+ '<p><span style=background-color:aqua>foo</font><p>[]bar',
+ '<p><span style=background-color:aqua>foo</font><p><span style=background-color:tan>[]bar</font>',
+ '<p>foo<p><span style=background-color:tan>[]bar</font>',
'<p style=text-decoration:underline>foo<p>[]bar',
'<p style=text-decoration:underline>foo<p style=text-decoration:line-through>[]bar',
@@ -458,11 +458,11 @@
'<p><u>foo</u><p><s>[]bar</s>',
'<p>foo<p><s>[]bar</s>',
- '<p style=color:red>foo</p>[]bar',
- 'foo<p style=color:blue>[]bar',
- '<div style=color:red><p style=color:green>foo</div>[]bar',
- '<div style=color:red><p style=color:green>foo</div><p style=color:blue>[]bar',
- '<p style=color:red>foo<div style=color:blue><p style=color:green>[]bar',
+ '<p style=color:blue>foo</p>[]bar',
+ 'foo<p style=color:brown>[]bar',
+ '<div style=color:blue><p style=color:green>foo</div>[]bar',
+ '<div style=color:blue><p style=color:green>foo</div><p style=color:brown>[]bar',
+ '<p style=color:blue>foo<div style=color:brown><p style=color:green>[]bar',
// Uncollapsed selection
'foo[bar]baz',
@@ -489,7 +489,7 @@
'<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 style=color:blue>baz]quz',
'<p>foo[bar<p><b>baz]quz</b>',
'<div><p>foo<p>[bar<p>baz]</div>',
@@ -751,24 +751,24 @@
'{<p><p> <p>foo</p>}',
'foo[bar<i>baz]qoz</i>quz',
- ['red', 'foo[bar]baz'],
+ ['blue', 'foo[bar]baz'],
['f', 'foo[bar]baz'],
['#f', 'foo[bar]baz'],
- ['f00', 'foo[bar]baz'],
- ['#f00', 'foo[bar]baz'],
- ['ff0000', 'foo[bar]baz'],
- ['#ff0000', 'foo[bar]baz'],
- ['fff000000', 'foo[bar]baz'],
- ['#fff000000', 'foo[bar]baz'],
- ['rgb(255, 0, 0)', 'foo[bar]baz'],
- ['rgb(100%, 0, 0)', 'foo[bar]baz'],
- ['rgb( 255 ,0 ,0)', 'foo[bar]baz'],
- ['rgba(255, 0, 0, 0.0)', 'foo[bar]baz'],
- ['rgb(375, -10, 15)', 'foo[bar]baz'],
+ ['00f', 'foo[bar]baz'],
+ ['#00f', 'foo[bar]baz'],
+ ['0000ff', 'foo[bar]baz'],
+ ['#0000ff', 'foo[bar]baz'],
+ ['000000fff', 'foo[bar]baz'],
+ ['#000000fff', 'foo[bar]baz'],
+ ['rgb(0, 0, 255)', 'foo[bar]baz'],
+ ['rgb(0%, 0%, 100%)', 'foo[bar]baz'],
+ ['rgb( 0 ,0 ,255)', 'foo[bar]baz'],
+ ['rgba(0, 0, 255, 0.0)', 'foo[bar]baz'],
+ ['rgb(15, -10, 375)', 'foo[bar]baz'],
['rgba(0, 0, 0, 1)', 'foo[bar]baz'],
['rgba(255, 255, 255, 1)', 'foo[bar]baz'],
- ['rgba(255, 0, 0, 0.5)', 'foo[bar]baz'],
- ['hsl(0%, 100%, 50%)', 'foo[bar]baz'],
+ ['rgba(0, 0, 255, 0.5)', 'foo[bar]baz'],
+ ['hsl(240, 100%, 50%)', 'foo[bar]baz'],
['cornsilk', 'foo[bar]baz'],
['potato quiche', 'foo[bar]baz'],
['transparent', 'foo[bar]baz'],
@@ -781,47 +781,47 @@
'<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>',
'{<table><tr><td>foo<td>bar<td>baz</table>}',
- 'foo<font color=red>[bar]</font>baz',
- 'foo{<font color=red>bar</font>}baz',
- '<span style="color: red">foo<span style="color: blue">[bar]</span>baz</span>',
- '<span style="color: #f00">foo<span style="color: blue">[bar]</span>baz</span>',
- '<span style="color: #ff0000">foo<span style="color: blue">[bar]</span>baz</span>',
- '<span style="color: rgb(255, 0, 0)">foo<span style="color: blue">[bar]</span>baz</span>',
- '<font color=red>foo<font color=blue>[bar]</font>baz</font>',
- '<span style="color: rgb(255, 0, 0)">foo<span style="color: blue">b[ar]</span>baz</span>',
+ 'foo<font color=blue>[bar]</font>baz',
+ 'foo{<font color=blue>bar</font>}baz',
+ '<span style="color: blue">foo<span style="color: brown">[bar]</span>baz</span>',
+ '<span style="color: #00f">foo<span style="color: brown">[bar]</span>baz</span>',
+ '<span style="color: #0000ff">foo<span style="color: brown">[bar]</span>baz</span>',
+ '<span style="color: rgb(0, 0, 255)">foo<span style="color: brown">[bar]</span>baz</span>',
+ '<font color=blue>foo<font color=brown>[bar]</font>baz</font>',
+ '<span style="color: rgb(0, 0, 255)">foo<span style="color: brown">b[ar]</span>baz</span>',
'foo<span id=purple>ba[r</span>ba]z',
- '<span style="color: rgb(255, 0, 0)">foo<span id=purple>b[a]r</span>baz</span>',
+ '<span style="color: rgb(0, 0, 255)">foo<span id=purple>b[a]r</span>baz</span>',
// Tests for queryCommandValue()
- '<font color="red">[foo]</font>',
- '<font color="ff0000">[foo]</font>',
- '<font color="#ff0000">[foo]</font>',
- '<span style="color: red">[foo]</span>',
- '<span style="color: #ff0000">[foo]</span>',
- '<span style="color: rgb(255, 0, 0)">[foo]</span>',
- '<span style="color: rgb(100%, 0, 0)">[foo]</span>',
- '<span style="color: rgb( 255 ,0 ,0)">[foo]</span>',
- '<span style="color: rgba(255, 0, 0, 0.0)">[foo]</span>',
- '<span style="color: rgb(375, -10, 15)">[foo]</span>',
+ '<font color="blue">[foo]</font>',
+ '<font color="0000ff">[foo]</font>',
+ '<font color="#0000ff">[foo]</font>',
+ '<span style="color: blue">[foo]</span>',
+ '<span style="color: #0000ff">[foo]</span>',
+ '<span style="color: rgb(0, 0, 255)">[foo]</span>',
+ '<span style="color: rgb(0%, 0%, 100%)">[foo]</span>',
+ '<span style="color: rgb( 0 ,0 ,255)">[foo]</span>',
+ '<span style="color: rgba(0, 0, 255, 0.0)">[foo]</span>',
+ '<span style="color: rgb(15, -10, 375)">[foo]</span>',
'<span style="color: rgba(0, 0, 0, 1)">[foo]</span>',
'<span style="color: rgba(255, 255, 255, 1)">[foo]</span>',
- '<span style="color: rgba(255, 0, 0, 0.5)">[foo]</span>',
- '<span style="color: hsl(0%, 100%, 50%)">[foo]</span>',
+ '<span style="color: rgba(0, 0, 255, 0.5)">[foo]</span>',
+ '<span style="color: hsl(240, 100%, 50%)">[foo]</span>',
'<span style="color: cornsilk">[foo]</span>',
'<span style="color: transparent">[foo]</span>',
'<span style="color: currentColor">[foo]</span>',
// Tests for queryCommandIndeterm() and queryCommandState()
- 'fo[o<font color=blue>b]ar</font>baz',
- 'foo<font color=blue>ba[r</font>b]az',
- 'fo[o<font color=blue>bar</font>b]az',
- 'foo[<font color=blue>b]ar</font>baz',
- 'foo<font color=blue>ba[r</font>]baz',
- 'foo[<font color=blue>bar</font>]baz',
- 'foo<font color=blue>[bar]</font>baz',
- 'foo{<font color=blue>bar</font>}baz',
- '<font color=blue>fo[o</font><span style=color:blue>b]ar</span>',
- '<span style=color:blue>fo[o</span><span style=color:#0000ff>b]ar</span>',
+ 'fo[o<font color=brown>b]ar</font>baz',
+ 'foo<font color=brown>ba[r</font>b]az',
+ 'fo[o<font color=brown>bar</font>b]az',
+ 'foo[<font color=brown>b]ar</font>baz',
+ 'foo<font color=brown>ba[r</font>]baz',
+ 'foo[<font color=brown>bar</font>]baz',
+ 'foo<font color=brown>[bar]</font>baz',
+ 'foo{<font color=brown>bar</font>}baz',
+ '<font color=brown>fo[o</font><span style=color:brown>b]ar</span>',
+ '<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>',
],
//@}
formatblock: [
@@ -1075,7 +1075,7 @@
'<h1>[foo</h1><h2>bar]</h2>',
'<div>[foo</div>bar]',
- ['<p>', '<div style=color:red>[foo]</div>'],
+ ['<p>', '<div style=color:blue>[foo]</div>'],
],
//@}
forwarddelete: [
@@ -1192,11 +1192,11 @@
'foo[]<blockquote>bar</blockquote>',
'foo[]<blockquote><blockquote>bar</blockquote></blockquote>',
'foo[]<blockquote><div>bar</div></blockquote>',
- 'foo[]<blockquote style="color: red">bar</blockquote>',
+ 'foo[]<blockquote style="color: blue">bar</blockquote>',
'foo[]<blockquote><blockquote><p>bar<p>baz</blockquote></blockquote>',
'foo[]<blockquote><div><p>bar<p>baz</div></blockquote>',
- 'foo[]<blockquote style="color: red"><p>bar<p>baz</blockquote>',
+ 'foo[]<blockquote style="color: blue"><p>bar<p>baz</blockquote>',
'foo[]<blockquote><p><b>bar</b><p>baz</blockquote>',
'foo[]<blockquote><p><strong>bar</strong><p>baz</blockquote>',
@@ -1233,22 +1233,22 @@
'<div><div><p>foo[]</p></div></div><div><div><div><!--abc-->bar</div></div></div>',
// Styled stuff with collapsed selection
- '<p style=color:red>foo[]<p>bar',
- '<p style=color:red>foo[]<p style=color:blue>bar',
- '<p>foo[]<p style=color:blue>bar',
- '<p><font color=red>foo[]</font><p>bar',
- '<p><font color=red>foo[]</font><p><font color=blue>bar</font>',
- '<p>foo[]<p><font color=blue>bar</font>',
- '<p><span style=color:red>foo[]</font><p>bar',
- '<p><span style=color:red>foo[]</font><p><span style=color:blue>bar</font>',
- '<p>foo[]<p><span style=color:blue>bar</font>',
-
- '<p style=background-color:salmon>foo[]<p>bar',
- '<p style=background-color:salmon>foo[]<p style=background-color:aqua>bar',
- '<p>foo[]<p style=background-color:aqua>bar',
- '<p><span style=background-color:salmon>foo[]</font><p>bar',
- '<p><span style=background-color:salmon>foo[]</font><p><span style=background-color:aqua>bar</font>',
- '<p>foo[]<p><span style=background-color:aqua>bar</font>',
+ '<p style=color:blue>foo[]<p>bar',
+ '<p style=color:blue>foo[]<p style=color:brown>bar',
+ '<p>foo[]<p style=color:brown>bar',
+ '<p><font color=blue>foo[]</font><p>bar',
+ '<p><font color=blue>foo[]</font><p><font color=brown>bar</font>',
+ '<p>foo[]<p><font color=brown>bar</font>',
+ '<p><span style=color:blue>foo[]</font><p>bar',
+ '<p><span style=color:blue>foo[]</font><p><span style=color:brown>bar</font>',
+ '<p>foo[]<p><span style=color:brown>bar</font>',
+
+ '<p style=background-color:aqua>foo[]<p>bar',
+ '<p style=background-color:aqua>foo[]<p style=background-color:tan>bar',
+ '<p>foo[]<p style=background-color:tan>bar',
+ '<p><span style=background-color:aqua>foo[]</font><p>bar',
+ '<p><span style=background-color:aqua>foo[]</font><p><span style=background-color:tan>bar</font>',
+ '<p>foo[]<p><span style=background-color:tan>bar</font>',
'<p style=text-decoration:underline>foo[]<p>bar',
'<p style=text-decoration:underline>foo[]<p style=text-decoration:line-through>bar',
@@ -1257,11 +1257,11 @@
'<p><u>foo[]</u><p><s>bar</s>',
'<p>foo[]<p><s>bar</s>',
- '<p style=color:red>foo[]</p>bar',
- 'foo[]<p style=color:blue>bar',
- '<div style=color:red><p style=color:green>foo[]</div>bar',
- '<div style=color:red><p style=color:green>foo[]</div><p style=color:blue>bar',
- '<p style=color:red>foo[]<div style=color:blue><p style=color:green>bar',
+ '<p style=color:blue>foo[]</p>bar',
+ 'foo[]<p style=color:brown>bar',
+ '<div style=color:blue><p style=color:green>foo[]</div>bar',
+ '<div style=color:blue><p style=color:green>foo[]</div><p style=color:brown>bar',
+ '<p style=color:blue>foo[]<div style=color:brown><p style=color:green>bar',
// Uncollapsed selection (should be same as delete command)
'foo[bar]baz',
@@ -1288,7 +1288,7 @@
'<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 style=color:blue>baz]quz',
'<p>foo[bar<p><b>baz]quz</b>',
'<div><p>foo<p>[bar<p>baz]</div>',
@@ -1369,30 +1369,31 @@
'<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>',
'{<table><tr><td>foo<td>bar<td>baz</table>}',
- '<p style="background-color: rgb(255, 136, 136)">foo[bar]baz</p>',
- '<p style="background-color: #ff8888">foo[bar]baz</p>',
+ '<p style="background-color: rgb(0, 255, 255)">foo[bar]baz</p>',
+ '<p style="background-color: #00ffff">foo[bar]baz</p>',
'<p style="background-color: aqua">foo[bar]baz</p>',
'{<p style="background-color: aqua">foo</p><p>bar</p>}',
- '<span style="background-color: #ff8888">foo<span style="background-color: aqua">[bar]</span>baz</span>',
- '<span style="background-color: #f88">foo<span style="background-color: aqua">[bar]</span>baz</span>',
- '<span style="background-color: rgb(255, 136, 136)">foo<span style="background-color: aqua">[bar]</span>baz</span>',
- '<span style="background-color: #ff8888">foo<span style="background-color: aqua">b[ar]</span>baz</span>',
- '<p style="background-color: #ff8888">foo<span style="background-color: aqua">b[ar]</span>baz</p>',
- '<div style="background-color: #ff8888"><p style="background-color: aqua">b[ar]</p></div>',
- '<span style="display: block; background-color: #ff8888"><span style="display: block; background-color: aqua">b[ar]</span></span>',
+ '<span style="background-color: aqua">foo<span style="background-color: tan">[bar]</span>baz</span>',
+ '<span style="background-color: #00ffff">foo<span style="background-color: tan">[bar]</span>baz</span>',
+ '<span style="background-color: #0ff">foo<span style="background-color: tan">[bar]</span>baz</span>',
+ '<span style="background-color: rgb(0, 255, 255)">foo<span style="background-color: tan">[bar]</span>baz</span>',
+ '<span style="background-color: aqua">foo<span style="background-color: tan">b[ar]</span>baz</span>',
+ '<p style="background-color: aqua">foo<span style="background-color: tan">b[ar]</span>baz</p>',
+ '<div style="background-color: aqua"><p style="background-color: tan">b[ar]</p></div>',
+ '<span style="display: block; background-color: aqua"><span style="display: block; background-color: tan">b[ar]</span></span>',
// Tests for queryCommandIndeterm() and queryCommandState()
- 'fo[o<span style=background-color:aqua>b]ar</span>baz',
- 'foo<span style=background-color:aqua>ba[r</span>b]az',
- 'fo[o<span style=background-color:aqua>bar</span>b]az',
- 'foo[<span style=background-color:aqua>b]ar</span>baz',
- 'foo<span style=background-color:aqua>ba[r</span>]baz',
- 'foo[<span style=background-color:aqua>bar</span>]baz',
- 'foo<span style=background-color:aqua>[bar]</span>baz',
- 'foo{<span style=background-color:aqua>bar</span>}baz',
- '<span style=background-color:aqua>fo[o</span><span style=background-color:lime>b]ar</span>',
- '<span style=background-color:aqua>fo[o</span><span style=background-color:aqua>b]ar</span>',
- '<span style=background-color:aqua>fo[o<span style=background-color:transparent>b]ar</span></span>',
+ 'fo[o<span style=background-color:tan>b]ar</span>baz',
+ 'foo<span style=background-color:tan>ba[r</span>b]az',
+ 'fo[o<span style=background-color:tan>bar</span>b]az',
+ 'foo[<span style=background-color:tan>b]ar</span>baz',
+ 'foo<span style=background-color:tan>ba[r</span>]baz',
+ 'foo[<span style=background-color:tan>bar</span>]baz',
+ 'foo<span style=background-color:tan>[bar]</span>baz',
+ 'foo{<span style=background-color:tan>bar</span>}baz',
+ '<span style=background-color:tan>fo[o</span><span style=background-color:yellow>b]ar</span>',
+ '<span style=background-color:tan>fo[o</span><span style=background-color:tan>b]ar</span>',
+ '<span style=background-color:tan>fo[o<span style=background-color:transparent>b]ar</span></span>',
],
//@}
indent: [
@@ -1710,8 +1711,8 @@
['<nobr>abc</nobr>', '<nobr>f[o]o</nobr>'],
['<nobr>abc</nobr>', 'f[o]o'],
- ['<p>abc', '<font color=red>foo[]bar</font>'],
- ['<p>abc', '<span style=color:red>foo[]bar</span>'],
+ ['<p>abc', '<font color=blue>foo[]bar</font>'],
+ ['<p>abc', '<span style=color:blue>foo[]bar</span>'],
['<p>abc', '<span style=font-variant:small-caps>foo[]bar</span>'],
[' ', '<p>[foo]</p>'],
['<span style=display:none></span>', '<p>[foo]</p>'],
@@ -1746,7 +1747,7 @@
'<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 style=color:blue>baz]quz',
'<p>foo[bar<p><b>baz]quz</b>',
'<div><p>foo<p>[bar<p>baz]</div>',
@@ -1951,13 +1952,13 @@
// Attributes
'<ul id=abc><li>foo<li>[bar]<li>baz</ul>',
- '<ul style=color:red><li>foo<li>[bar]<li>baz</ul>',
+ '<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>',
'<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>',
'<ul id=abc><li>[foo]<li>bar<li>baz</ul>',
- '<ul style=color:red><li>[foo]<li>bar<li>baz</ul>',
+ '<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>',
'<ul style=text-indent:1em><li>[foo]<li>bar<li>baz</ul>',
'<ul id=abc><li>foo<li>bar<li>[baz]</ul>',
- '<ul style=color:red><li>foo<li>bar<li>[baz]</ul>',
+ '<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>',
'<ul style=text-indent:1em><li>foo<li>bar<li>[baz]</ul>',
],
//@}
@@ -2346,13 +2347,13 @@
// Attributes
'<ul id=abc><li>foo<li>[bar]<li>baz</ul>',
- '<ul style=color:red><li>foo<li>[bar]<li>baz</ul>',
+ '<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>',
'<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>',
'<ul id=abc><li>[foo]<li>bar<li>baz</ul>',
- '<ul style=color:red><li>[foo]<li>bar<li>baz</ul>',
+ '<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>',
'<ul style=text-indent:1em><li>[foo]<li>bar<li>baz</ul>',
'<ul id=abc><li>foo<li>bar<li>[baz]</ul>',
- '<ul style=color:red><li>foo<li>bar<li>[baz]</ul>',
+ '<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>',
'<ul style=text-indent:1em><li>foo<li>bar<li>[baz]</ul>',
],
//@}
@@ -2884,7 +2885,7 @@
'<blockquote><div>foo[bar]baz</div></blockquote>',
'<blockquote><div id=abc>foo[bar]baz</div></blockquote>',
'<blockquote id=abc>foo[bar]baz</blockquote>',
- '<blockquote style="color: red">foo[bar]baz</blockquote>',
+ '<blockquote style="color: blue">foo[bar]baz</blockquote>',
'<blockquote><blockquote><p>foo[bar]<p>baz</blockquote></blockquote>',
'<blockquote><blockquote data-abc=def><p>foo[bar]<p>baz</blockquote></blockquote>',
@@ -2892,13 +2893,13 @@
'<blockquote><div><p>foo[bar]<p>baz</div></blockquote>',
'<blockquote><div id=abc><p>foo[bar]<p>baz</div></blockquote>',
'<blockquote id=abc><p>foo[bar]<p>baz</blockquote>',
- '<blockquote style="color: red"><p>foo[bar]<p>baz</blockquote>',
+ '<blockquote style="color: blue"><p>foo[bar]<p>baz</blockquote>',
'<blockquote><p><b>foo[bar]</b><p>baz</blockquote>',
'<blockquote><p><strong>foo[bar]</strong><p>baz</blockquote>',
'<blockquote><p><span>foo[bar]</span><p>baz</blockquote>',
- '<blockquote><blockquote style="color: red"><p>foo[bar]</blockquote><p>baz</blockquote>',
- '<blockquote style="color: red"><blockquote><p>foo[bar]</blockquote><p>baz</blockquote>',
+ '<blockquote><blockquote style="color: blue"><p>foo[bar]</blockquote><p>baz</blockquote>',
+ '<blockquote style="color: blue"><blockquote><p>foo[bar]</blockquote><p>baz</blockquote>',
// Lists!
'<ol><li>foo<li>[bar]<li>baz</ol>',
@@ -2942,19 +2943,19 @@
// Attribute handling on lists
'foo<ol start=5><li>[bar]</ol>baz',
'foo<ol id=abc><li>[bar]</ol>baz',
- 'foo<ol style=color:red><li>[bar]</ol>baz',
+ 'foo<ol style=color:blue><li>[bar]</ol>baz',
'foo<ol><li value=5>[bar]</ol>baz',
'foo<ol><li id=abc>[bar]</ol>baz',
- 'foo<ol><li style=color:red>[bar]</ol>baz',
+ 'foo<ol><li style=color:blue>[bar]</ol>baz',
'<ol><li>foo</li><ol><li value=5>[bar]</ol></ol>',
'<ul><li>foo</li><ol><li value=5>[bar]</ol></ul>',
'<ol><li>foo</li><ol start=5><li>[bar]</ol><li>baz</ol>',
'<ol><li>foo</li><ol id=abc><li>[bar]</ol><li>baz</ol>',
- '<ol><li>foo</li><ol style=color:red><li>[bar]</ol><li>baz</ol>',
+ '<ol><li>foo</li><ol style=color:blue><li>[bar]</ol><li>baz</ol>',
'<ol><li>foo</li><ol style=text-indent:1em><li>[bar]</ol><li>baz</ol>',
'<ol><li>foo</li><ol start=5><li>[bar<li>baz]</ol><li>quz</ol>',
'<ol><li>foo</li><ol id=abc><li>[bar<li>baz]</ol><li>quz</ol>',
- '<ol><li>foo</li><ol style=color:red><li>[bar<li>baz]</ol><li>quz</ol>',
+ '<ol><li>foo</li><ol style=color:blue><li>[bar<li>baz]</ol><li>quz</ol>',
'<ol><li>foo</li><ol style=text-indent:1em><li>[bar<li>baz]</ol><li>quz</ol>',
// List inside indentation element
@@ -3014,8 +3015,8 @@
'foo<em>b[a]r</em>baz',
'[foo<font>bar</font>baz]',
'foo<font>b[a]r</font>baz',
- '[foo<font color=red>bar</font>baz]',
- 'foo<font color=red>b[a]r</font>baz',
+ '[foo<font color=blue>bar</font>baz]',
+ 'foo<font color=blue>b[a]r</font>baz',
'[foo<i>bar</i>baz]',
'foo<i>b[a]r</i>baz',
'[foo<ins>bar</ins>baz]',
@@ -3059,7 +3060,7 @@
'[foo<img src=abc>bar]',
'[foo<video></video>bar]',
'[foo<video src=abc></video>bar]',
- '[foo<svg><circle fill=red r=20 cx=20 cy=20 /></svg>bar]',
+ '[foo<svg><circle fill=blue r=20 cx=20 cy=20 /></svg>bar]',
// Unrecognized elements
'[foo<nonexistentelement>bar</nonexistentelement>baz]',
@@ -3074,8 +3075,8 @@
'foo<span class=foo>b[a]r</span>baz',
'[foo<b style="font-weight: normal">bar</b>baz]',
'foo<b style="font-weight: normal">b[a]r</b>baz',
- '<p style="background-color: red">foo[bar]baz</p>',
- '<p><span style="background-color: red">foo[bar]baz</span></p>',
+ '<p style="background-color: blue">foo[bar]baz</p>',
+ '<p><span style="background-color: blue">foo[bar]baz</span></p>',
'<p style="font-weight: bold">foo[bar]baz</p>',
'<b><p style="font-weight: bold">foo[bar]baz</p></b>',
'<p style="font-variant: small-caps">foo[bar]baz</p>',
@@ -3104,8 +3105,8 @@
'foo<u>[bar]</u>baz',
'foo<span style="text-decoration: underline">[bar]</span>baz',
'<u>foo[bar]baz</u>',
- '<u>foo[b<span style="color:red">ar]ba</span>z</u>',
- '<u>foo[b<span style="color:red" id=foo>ar]ba</span>z</u>',
+ '<u>foo[b<span style="color:blue">ar]ba</span>z</u>',
+ '<u>foo[b<span style="color:blue" id=foo>ar]ba</span>z</u>',
'<u>foo[b<span style="font-size:3em">ar]ba</span>z</u>',
'<u>foo[b<i>ar]ba</i>z</u>',
'<p style="text-decoration: underline">foo[bar]baz</p>',
@@ -3113,30 +3114,30 @@
'foo<s>[bar]</s>baz',
'foo<span style="text-decoration: line-through">[bar]</span>baz',
'<s>foo[bar]baz</s>',
- '<s>foo[b<span style="color:red">ar]ba</span>z</s>',
- '<s>foo[b<span style="color:red" id=foo>ar]ba</span>z</s>',
+ '<s>foo[b<span style="color:blue">ar]ba</span>z</s>',
+ '<s>foo[b<span style="color:blue" id=foo>ar]ba</span>z</s>',
'<s>foo[b<span style="font-size:3em">ar]ba</span>z</s>',
'<s>foo[b<i>ar]ba</i>z</s>',
'<p style="text-decoration: line-through">foo[bar]baz</p>',
'foo<strike>[bar]</strike>baz',
'<strike>foo[bar]baz</strike>',
- '<strike>foo[b<span style="color:red">ar]ba</span>z</strike>',
- '<strike>foo[b<span style="color:red" id=foo>ar]ba</span>z</strike>',
+ '<strike>foo[b<span style="color:blue">ar]ba</span>z</strike>',
+ '<strike>foo[b<span style="color:blue" id=foo>ar]ba</span>z</strike>',
'<strike>foo[b<span style="font-size:3em">ar]ba</span>z</strike>',
'<strike>foo[b<i>ar]ba</i>z</strike>',
'foo<ins>[bar]</ins>baz',
'<ins>foo[bar]baz</ins>',
- '<ins>foo[b<span style="color:red">ar]ba</span>z</ins>',
- '<ins>foo[b<span style="color:red" id=foo>ar]ba</span>z</ins>',
+ '<ins>foo[b<span style="color:blue">ar]ba</span>z</ins>',
+ '<ins>foo[b<span style="color:blue" id=foo>ar]ba</span>z</ins>',
'<ins>foo[b<span style="font-size:3em">ar]ba</span>z</ins>',
'<ins>foo[b<i>ar]ba</i>z</ins>',
'foo<del>[bar]</del>baz',
'<del>foo[bar]baz</del>',
- '<del>foo[b<span style="color:red">ar]ba</span>z</del>',
- '<del>foo[b<span style="color:red" id=foo>ar]ba</span>z</del>',
+ '<del>foo[b<span style="color:blue">ar]ba</span>z</del>',
+ '<del>foo[b<span style="color:blue" id=foo>ar]ba</span>z</del>',
'<del>foo[b<span style="font-size:3em">ar]ba</span>z</del>',
'<del>foo[b<i>ar]ba</i>z</del>',
@@ -3297,8 +3298,8 @@
'foo<u>[bar]</u>baz',
'foo<span style="text-decoration: underline">[bar]</span>baz',
'<u>foo[bar]baz</u>',
- '<u>foo[b<span style="color:red">ar]ba</span>z</u>',
- '<u>foo[b<span style="color:red" id=foo>ar]ba</span>z</u>',
+ '<u>foo[b<span style="color:blue">ar]ba</span>z</u>',
+ '<u>foo[b<span style="color:blue" id=foo>ar]ba</span>z</u>',
'<u>foo[b<span style="font-size:3em">ar]ba</span>z</u>',
'<u>foo[b<i>ar]ba</i>z</u>',
'<p style="text-decoration: underline">foo[bar]baz</p>',
@@ -3306,30 +3307,30 @@
'foo<s>[bar]</s>baz',
'foo<span style="text-decoration: line-through">[bar]</span>baz',
'<s>foo[bar]baz</s>',
- '<s>foo[b<span style="color:red">ar]ba</span>z</s>',
- '<s>foo[b<span style="color:red" id=foo>ar]ba</span>z</s>',
+ '<s>foo[b<span style="color:blue">ar]ba</span>z</s>',
+ '<s>foo[b<span style="color:blue" id=foo>ar]ba</span>z</s>',
'<s>foo[b<span style="font-size:3em">ar]ba</span>z</s>',
'<s>foo[b<i>ar]ba</i>z</s>',
'<p style="text-decoration: line-through">foo[bar]baz</p>',
'foo<strike>[bar]</strike>baz',
'<strike>foo[bar]baz</strike>',
- '<strike>foo[b<span style="color:red">ar]ba</span>z</strike>',
- '<strike>foo[b<span style="color:red" id=foo>ar]ba</span>z</strike>',
+ '<strike>foo[b<span style="color:blue">ar]ba</span>z</strike>',
+ '<strike>foo[b<span style="color:blue" id=foo>ar]ba</span>z</strike>',
'<strike>foo[b<span style="font-size:3em">ar]ba</span>z</strike>',
'<strike>foo[b<i>ar]ba</i>z</strike>',
'foo<ins>[bar]</ins>baz',
'<ins>foo[bar]baz</ins>',
- '<ins>foo[b<span style="color:red">ar]ba</span>z</ins>',
- '<ins>foo[b<span style="color:red" id=foo>ar]ba</span>z</ins>',
+ '<ins>foo[b<span style="color:blue">ar]ba</span>z</ins>',
+ '<ins>foo[b<span style="color:blue" id=foo>ar]ba</span>z</ins>',
'<ins>foo[b<span style="font-size:3em">ar]ba</span>z</ins>',
'<ins>foo[b<i>ar]ba</i>z</ins>',
'foo<del>[bar]</del>baz',
'<del>foo[bar]baz</del>',
- '<del>foo[b<span style="color:red">ar]ba</span>z</del>',
- '<del>foo[b<span style="color:red" id=foo>ar]ba</span>z</del>',
+ '<del>foo[b<span style="color:blue">ar]ba</span>z</del>',
+ '<del>foo[b<span style="color:blue" id=foo>ar]ba</span>z</del>',
'<del>foo[b<span style="font-size:3em">ar]ba</span>z</del>',
'<del>foo[b<i>ar]ba</i>z</del>',
@@ -3414,13 +3415,13 @@
var defaultValues = {
//@{
- backcolor: "#FF8888",
+ backcolor: "#00FFFF",
createlink: "http://www.google.com/",
fontname: "sans-serif",
fontsize: "4",
- forecolor: "#FF0000",
+ forecolor: "#0000FF",
formatblock: "<div>",
- hilitecolor: "#FF8888",
+ hilitecolor: "#00FFFF",
inserthorizontalrule: "",
inserthtml: "ab<b>c</b>d",
insertimage: "/img/lion.svg",
@@ -3430,9 +3431,7 @@
var notes = {
//@{
- backcolor: '<strong>Note:</strong> No spec has yet been written, so the spec column does nothing.',
fontname: 'Note that the body\'s font-family is "serif".',
- hilitecolor: 'In IE we run backColor instead of hiliteColor.',
};
//@}
@@ -3512,6 +3511,69 @@
}
//@}
+function queryOutputHelper(beforeIndeterm, beforeState, beforeValue, afterIndeterm, afterState, afterValue, command, value) {
+//@{
+ var frag = document.createDocumentFragment();
+ var beforeDiv = document.createElement("div");
+ var afterDiv = document.createElement("div");
+ frag.appendChild(beforeDiv);
+ frag.appendChild(afterDiv);
+ beforeDiv.className = afterDiv.className = "extra-results";
+ beforeDiv.textContent = "Before: ";
+ afterDiv.textContent = "After: ";
+
+ beforeDiv.appendChild(document.createElement("span"));
+ afterDiv.appendChild(document.createElement("span"));
+ if (afterIndeterm !== "Exception") {
+ afterDiv.lastChild.className =
+ !afterIndeterm
+ ? "good-result"
+ : "bad-result";
+ }
+ beforeDiv.lastChild.textContent = "indeterm " + beforeIndeterm;
+ afterDiv.lastChild.textContent = "indeterm " + afterIndeterm;
+
+ beforeDiv.appendChild(document.createTextNode(", "));
+ afterDiv.appendChild(document.createTextNode(", "));
+
+ beforeDiv.appendChild(document.createElement("span"));
+ afterDiv.appendChild(document.createElement("span"));
+ if (beforeState !== "Exception" || afterState !== "Exception") {
+ beforeDiv.lastChild.className =
+ afterDiv.lastChild.className =
+ beforeState !== "Exception" && afterState !== "Exception" && beforeState === !afterState
+ ? "good-result"
+ : "bad-result";
+ }
+ beforeDiv.lastChild.textContent = "state " + beforeState;
+ afterDiv.lastChild.textContent = "state " + afterState;
+
+ beforeDiv.appendChild(document.createTextNode(", "));
+ afterDiv.appendChild(document.createTextNode(", "));
+
+ // Hack to get highlighting working right for colors
+ if (command == "backcolor" || command == "forecolor" || command == "hilitecolor") {
+ if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) {
+ value = "#" + value;
+ }
+ }
+
+ beforeDiv.appendChild(document.createElement("span"));
+ afterDiv.appendChild(document.createElement("span"));
+ if (afterValue !== "Exception"
+ && typeof value != "undefined") {
+ afterDiv.lastChild.className =
+ valuesEqual(command, afterValue, value)
+ ? "good-result"
+ : "bad-result";
+ }
+ beforeDiv.lastChild.textContent = "value " + beforeValue;
+ afterDiv.lastChild.textContent = "value " + afterValue;
+
+ return frag;
+}
+//@}
+
function doInputCell(tr, test) {
//@{
var value = null;
@@ -3553,8 +3615,24 @@
}
specCell.firstChild.contentEditable = "true";
specCell.firstChild.spellcheck = false;
- myExecCommand("styleWithCSS", false, styleWithCss);
+ myExecCommand("styleWithCSS", false, styleWithCss, range);
+
+ try { var beforeIndeterm = myQueryCommandIndeterm(command, range) }
+ catch(e) { beforeIndeterm = "Exception" }
+ try { var beforeState = myQueryCommandState(command, range) }
+ catch(e) { beforeState = "Exception" }
+ try { var beforeValue = myQueryCommandValue(command, range) }
+ catch(e) { beforeValue = "Exception" }
+
myExecCommand(command, false, value, range);
+
+ try { var afterIndeterm = myQueryCommandIndeterm(command, range) }
+ catch(e) { afterIndeterm = "Exception" }
+ try { var afterState = myQueryCommandState(command, range) }
+ catch(e) { afterState = "Exception" }
+ try { var afterValue = myQueryCommandValue(command, range) }
+ catch(e) { afterValue = "Exception" }
+
specCell.firstChild.contentEditable = "inherit";
specCell.firstChild.removeAttribute("spellcheck");
var compareDiv1 = specCell.firstChild.cloneNode(true);
@@ -3586,6 +3664,10 @@
}
specCell.lastChild.textContent = specCell.firstChild.innerHTML;
+ specCell.lastChild.appendChild(queryOutputHelper(
+ beforeIndeterm, beforeState, beforeValue,
+ afterIndeterm, afterState, afterValue,
+ command, value));
} catch (e) {
specCell.firstChild.contentEditable = "inherit";
specCell.firstChild.removeAttribute("spellcheck");