I forgot there's such a thing as "effective value"
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 28 Jun 2011 11:57:05 -0600
changeset 333 c10760dd0af0
parent 332 6e74be75cba7
child 334 e08705e86018
I forgot there's such a thing as "effective value"

Also make use of the new fact that there are sanity checks on what the
active range can be.
editcommands.html
implementation.js
source.html
--- a/editcommands.html	Tue Jun 28 10:49:22 2011 -0600
+++ b/editcommands.html	Tue Jun 28 11:57:05 2011 -0600
@@ -2151,7 +2151,11 @@
 understand CSS font-family syntax?), so I don't think such usability concerns
 apply. -->
 
-<p><a href=#value>Value</a>:
+<p><a href=#value>Value</a>: The <a href=#effective-value>effective 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.
 
 IE 9 RC: Always the empty string.  Not very useful.
@@ -2168,17 +2172,6 @@
 I'm just going to punt on this and say it should be the computed value of
 font-family.  I'll leave CSSOM to decide what that means if there are no
 applicable style rules. -->
-<ol>
-  <li>Let <var title="">node</var> be the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <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> of the <a href=#active-range>active
-  range</a>.
-
-  <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, set <var title="">node</var> to its
-  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
-
-  <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, return the empty string.
-
-  <li>Return the <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> of "font-family" for <var title="">node</var>.
-</ol>
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "font-family"
 
@@ -2311,15 +2304,12 @@
 browsers behave differently.  I see no reason to behave differently.
 -->
 <ol>
-  <li>Let <var title="">node</var> be the <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>.
-
-  <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, set <var title="">node</var> to its
-  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
-
-  <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, return "3".
-
-  <li>Let <var title="">pixel size</var> be the <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> of "font-size" for
-  <var title="">node</var>, in pixels.
+  <li>Let <var title="">pixel size</var> be the <a href=#effective-value>effective 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.
 
   <li>Let <var title="">returned size</var> be 1.
 
@@ -2427,7 +2417,11 @@
 not state.  Firefox 4b11 throws an exception, which is an interesting approach,
 but I'll go with IE/WebKit, which makes at least as much sense. -->
 
-<p><a href=#value>Value</a>:
+<p><a href=#value>Value</a>: The <a href=#effective-value>effective 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.
 <!--
 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
@@ -2436,16 +2430,6 @@
 getComputedStyle() but rgb() here, and also drops the transparent part of the
 color if there is any.
 -->
-<ol>
-  <li>Let <var title="">node</var> be the <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>.
-
-  <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, set <var title="">node</var> to its
-  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
-
-  <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, return "rgb(0, 0, 0)".
-
-  <li>Return the <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> of "color" on <var title="">node</var>.
-</ol>
 
 <p><a href=#relevant-css-property>Relevant CSS property</a>: "color"
 
--- a/implementation.js	Tue Jun 28 10:49:22 2011 -0600
+++ b/implementation.js	Tue Jun 28 11:57:05 2011 -0600
@@ -590,16 +590,29 @@
  * range in the Selection given by calling getSelection() on the context
  * object, or null if there is no such range."
  *
- * We cheat and return globalRange if that's defined.
+ * We cheat and return globalRange if that's defined.  We also ensure that the
+ * active range meets the requirements that selection boundary points are
+ * supposed to meet, i.e., that the nodes are both Text or Element nodes that
+ * descend from a Document.
  */
 function getActiveRange() {
+	var ret;
 	if (globalRange) {
-		return globalRange;
-	}
-	if (getSelection().rangeCount) {
-		return getSelection().getRangeAt(0);
-	}
-	return null;
+		ret = globalRange;
+	} else if (getSelection().rangeCount) {
+		ret = getSelection().getRangeAt(0);
+	} else {
+		return null;
+	}
+	if ([Node.TEXT_NODE, Node.ELEMENT_NODE].indexOf(ret.startContainer.nodeType) == -1
+	|| [Node.TEXT_NODE, Node.ELEMENT_NODE].indexOf(ret.endContainer.nodeType) == -1
+	|| !ret.startContainer.ownerDocument
+	|| !ret.endContainer.ownerDocument
+	|| !isDescendant(ret.startContainer, ret.startContainer.ownerDocument)
+	|| !isDescendant(ret.endContainer, ret.endContainer.ownerDocument)) {
+		throw "Invalid active range; test bug?";
+	}
+	return ret;
 }
 //@}
 
@@ -2685,21 +2698,8 @@
 			setNodeValue(nodeList[i], "fontname", value);
 		}
 	}, value: function() {
-		// "Let node be the start node of the active range."
-		var node = getActiveRange().startContainer;
-
-		// "If node is not an Element, set node to its parent."
-		if (node.nodeType != Node.ELEMENT_NODE) {
-			node = node.parentNode;
-		}
-
-		// "If node is not an Element, return the empty string."
-		if (node.nodeType != Node.ELEMENT_NODE) {
-			return "";
-		}
-
-		// "Return the computed value of "font-family" for node."
-		return getComputedStyle(node).fontFamily;
+		// "The effective value of the active range's start node."
+		return getEffectiveValue(getActiveRange().startContainer, "fontname");
 	}, relevantCssProperty: "fontFamily"
 };
 //@}
