Define value for justify*
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 28 Jun 2011 12:40:22 -0600
changeset 335 a2ecb1a224ce
parent 334 e08705e86018
child 336 4be87fc75653
Define value for justify*

This seems to be all the values that need defining, although I haven't
tested every single command in every single browser.
editcommands.html
implementation.js
source.html
--- a/editcommands.html	Tue Jun 28 12:07:01 2011 -0600
+++ b/editcommands.html	Tue Jun 28 12:40:22 2011 -0600
@@ -3231,7 +3231,40 @@
   </ol>
 </ol>
 
-<p>The <dfn id=current-alignment-state>current alignment state</dfn> is returned by the following
+<p>The <dfn id=alignment-value>alignment value</dfn> of a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> <var title="">node</var> is returned by
+the following algorithm:
+<!--
+When querying the value of justify*, IE9 seems to return boolean false across
+the board when it doesn't throw exceptions, which it usually does in my tests.
+Chrome 14 dev returns the string "true" or "false" depending on state, as in
+other cases, which is useless.  Opera 11.11 returns "" across the board.
+Firefox 6.0a2 behaves like with other command values: it returns
+"center"/"justify"/"left"/"right" depending on the active range's start node.
+Since this is the only behavior that's possibly useful, it's what I specced.
+Firefox ties the value closely to the state, returning true for the state if
+and only if the value matches the desired value, but this seems less useful
+than what I've specced for the state.
+-->
+<ol>
+  <li>While <var title="">node</var> is neither null nor 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>, or it is 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> but its "display" property has <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> "inline" or "none",
+  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 "left".
+  <!-- This means there's no applicable style rule, so probably it will wind up
+  left-aligned.  Of course this ignores the fact that the alignment will really
+  be "start", per the XXX below, so this is wrong for RTL, but it's a pretty
+  marginal corner case anyway.  (It will only happen if, e.g., everything up to
+  and including the html and body elements have display: inline or none.) -->
+
+  <li>Return "center", "justify", "left", or "right", depending on the
+  <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> of <var title="">node</var>'s "text-align" property.
+
+  <p class=XXX>What to do for "start" "auto" etc. currently undefined.  We
+  assume something CSS 2.1-ish.
+</ol>
+
+<p>The <dfn id="selection's-alignment-value">selection's alignment value</dfn> is returned by the following
 algorithm:
 <!--
 IE9 throws exceptions in almost every case when querying the state of justify*,
@@ -3270,22 +3303,11 @@
   <li>For each <var title="">node</var> in <var title="">node list</var>:
 
   <ol>
-    <li>While <var title="">node</var> is neither null nor 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>, or it is 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> but its "display" property has <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> "inline" or "none",
-    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> or its "display" property has
-    <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> "inline" or "none", continue with the next <var title="">node</var>.
-
-    <li>If <var title="">state</var> is "none", set <var title="">state</var> to either "center",
-    "justify", "left", or "right", depending on the <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> of
-    <var title="">node</var>'s "text-align" property.
-
-    <p class=XXX>What to do for "start" "auto" etc. currently undefined.  We
-    assume something CSS 2.1-ish.
-
-    <li>If <var title="">state</var> is different from the <a href=http://www.w3.org/TR/CSS21/cascade.html#computed-value>computed value</a> of
-    <var title="">node</var>'s "text-align" property, return "none".
+    <li>If <var title="">state</var> is "none", set <var title="">state</var> to
+    <var title="">node</var>'s <a href=#alignment-value>alignment value</a>.
+
+    <li>If <var title="">state</var> is different from <var title="">node</var>'s <a href=#alignment-value>alignment
+    value</a>, return "none".
   </ol>
 
   <li>Return <var title="">state</var>.
@@ -6204,36 +6226,48 @@
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "center".
 
-<p><a href=#state>State</a>: True if the <a href=#current-alignment-state>current alignment state</a> is
+<p><a href=#state>State</a>: True if the <a href="#selection's-alignment-value">selection's alignment value</a> is
 "center", otherwise false.
 
