Define indeterm for bold
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 28 Jun 2011 13:32:08 -0600
changeset 336 4be87fc75653
parent 335 a2ecb1a224ce
child 337 82989e38ad2e
Define indeterm for bold

Also lower the cutoff for boldness from 700 to 600, for reasons noted in
a comment I added.
editcommands.html
implementation.js
source.html
tests.js
--- a/editcommands.html	Tue Jun 28 12:40:22 2011 -0600
+++ b/editcommands.html	Tue Jun 28 13:32:08 2011 -0600
@@ -334,24 +334,31 @@
 method on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> interface does
 the same thing as <code><a href=#querycommandsupported()>queryCommandSupported()</a></code>.
 
-<p class=XXX>The <dfn id=querycommandindeterm() title=queryCommandIndeterm()><code>queryCommandIndeterm(<var title="">command</var>)</code></dfn>
-method on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> interface is a
-useless method that always returns false.  I think.
+<p>The <dfn id=querycommandindeterm() title=queryCommandIndeterm()><code>queryCommandIndeterm(<var title="">command</var>)</code></dfn>
+method on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> interface allows
+scripts to determine whether the selection is in a mixed or indeterminate
+state, like (for <a href=#the-bold-command>the <code title="">bold</code> command</a>) partly bold
+and partly not.  An editing toolbar with a "bold" button might show it
+differently if the selection is indeterminate.
 
 <p>The <dfn id=querycommandstate() title=queryCommandState()><code>queryCommandState(<var title="">command</var>)</code></dfn>
 method on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> interface allows
 scripts to ask true-or-false status questions about the current selection, such
-as whether it is bold or not.
+as whether it is bold or not.  An editing toolbar with a "bold" button might
+show it as preseed down if the state is true and undepressed if the state is
+false.
 
 <p>The <dfn id=querycommandsupported() title=queryCommandSupported()><code>queryCommandSupported(<var title="">command</var>)</code></dfn>
 method on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> interface allows
 scripts to determine whether a particular command is supported or will do
-nothing.
+nothing.  Authors might write their scripts to use some type of fallback if a
+command is unsupported, or display an error.
 
 <p>The <dfn id=querycommandvalue() title=queryCommandValue()><code>queryCommandValue(<var title="">command</var>)</code></dfn>
 method on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> interface allows
 scripts to get the value of some property of the current selection in string
-form, such as what color it is.
+form, such as what color it is.  Usually this will return the value for the
+beginning of the selection, if it's not the same for the whole selection.
 
 <p>All of these methods operate using particular <dfn id=command title=command>commands</dfn>, identified by a string <var title="">command</var> passed
 as the first argument.  The <var title="">command</var> argument of all the methods must
@@ -2044,9 +2051,31 @@
 If the <a href=#state>state</a> is then false, <a href=#set-the-value>set the value</a> of each
 returned <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> to "bold", otherwise <a href=#set-the-value>set the value</a> to "normal".
 
+<p><a href=#indeterminate-flag>Indeterminate flag</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
+range</a>, there is at least one with <a href=#effective-value>effective value</a> less than
+600 and at least one with <a href=#effective-value>effective value</a> greater than or equal to
+600.  Otherwise false.
+<!--
+The cutoff of 600 (both here and for state) matches Chrome 14 dev.  The cutoff
+used by IE9 and Firefox 6.0a2 seems to be 500, and the distinction isn't
+relevant for Opera 11.11 (it doesn't use CSS here at all AFAICT).  On my test
+systems with default fonts, Chrome 14 dev displays 700 and up as bold, while
+the other three display 600 and up as bold.
+
+Thus in Chrome on my system, the bold command will behave a bit oddly the first
+time you hit it if there's anything in the range with font-weight: 600, but it
+will look right in other browsers.  On the other hand, if I followed
+IE/Firefox, it would look wrong on all my browsers for font-weight: 500.
+
+700 actually makes more sense: then you'd view 100-300 as light, 400-600 as
+medium, 700-900 as bold.  But that's not how it seems to work in browsers, so
+I'll go with 600 as the cutoff.
+-->
+
 <p><a href=#state>State</a>: True if every <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> has
-<a href=#effective-value>effective value</a> at least 700, and there is at least one such
+<a href=#effective-value>effective value</a> at least 600, and there is at least one such
 <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.  Otherwise false.
 <!--
 For bold and similar commands, IE 9 RC seems to consider the state true or
--- a/implementation.js	Tue Jun 28 12:40:22 2011 -0600
+++ b/implementation.js	Tue Jun 28 13:32:08 2011 -0600
@@ -202,6 +202,41 @@
 		|| ns === htmlNamespace;
 }
 
+// For computing indeterminate flags of the form "True if among editable Text
+// nodes that are effectively contained in the active range, there is at least
+// one with (property X) and at least one with (property not-X).  Otherwise
+// false."
+function indetermHelper(callback) {
+	var range = getActiveRange();
+	// XXX: This algorithm for getting all effectively contained nodes might be
+	// wrong . . .
+	var node = range.startContainer;
+	while (node.parentNode && node.parentNode.firstChild == node) {
+		node = node.parentNode;
+	}
+	var stop = nextNodeDescendants(range.endContainer);
+
+	var hasProperty = false;
+	var lacksProperty = false;
+	for (; node && node != stop; node = nextNode(node)) {
+		if (!isEffectivelyContained(node, range)
+		|| node.nodeType != Node.TEXT_NODE
+		|| !isEditable(node)) {
+			continue;
+		}
+
+		if (callback(node)) {
+			hasProperty = true;
+		} else {
+			lacksProperty = true;
+		}
+		if (hasProperty && lacksProperty) {
+			return true;
+		}
+	}
+	return false;
+}
+
 // For computing states of the form "True if every editable Text node that is
 // effectively contained in the active range (has property X), and there is at
 // least one such Text node.  Otherwise false."
@@ -2640,12 +2675,24 @@
 		for (var i = 0; i < nodeList.length; i++) {
 			setNodeValue(nodeList[i], "bold", newValue);
 		}
-	}, state: function() { return stateHelper(function(node) {
+	}, indeterm: function() { return indetermHelper(function(node) {
+		// "True if among editable Text nodes that are effectively contained in
+		// the active range, there is at least one with effective value less
+		// than 600 and at least one with effective value greater than or equal
+		// to 600."
+		var fontWeight = getEffectiveValue(node, "bold");
+		return fontWeight === "bold"
+			|| fontWeight === "600"
+			|| fontWeight === "700"
+			|| fontWeight === "800"
+			|| fontWeight === "900";
+	})}, state: function() { return stateHelper(function(node) {
 		// "True if every editable Text node that is effectively contained in
-		// the active range has effective value at least 700, and there is at
+		// the active range has effective value at least 600, and there is at
 		// least one such text node. Otherwise false."
 		var fontWeight = getEffectiveValue(node, "bold");
 		return fontWeight === "bold"
+			|| fontWeight === "600"
 			|| fontWeight === "700"
 			|| fontWeight === "800"
 			|| fontWeight === "900";
--- a/source.html	Tue Jun 28 12:40:22 2011 -0600
+++ b/source.html	Tue Jun 28 13:32:08 2011 -0600
@@ -269,28 +269,35 @@
 method on the <code data-anolis-spec=html>HTMLDocument</code> interface does
 the same thing as <code>queryCommandSupported()</code>.
 
-<p class=XXX>The <dfn
+<p>The <dfn
 title=queryCommandIndeterm()><code>queryCommandIndeterm(<var>command</var>)</code></dfn>
-method on the <code data-anolis-spec=html>HTMLDocument</code> interface is a
-useless method that always returns false.  I think.
+method on the <code data-anolis-spec=html>HTMLDocument</code> interface allows
+scripts to determine whether the selection is in a mixed or indeterminate
+state, like (for <span>the <code title>bold</code> command</span>) partly bold
+and partly not.  An editing toolbar with a "bold" button might show it
+differently if the selection is indeterminate.
 
 <p>The <dfn
 title=queryCommandState()><code>queryCommandState(<var>command</var>)</code></dfn>
 method on the <code data-anolis-spec=html>HTMLDocument</code> interface allows
 scripts to ask true-or-false status questions about the current selection, such
-as whether it is bold or not.
+as whether it is bold or not.  An editing toolbar with a "bold" button might
+show it as preseed down if the state is true and undepressed if the state is
+false.
 
 <p>The <dfn
 title=queryCommandSupported()><code>queryCommandSupported(<var>command</var>)</code></dfn>
 method on the <code data-anolis-spec=html>HTMLDocument</code> interface allows
 scripts to determine whether a particular command is supported or will do
-nothing.
+nothing.  Authors might write their scripts to use some type of fallback if a
+command is unsupported, or display an error.
 
 <p>The <dfn
 title=queryCommandValue()><code>queryCommandValue(<var>command</var>)</code></dfn>
 method on the <code data-anolis-spec=html>HTMLDocument</code> interface allows
 scripts to get the value of some property of the current selection in string
-form, such as what color it is.
+form, such as what color it is.  Usually this will return the value for the
+beginning of the selection, if it's not the same for the whole selection.
 
 <p>All of these methods operate using particular <dfn
 title=command>commands</dfn>, identified by a string <var>command</var> passed
@@ -2020,9 +2027,31 @@
 If the <span>state</span> is then false, <span>set the value</span> of each
 returned [[node]] to "bold", otherwise <span>set the value</span> to "normal".
 
+<p><span>Indeterminate flag</span>: True if among <span>editable</span>
+[[text]] nodes that are <span>effectively contained</span> in the <span>active
+range</span>, there is at least one with <span>effective value</span> less than
+600 and at least one with <span>effective value</span> greater than or equal to
+600.  Otherwise false.
+<!--
+The cutoff of 600 (both here and for state) matches Chrome 14 dev.  The cutoff
+used by IE9 and Firefox 6.0a2 seems to be 500, and the distinction isn't
+relevant for Opera 11.11 (it doesn't use CSS here at all AFAICT).  On my test
+systems with default fonts, Chrome 14 dev displays 700 and up as bold, while
+the other three display 600 and up as bold.
+
+Thus in Chrome on my system, the bold command will behave a bit oddly the first
+time you hit it if there's anything in the range with font-weight: 600, but it
+will look right in other browsers.  On the other hand, if I followed
+IE/Firefox, it would look wrong on all my browsers for font-weight: 500.
+
+700 actually makes more sense: then you'd view 100-300 as light, 400-600 as
+medium, 700-900 as bold.  But that's not how it seems to work in browsers, so
+I'll go with 600 as the cutoff.
+-->
+
 <p><span>State</span>: True if every <span>editable</span> [[text]] node that
 is <span>effectively contained</span> in the <span>active range</span> has
-<span>effective value</span> at least 700, and there is at least one such
+<span>effective value</span> at least 600, and there is at least one such
 [[text]] node.  Otherwise false.
 <!--
 For bold and similar commands, IE 9 RC seems to consider the state true or
--- a/tests.js	Tue Jun 28 12:40:22 2011 -0600
+++ b/tests.js	Tue Jun 28 13:32:08 2011 -0600
@@ -157,8 +157,13 @@
 		'<b id=purple>bar [baz] qoz</b>',
 
 		'foo<span style="font-weight: 100">[bar]</span>baz',
+		'foo<span style="font-weight: 200">[bar]</span>baz',
+		'foo<span style="font-weight: 300">[bar]</span>baz',
 		'foo<span style="font-weight: 400">[bar]</span>baz',
+		'foo<span style="font-weight: 500">[bar]</span>baz',
+		'foo<span style="font-weight: 600">[bar]</span>baz',
 		'foo<span style="font-weight: 700">[bar]</span>baz',
+		'foo<span style="font-weight: 800">[bar]</span>baz',
 		'foo<span style="font-weight: 900">[bar]</span>baz',
 		'foo<span style="font-weight: 400">[bar</span>]baz',
 		'foo<span style="font-weight: 700">[bar</span>]baz',
@@ -204,6 +209,25 @@
 		'<b><span class=notbold>foo[bar]baz</span></b>',
 
 		'<p style="font-weight: bold">foo[bar]baz</p>',
+
+		// Tests for queryCommandIndeterm()
+		'fo[o<b>b]ar</b>baz',
+		'foo<b>ba[r</b>b]az',
+		'fo[o<b>bar</b>b]az',
+		'foo[<b>b]ar</b>baz',
+		'foo<b>ba[r</b>]baz',
+		'foo[<b>bar</b>]baz',
+		'foo<b>[bar]</b>baz',
+		'foo{<b>bar</b>}baz',
+		'fo[o<span style=font-weight:bold>b]ar</span>baz',
+		'<span style=font-weight:800>fo[o</span><span style=font-weight:900>b]ar</span>',
+		'<span style=font-weight:700>fo[o</span><span style=font-weight:800>b]ar</span>',
+		'<span style=font-weight:600>fo[o</span><span style=font-weight:700>b]ar</span>',
+		'<span style=font-weight:500>fo[o</span><span style=font-weight:600>b]ar</span>',
+		'<span style=font-weight:400>fo[o</span><span style=font-weight:500>b]ar</span>',
+		'<span style=font-weight:300>fo[o</span><span style=font-weight:400>b]ar</span>',
+		'<span style=font-weight:200>fo[o</span><span style=font-weight:300>b]ar</span>',
+		'<span style=font-weight:100>fo[o</span><span style=font-weight:200>b]ar</span>',
 	],
 	//@}
 	createlink: [