@@ -2796,22 +2796,9 @@
 			setNodeValue(nodeList[i], "fontsize", value);
 		}
 	}, value: function() {
-		// "Let node be the active range's start node."
-		var node = getActiveRange().startContainer;
-
-		// "If node is not an Element, set node to its parent."
-		if (node.nodeType != Node.ELEMENT_NODE) {
-			node = node.parentNode;
-		}
-
-		// "If node is not an Element, return "3"."
-		if (node.nodeType != Node.ELEMENT_NODE) {
-			return "3";
-		}
-
-		// "Let pixel size be the computed value of "font-size" for node, in
-		// pixels."
-		var pixelSize = parseInt(getComputedStyle(node).fontSize);
+		// "Let pixel size be the effective value of the active range's start
+		// node, as a number of pixels."
+		var pixelSize = parseInt(getEffectiveValue(getActiveRange().startContainer, "fontsize"));
 
 		// "Let returned size be 1."
 		var returnedSize = 1;
@@ -2882,31 +2869,18 @@
 			setNodeValue(nodeList[i], "forecolor", value);
 		}
 	}, value: function() {
-		// "Let node be the active range's start node."
-		var node = getActiveRange().startContainer;
-
-		// "If node is not an Element, set node to its parent."
-		if (node.nodeType != Node.ELEMENT_NODE) {
-			node = node.parentNode;
-		}
-
-		// "If node is not an Element, return "rgb(0, 0, 0)"."
-		if (node.nodeType != Node.ELEMENT_NODE) {
-			return "rgb(0, 0, 0)";
-		}
-
-		// "Return the computed value of "color" on node."
+		// "The effective 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 computed value stuff is underdefined
 		// anyway).
-		var computed = getComputedStyle(node).color;
-		if (/^#[0-9a-f]{6}$/.test(computed)) {
-			computed = "rgb(" + parseInt(computed.slice(1, 3), 16)
-				+ "," + parseInt(computed.slice(3, 5), 16)
-				+ "," + parseInt(computed.slice(5), 16) + ")";
-		}
-		return computed;
+		var value = getEffectiveValue(getActiveRange().startContainer, "forecolor");
+		if (/^#[0-9a-f]{6}$/.test(value)) {
+			value = "rgb(" + parseInt(value.slice(1, 3), 16)
+				+ "," + parseInt(value.slice(3, 5), 16)
+				+ "," + parseInt(value.slice(5), 16) + ")";
+		}
+		return value;
 	}, relevantCssProperty: "color"
 };
 //@}
--- a/source.html	Tue Jun 28 10:49:22 2011 -0600
+++ b/source.html	Tue Jun 28 11:57:05 2011 -0600
@@ -2127,7 +2127,11 @@
 understand CSS font-family syntax?), so I don't think such usability concerns
 apply. -->
 
-<p><span>Value</span>:
+<p><span>Value</span>: The <span>effective 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.
 
 IE 9 RC: Always the empty string.  Not very useful.
@@ -2144,17 +2148,6 @@
 I'm just going to punt on this and say it should be the computed value of
 font-family.  I'll leave CSSOM to decide what that means if there are no
 applicable style rules. -->
-<ol>
-  <li>Let <var>node</var> be the [[startnode]] of the <span>active
-  range</span>.
-
-  <li>If <var>node</var> is not an [[element]], set <var>node</var> to its
-  [[parent]].
-
-  <li>If <var>node</var> is not an [[element]], return the empty string.
-
-  <li>Return the [[compval]] of "font-family" for <var>node</var>.
-</ol>
 
 <p><span>Relevant CSS property</span>: "font-family"
 <!-- @} -->
@@ -2287,15 +2280,12 @@
 browsers behave differently.  I see no reason to behave differently.
 -->
 <ol>
-  <li>Let <var>node</var> be the <span>active range</span>'s [[startnode]].
-
-  <li>If <var>node</var> is not an [[element]], set <var>node</var> to its
-  [[parent]].
-
-  <li>If <var>node</var> is not an [[element]], return "3".
-
-  <li>Let <var>pixel size</var> be the [[compval]] of "font-size" for
-  <var>node</var>, in pixels.
+  <li>Let <var>pixel size</var> be the <span>effective 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.
 
   <li>Let <var>returned size</var> be 1.
 
@@ -2403,7 +2393,11 @@
 not state.  Firefox 4b11 throws an exception, which is an interesting approach,
 but I'll go with IE/WebKit, which makes at least as much sense. -->
 
-<p><span>Value</span>:
+<p><span>Value</span>: The <span>effective 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.
 <!--
 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
@@ -2412,16 +2406,6 @@
 getComputedStyle() but rgb() here, and also drops the transparent part of the
 color if there is any.
 -->
-<ol>
-  <li>Let <var>node</var> be the <span>active range</span>'s [[startnode]].
-
-  <li>If <var>node</var> is not an [[element]], set <var>node</var> to its
-  [[parent]].
-
-  <li>If <var>node</var> is not an [[element]], return "rgb(0, 0, 0)".
-
-  <li>Return the [[compval]] of "color" on <var>node</var>.
-</ol>
 
 <p><span>Relevant CSS property</span>: "color"
 <!-- @} -->