+<p><a href=#value>Value</a>: 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>'s
+<a href=#alignment-value>alignment value</a>.
+
 
 <h3 id=the-justifyfull-command><span class=secno>7.22 </span><dfn>The <code title="">justifyFull</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "justify".
 
-<p><a href=#state>State</a>: True if the <a href=#current-alignment-state>current alignment state</a> is
+<p><a href=#state>State</a>: True if the <a href="#selection's-alignment-value">selection's alignment value</a> is
 "justify", otherwise false.
 
+<p><a href=#value>Value</a>: 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>'s
+<a href=#alignment-value>alignment value</a>.
+
 
 <h3 id=the-justifyleft-command><span class=secno>7.23 </span><dfn>The <code title="">justifyLeft</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "left".
 
-<p><a href=#state>State</a>: True if the <a href=#current-alignment-state>current alignment state</a> is
+<p><a href=#state>State</a>: True if the <a href="#selection's-alignment-value">selection's alignment value</a> is
 "left", otherwise false.
 
+<p><a href=#value>Value</a>: 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>'s
+<a href=#alignment-value>alignment value</a>.
+
 
 <h3 id=the-justifyright-command><span class=secno>7.24 </span><dfn>The <code title="">justifyRight</code> command</dfn></h3>
 
 <p><a href=#action>Action</a>: <a href=#justify-the-selection>Justify the selection</a> with
 <var title="">alignment</var> "right".
 
-<p><a href=#state>State</a>: True if the <a href=#current-alignment-state>current alignment state</a> is
+<p><a href=#state>State</a>: True if the <a href="#selection's-alignment-value">selection's alignment value</a> is
 "right", otherwise false.
 
+<p><a href=#value>Value</a>: 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>'s
+<a href=#alignment-value>alignment value</a>.
+
 
 <h3 id=the-outdent-command><span class=secno>7.25 </span><dfn>The <code title="">outdent</code> command</dfn></h3>
 
--- a/implementation.js	Tue Jun 28 12:07:01 2011 -0600
+++ b/implementation.js	Tue Jun 28 12:40:22 2011 -0600
@@ -3627,7 +3627,27 @@
 	}
 }
 
-function getCurrentAlignmentState() {
+function getAlignmentValue(node) {
+	// "While node is neither null nor an Element, or it is an Element but its
+	// "display" property has computed value "inline" or "none", set node to
+	// its parent."
+	while ((node && node.nodeType != Node.ELEMENT_NODE)
+	|| (node.nodeType == Node.ELEMENT_NODE
+	&& ["inline", "none"].indexOf(getComputedStyle(node).display) != -1)) {
+		node = node.parentNode;
+	}
+
+	// "If node is not an Element, return "left"."
+	if (!node || node.nodeType != Node.ELEMENT_NODE) {
+		return "left";
+	}
+
+	// "Return "center", "justify", "left", or "right", depending on the
+	// computed value of node's "text-align" property."
+	return getRealTextAlign(node);
+}
+
+function getSelectionAlignmentValue() {
 	// "Block-extend the active range, and let new range be the result."
 	var newRange = blockExtendRange(getActiveRange());
 
@@ -3647,33 +3667,13 @@
 	for (var i = 0; i < nodeList.length; i++) {
 		var node = nodeList[i];
 
-		// "While node is neither null nor an Element, or it is an Element
-		// but its "display" property has computed value "inline" or
-		// "none", set node to its parent."
-		while ((node && node.nodeType != Node.ELEMENT_NODE)
-		|| (node.nodeType == Node.ELEMENT_NODE && getComputedStyle(node).display == "inline")
-		|| (node.nodeType == Node.ELEMENT_NODE && getComputedStyle(node).display == "none")) {
-			node = node.parentNode;
-		}
-
-		// "If node is not an Element or its "display" property has computed
-		// value "inline" or "none", continue with the next node."
-		if (node.nodeType != Node.ELEMENT_NODE
-		|| getComputedStyle(node).display == "inline"
-		|| getComputedStyle(node).display == "none") {
-			continue;
-		}
-
-		// "If state is "none", set state to either "center", "justify",
-		// "left", or "right", depending on the computed value of node's
-		// "text-align" property."
+		// "If state is "none", set state to node's alignment value."
 		if (state == "none") {
-			state = getRealTextAlign(node);
-		}
-
-		// "If state is different from the computed value of node's
-		// "text-align" property, return "none"."
-		if (state != getRealTextAlign(node)) {
+			state = getAlignmentValue(node);
+		}
+
+		// "If state is different from node's alignment value, return "none"."
+		if (state != getAlignmentValue(node)) {
 			return "none";
 		}
 	}
@@ -6316,8 +6316,10 @@
 commands.justifycenter = {
 	// "Justify the selection with alignment "center"."
 	action: function() { justifySelection("center") },
-	// "True if the current alignment state is "center", otherwise false."
-	state: function() { return getCurrentAlignmentState() == "center" },
+	// "True if the selection's alignment value is "center", otherwise false."
+	state: function() { return getSelectionAlignmentValue() == "center" },
+	// "The active range's start node's alignment value."
+	value: function() { return getAlignmentValue(getActiveRange().startContainer) },
 };
 //@}
 
@@ -6326,8 +6328,10 @@
 commands.justifyfull = {
 	// "Justify the selection with alignment "justify"."
 	action: function() { justifySelection("justify") },
-	// "True if the current alignment state is "justify", otherwise false."
-	state: function() { return getCurrentAlignmentState() == "justify" },
+	// "True if the selection's alignment value is "justify", otherwise false."
+	state: function() { return getSelectionAlignmentValue() == "justify" },
+	// "The active range's start node's alignment value."
+	value: function() { return getAlignmentValue(getActiveRange().startContainer) },
 };
 //@}
 
@@ -6336,8 +6340,10 @@
 commands.justifyleft = {
 	// "Justify the selection with alignment "left"."
 	action: function() { justifySelection("left") },
-	// "True if the current alignment state is "left", otherwise false."
-	state: function() { return getCurrentAlignmentState() == "left" },
+	// "True if the selection's alignment value is "left", otherwise false."
+	state: function() { return getSelectionAlignmentValue() == "left" },
+	// "The active range's start node's alignment value."
+	value: function() { return getAlignmentValue(getActiveRange().startContainer) },
 };
 //@}
 
@@ -6346,8 +6352,10 @@
 commands.justifyright = {
 	// "Justify the selection with alignment "right"."
 	action: function() { justifySelection("right") },
-	// "True if the current alignment state is "right", otherwise false."
-	state: function() { return getCurrentAlignmentState() == "right" },
+	// "True if the selection's alignment value is "right", otherwise false."
+	state: function() { return getSelectionAlignmentValue() == "right" },
+	// "The active range's start node's alignment value."
+	value: function() { return getAlignmentValue(getActiveRange().startContainer) },
 };
 //@}
 
--- a/source.html	Tue Jun 28 12:07:01 2011 -0600
+++ b/source.html	Tue Jun 28 12:40:22 2011 -0600
@@ -3216,7 +3216,40 @@
   </ol>
 </ol>
 
-<p>The <dfn>current alignment state</dfn> is returned by the following
+<p>The <dfn>alignment value</dfn> of a [[node]] <var>node</var> is returned by
+the following algorithm:
+<!--
+When querying the value of justify*, IE9 seems to return boolean false across
+the board when it doesn't throw exceptions, which it usually does in my tests.
+Chrome 14 dev returns the string "true" or "false" depending on state, as in
+other cases, which is useless.  Opera 11.11 returns "" across the board.
+Firefox 6.0a2 behaves like with other command values: it returns
+"center"/"justify"/"left"/"right" depending on the active range's start node.
+Since this is the only behavior that's possibly useful, it's what I specced.
+Firefox ties the value closely to the state, returning true for the state if
+and only if the value matches the desired value, but this seems less useful
+than what I've specced for the state.
+-->
+<ol>
+  <li>While <var>node</var> is neither null nor an [[element]], or it is an
+  [[element]] but its "display" property has [[compval]] "inline" or "none",
+  set <var>node</var> to its [[parent]].
+
+  <li>If <var>node</var> is not an [[element]], return "left".
+  <!-- This means there's no applicable style rule, so probably it will wind up
+  left-aligned.  Of course this ignores the fact that the alignment will really
+  be "start", per the XXX below, so this is wrong for RTL, but it's a pretty
+  marginal corner case anyway.  (It will only happen if, e.g., everything up to
+  and including the html and body elements have display: inline or none.) -->
+
+  <li>Return "center", "justify", "left", or "right", depending on the
+  [[compval]] of <var>node</var>'s "text-align" property.
+
+  <p class=XXX>What to do for "start" "auto" etc. currently undefined.  We
+  assume something CSS 2.1-ish.
+</ol>
+
+<p>The <dfn>selection's alignment value</dfn> is returned by the following
 algorithm:
 <!--
 IE9 throws exceptions in almost every case when querying the state of justify*,
@@ -3255,22 +3288,11 @@
   <li>For each <var>node</var> in <var>node list</var>:
 
   <ol>
-    <li>While <var>node</var> is neither null nor an [[element]], or it is an
-    [[element]] but its "display" property has [[compval]] "inline" or "none",
-    set <var>node</var> to its [[parent]].
-
-    <li>If <var>node</var> is not an [[element]] or its "display" property has
-    [[compval]] "inline" or "none", continue with the next <var>node</var>.
-
-    <li>If <var>state</var> is "none", set <var>state</var> to either "center",
-    "justify", "left", or "right", depending on the [[compval]] of
-    <var>node</var>'s "text-align" property.
-
-    <p class=XXX>What to do for "start" "auto" etc. currently undefined.  We
-    assume something CSS 2.1-ish.
-
-    <li>If <var>state</var> is different from the [[compval]] of
-    <var>node</var>'s "text-align" property, return "none".
+    <li>If <var>state</var> is "none", set <var>state</var> to
+    <var>node</var>'s <span>alignment value</span>.
+
+    <li>If <var>state</var> is different from <var>node</var>'s <span>alignment
+    value</span>, return "none".
   </ol>
 
   <li>Return <var>state</var>.
@@ -6224,8 +6246,11 @@
 <p><span>Action</span>: <span>Justify the selection</span> with
 <var>alignment</var> "center".
 
-<p><span>State</span>: True if the <span>current alignment state</span> is
+<p><span>State</span>: True if the <span>selection's alignment value</span> is
 "center", otherwise false.
+
+<p><span>Value</span>: The <span>active range</span>'s [[startnode]]'s
+<span>alignment value</span>.
 <!-- @} -->
 
 <h3><dfn>The <code title>justifyFull</code> command</dfn></h3>
@@ -6233,8 +6258,11 @@
 <p><span>Action</span>: <span>Justify the selection</span> with
 <var>alignment</var> "justify".
 
-<p><span>State</span>: True if the <span>current alignment state</span> is
+<p><span>State</span>: True if the <span>selection's alignment value</span> is
 "justify", otherwise false.
+
+<p><span>Value</span>: The <span>active range</span>'s [[startnode]]'s
+<span>alignment value</span>.
 <!-- @} -->
 
 <h3><dfn>The <code title>justifyLeft</code> command</dfn></h3>
@@ -6242,8 +6270,11 @@
 <p><span>Action</span>: <span>Justify the selection</span> with
 <var>alignment</var> "left".
 
-<p><span>State</span>: True if the <span>current alignment state</span> is
+<p><span>State</span>: True if the <span>selection's alignment value</span> is
 "left", otherwise false.
+
+<p><span>Value</span>: The <span>active range</span>'s [[startnode]]'s
+<span>alignment value</span>.
 <!-- @} -->
 
 <h3><dfn>The <code title>justifyRight</code> command</dfn></h3>
@@ -6251,8 +6282,11 @@
 <p><span>Action</span>: <span>Justify the selection</span> with
 <var>alignment</var> "right".
 
-<p><span>State</span>: True if the <span>current alignment state</span> is
+<p><span>State</span>: True if the <span>selection's alignment value</span> is
 "right", otherwise false.
+
+<p><span>Value</span>: The <span>active range</span>'s [[startnode]]'s
+<span>alignment value</span>.
 <!-- @} -->
 
 <h3><dfn>The <code title>outdent</code> command</dfn></h3>