--- a/editcommands.html Wed Jun 29 11:40:29 2011 -0600
+++ b/editcommands.html Wed Jun 29 12:42:49 2011 -0600
@@ -3502,55 +3502,6 @@
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*,
-and Opera 11.11 returns false in every case except some seemingly random crazy
-ones.
-
-Firefox 6.0a2 returns true for the state of justify* if anything in the range
-has the right alignment, not if everything does. This isn't consistent with
-how state works for the inline commands, nor with WebKit.
-
-Chrome 14 dev counts text-align on inline elements, which is wrong, because the
-property has no effect. It also counts it on non-editable elements, which is
-wrong, because then the state for justify* wouldn't necessarily be true after
-executing it. (Chrome actually does align the non-editable elements, but
-that's just a bug.) Chrome further returns false for justify* if the
-justification is just the default inherited justification, e.g., left for LTR.
-This doesn't seem to make sense either.
-
-It's not actually clear how much sense state makes here. Most commands that
-have a state that's not always false work differently depending on what the
-state is, generally because they toggle something (bold, lists, etc.). The
-justify commands behave the same regardless of state. Still, I'll follow
-Gecko/WebKit in supporting the command.
--->
-<ol>
- <li><a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>, and let <var title="">new
- range</var> be the result.
-
- <li>Let <var title="">node list</var> be a list of all <a href=#editable>editable</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>nodes</a>
- <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in <var title="">new range</var>.
-
- <li>If <var title="">node list</var> is empty, return "none".
-
- <li>Let <var title="">state</var> be "none".
-
- <li>For each <var title="">node</var> in <var title="">node list</var>:
-
- <ol>
- <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>.
-</ol>
-
<h3 id=allowed-children><span class=secno>8.3 </span>Allowed children</h3>
@@ -6428,17 +6379,64 @@
<var title="">alignment</var> "center".
<p><a href=#indeterminate>Indeterminate</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active
-range</a>. Return true if among <a href=#editable>editable</a> nodes <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a>
-in the result, at least one has <a href=#alignment-value>alignment value</a> "center" and at
+range</a>. Return true if among <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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>nodes</a> that are <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and have
+no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, at least one has <a href=#alignment-value>alignment value</a> "center" and at
least one does not. Otherwise return false.
-<!-- This roughly matches Chrome 14 dev, although not exactly. Firefox 6.0a2
-always returns false. -->
-
-<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>.
+<!--
+This roughly matches Chrome 14 dev, although not exactly. Firefox 6.0a2 always
+returns false.
+
+As a general rule, ignoring nodes with children saves us from treating <div
+align=left><div align=center>foo</div></div> as though it's indeterminate.
+Chrome 14 dev seems to only pay attention to text nodes, instead, or something
+like that. At any rate, it fails on images. Firefox 6.0a2 (for state and
+value) gets tripped up by examples like the one given.
+
+If we ever support centering of tables and similar, we'd want to pay attention
+even to some nodes that do have children.
+-->
+
+<p><a href=#state>State</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>.
+Return true if there is at least one <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and has no
+<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, and all such <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a> have <a href=#alignment-value>alignment value</a>
+"center". Otherwise return false.
+<!--
+IE9 throws exceptions in almost every case when querying the state of justify*,
+and Opera 11.11 returns false in every case except some seemingly random crazy
+ones.
+
+Firefox 6.0a2 returns true for the state of justify* if anything in the range
+has the right alignment, not if everything does. This isn't consistent with
+how state works for the inline commands, nor with WebKit.
+
+Chrome 14 dev counts text-align on inline elements, which is wrong, because the
+property has no effect. It also counts it on non-editable elements, which is
+wrong, because then the state for justify* wouldn't necessarily be true after
+executing it. (Chrome actually does align the non-editable elements, but
+that's just a bug.) Chrome further returns false for justify* if the
+justification is just the default inherited justification, e.g., left for LTR.
+This doesn't seem to make sense either.
+
+State is kind of redundant here, because it's true if and only if indeterminate
+is false and the value is equal to the desired value. However, I'll support it
+anyway, since Gecko/WebKit do.
+-->
+
+<p><a href=#value>Value</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>,
+and return the <a href=#alignment-value>alignment value</a> of the first <a href=#visible-node title="visible
+node">visible</a> <a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in
+the result and has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>. If there is no such <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>, return
+"left".
+<!--
+Not bidi-safe, but it's a pretty marginal corner case. Firefox 6.0a2 behaves
+weirdly here: it keys off the start node of the active range, even if that's
+not contained. Thus {<div align=center>foo</div>} has value "left" and
+indeterminate false, which would suggest that the whole selection is aligned
+left, but that's not the case. Chrome 14 dev returns the state cast to a
+string, as usual. Opera 11.11 always returns the empty string.
+-->
<h3 id=the-justifyfull-command><span class=secno>8.22 </span><dfn>The <code title="">justifyFull</code> command</dfn></h3>
@@ -6447,15 +6445,22 @@
<var title="">alignment</var> "justify".
<p><a href=#indeterminate>Indeterminate</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active
-range</a>. Return true if among <a href=#editable>editable</a> nodes <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a>
-in the result, at least one has <a href=#alignment-value>alignment value</a> "justify" and at
+range</a>. Return true if among <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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>nodes</a> that are <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and have
+no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, at least one has <a href=#alignment-value>alignment value</a> "justify" and at
least one does not. Otherwise return false.
-<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>.
+<p><a href=#state>State</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>.
+Return true if there is at least one <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and has no
+<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, and all such <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a> have <a href=#alignment-value>alignment value</a>
+"justify". Otherwise return false.
+
+<p><a href=#value>Value</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>,
+and return the <a href=#alignment-value>alignment value</a> of the first <a href=#visible-node title="visible
+node">visible</a> <a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in
+the result and has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>. If there is no such <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>, return
+"left".
<h3 id=the-justifyleft-command><span class=secno>8.23 </span><dfn>The <code title="">justifyLeft</code> command</dfn></h3>
@@ -6464,15 +6469,22 @@
<var title="">alignment</var> "left".
<p><a href=#indeterminate>Indeterminate</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active
-range</a>. Return true if among <a href=#editable>editable</a> nodes <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a>
-in the result, at least one has <a href=#alignment-value>alignment value</a> "left" and at
+range</a>. Return true if among <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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>nodes</a> that are <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and have
+no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, at least one has <a href=#alignment-value>alignment value</a> "left" and at
least one does not. Otherwise return false.
-<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>.
+<p><a href=#state>State</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>.
+Return true if there is at least one <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and has no
+<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, and all such <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a> have <a href=#alignment-value>alignment value</a> "left".
+Otherwise return false.
+
+<p><a href=#value>Value</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>,
+and return the <a href=#alignment-value>alignment value</a> of the first <a href=#visible-node title="visible
+node">visible</a> <a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in
+the result and has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>. If there is no such <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>, return
+"left".
<h3 id=the-justifyright-command><span class=secno>8.24 </span><dfn>The <code title="">justifyRight</code> command</dfn></h3>
@@ -6481,15 +6493,22 @@
<var title="">alignment</var> "right".
<p><a href=#indeterminate>Indeterminate</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active
-range</a>. Return true if among <a href=#editable>editable</a> nodes <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a>
-in the result, at least one has <a href=#alignment-value>alignment value</a> "right" and at
+range</a>. Return true if among <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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>nodes</a> that are <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and have
+no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, at least one has <a href=#alignment-value>alignment value</a> "right" and at
least one does not. Otherwise return false.
-<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>.
+<p><a href=#state>State</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>.
+Return true if there is at least one <a href=#visible-node title="visible node">visible</a>
+<a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in the result and has no
+<a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>, and all such <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a> have <a href=#alignment-value>alignment value</a> "right".
+Otherwise return false.
+
+<p><a href=#value>Value</a>: <a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>,
+and return the <a href=#alignment-value>alignment value</a> of the first <a href=#visible-node title="visible
+node">visible</a> <a href=#editable>editable</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> that is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in
+the result and has no <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>children</a>. If there is no such <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>, return
+"left".
<h3 id=the-outdent-command><span class=secno>8.25 </span><dfn>The <code title="">outdent</code> command</dfn></h3>
--- a/implementation.js Wed Jun 29 11:40:29 2011 -0600
+++ b/implementation.js Wed Jun 29 12:42:49 2011 -0600
@@ -3874,41 +3874,6 @@
// 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());
-
- // "Let node list be a list of all editable nodes contained in new
- // range."
- var nodeList = collectAllContainedNodes(newRange, isEditable);
-
- // "If node list is empty, return "none"."
- if (nodeList.length == 0) {
- return "none";
- }
-
- // "Let state be "none"."
- var state = "none";
-
- // "For each node in node list:"
- for (var i = 0; i < nodeList.length; i++) {
- var node = nodeList[i];
-
- // "If state is "none", set state to node's alignment value."
- if (state == "none") {
- state = getAlignmentValue(node);
- }
-
- // "If state is different from node's alignment value, return "none"."
- if (state != getAlignmentValue(node)) {
- return "none";
- }
- }
-
- // "Return state."
- return state;
-}
//@}
///// Allowed children /////
@@ -6495,17 +6460,38 @@
// "Justify the selection with alignment "center"."
action: function() { justifySelection("center") },
indeterm: function() {
- // "Block-extend the active range. Return true if among editable nodes
- // contained in the result, at least one has alignment value "center"
- // and at least one does not. Otherwise return false."
- var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), isEditable);
+ // "Block-extend the active range. Return true if among visible
+ // editable nodes that are contained in the result and have no
+ // children, at least one has alignment value "center" and at least one
+ // does not. Otherwise return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
return nodes.some(function(node) { return getAlignmentValue(node) == "center" })
&& nodes.some(function(node) { return getAlignmentValue(node) != "center" });
+ }, state: function() {
+ // "Block-extend the active range. Return true if there is at least one
+ // visible editable node that is contained in the result and has no
+ // children, and all such nodes have alignment value "center".
+ // Otherwise return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ return nodes.length
+ && nodes.every(function(node) { return getAlignmentValue(node) == "center" });
+ }, value: function() {
+ // "Block-extend the active range, and return the alignment value of
+ // the first visible editable node that is contained in the result and
+ // has no children. If there is no such node, return "left"."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ if (nodes.length) {
+ return getAlignmentValue(nodes[0]);
+ } else {
+ return "left";
+ }
},
- // "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) },
};
//@}
@@ -6515,17 +6501,38 @@
// "Justify the selection with alignment "justify"."
action: function() { justifySelection("justify") },
indeterm: function() {
- // "Block-extend the active range. Return true if among editable nodes
- // contained in the result, at least one has alignment value "justify"
- // and at least one does not. Otherwise return false."
- var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), isEditable);
+ // "Block-extend the active range. Return true if among visible
+ // editable nodes that are contained in the result and have no
+ // children, at least one has alignment value "justify" and at least
+ // one does not. Otherwise return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
return nodes.some(function(node) { return getAlignmentValue(node) == "justify" })
&& nodes.some(function(node) { return getAlignmentValue(node) != "justify" });
+ }, state: function() {
+ // "Block-extend the active range. Return true if there is at least one
+ // visible editable node that is contained in the result and has no
+ // children, and all such nodes have alignment value "justify".
+ // Otherwise return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ return nodes.length
+ && nodes.every(function(node) { return getAlignmentValue(node) == "justify" });
+ }, value: function() {
+ // "Block-extend the active range, and return the alignment value of
+ // the first visible editable node that is contained in the result and
+ // has no children. If there is no such node, return "left"."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ if (nodes.length) {
+ return getAlignmentValue(nodes[0]);
+ } else {
+ return "left";
+ }
},
- // "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) },
};
//@}
@@ -6535,17 +6542,38 @@
// "Justify the selection with alignment "left"."
action: function() { justifySelection("left") },
indeterm: function() {
- // "Block-extend the active range. Return true if among editable nodes
- // contained in the result, at least one has alignment value "left"
- // and at least one does not. Otherwise return false."
- var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), isEditable);
+ // "Block-extend the active range. Return true if among visible
+ // editable nodes that are contained in the result and have no
+ // children, at least one has alignment value "left" and at least one
+ // does not. Otherwise return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
return nodes.some(function(node) { return getAlignmentValue(node) == "left" })
&& nodes.some(function(node) { return getAlignmentValue(node) != "left" });
+ }, state: function() {
+ // "Block-extend the active range. Return true if there is at least one
+ // visible editable node that is contained in the result and has no
+ // children, and all such nodes have alignment value "left". Otherwise
+ // return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ return nodes.length
+ && nodes.every(function(node) { return getAlignmentValue(node) == "left" });
+ }, value: function() {
+ // "Block-extend the active range, and return the alignment value of
+ // the first visible editable node that is contained in the result and
+ // has no children. If there is no such node, return "left"."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ if (nodes.length) {
+ return getAlignmentValue(nodes[0]);
+ } else {
+ return "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) },
};
//@}
@@ -6555,17 +6583,38 @@
// "Justify the selection with alignment "right"."
action: function() { justifySelection("right") },
indeterm: function() {
- // "Block-extend the active range. Return true if among editable nodes
- // contained in the result, at least one has alignment value "right"
- // and at least one does not. Otherwise return false."
- var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), isEditable);
+ // "Block-extend the active range. Return true if among visible
+ // editable nodes that are contained in the result and have no
+ // children, at least one has alignment value "right" and at least one
+ // does not. Otherwise return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
return nodes.some(function(node) { return getAlignmentValue(node) == "right" })
&& nodes.some(function(node) { return getAlignmentValue(node) != "right" });
+ }, state: function() {
+ // "Block-extend the active range. Return true if there is at least one
+ // visible editable node that is contained in the result and has no
+ // children, and all such nodes have alignment value "right".
+ // Otherwise return false."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ return nodes.length
+ && nodes.every(function(node) { return getAlignmentValue(node) == "right" });
+ }, value: function() {
+ // "Block-extend the active range, and return the alignment value of
+ // the first visible editable node that is contained in the result and
+ // has no children. If there is no such node, return "left"."
+ var nodes = collectAllContainedNodes(blockExtendRange(getActiveRange()), function(node) {
+ return isEditable(node) && isVisibleNode(node) && !node.hasChildNodes();
+ });
+ if (nodes.length) {
+ return getAlignmentValue(nodes[0]);
+ } else {
+ return "left";
+ }
},
- // "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 Wed Jun 29 11:40:29 2011 -0600
+++ b/source.html Wed Jun 29 12:42:49 2011 -0600
@@ -3492,55 +3492,6 @@
<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*,
-and Opera 11.11 returns false in every case except some seemingly random crazy
-ones.
-
-Firefox 6.0a2 returns true for the state of justify* if anything in the range
-has the right alignment, not if everything does. This isn't consistent with
-how state works for the inline commands, nor with WebKit.
-
-Chrome 14 dev counts text-align on inline elements, which is wrong, because the
-property has no effect. It also counts it on non-editable elements, which is
-wrong, because then the state for justify* wouldn't necessarily be true after
-executing it. (Chrome actually does align the non-editable elements, but
-that's just a bug.) Chrome further returns false for justify* if the
-justification is just the default inherited justification, e.g., left for LTR.
-This doesn't seem to make sense either.
-
-It's not actually clear how much sense state makes here. Most commands that
-have a state that's not always false work differently depending on what the
-state is, generally because they toggle something (bold, lists, etc.). The
-justify commands behave the same regardless of state. Still, I'll follow
-Gecko/WebKit in supporting the command.
--->
-<ol>
- <li><span>Block-extend</span> the <span>active range</span>, and let <var>new
- range</var> be the result.
-
- <li>Let <var>node list</var> be a list of all <span>editable</span> [[nodes]]
- [[contained]] in <var>new range</var>.
-
- <li>If <var>node list</var> is empty, return "none".
-
- <li>Let <var>state</var> be "none".
-
- <li>For each <var>node</var> in <var>node list</var>:
-
- <ol>
- <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>.
-</ol>
<!-- @} -->
<h3>Allowed children</h3>
@@ -6454,17 +6405,64 @@
<var>alignment</var> "center".
<p><span>Indeterminate</span>: <span>Block-extend</span> the <span>active
-range</span>. Return true if among <span>editable</span> nodes [[contained]]
-in the result, at least one has <span>alignment value</span> "center" and at
+range</span>. Return true if among <span title="visible node">visible</span>
+<span>editable</span> [[nodes]] that are [[contained]] in the result and have
+no [[children]], at least one has <span>alignment value</span> "center" and at
least one does not. Otherwise return false.
-<!-- This roughly matches Chrome 14 dev, although not exactly. Firefox 6.0a2
-always returns false. -->
-
-<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>.
+<!--
+This roughly matches Chrome 14 dev, although not exactly. Firefox 6.0a2 always
+returns false.
+
+As a general rule, ignoring nodes with children saves us from treating <div
+align=left><div align=center>foo</div></div> as though it's indeterminate.
+Chrome 14 dev seems to only pay attention to text nodes, instead, or something
+like that. At any rate, it fails on images. Firefox 6.0a2 (for state and
+value) gets tripped up by examples like the one given.
+
+If we ever support centering of tables and similar, we'd want to pay attention
+even to some nodes that do have children.
+-->
+
+<p><span>State</span>: <span>Block-extend</span> the <span>active range</span>.
+Return true if there is at least one <span title="visible node">visible</span>
+<span>editable</span> [[node]] that is [[contained]] in the result and has no
+[[children]], and all such [[nodes]] have <span>alignment value</span>
+"center". Otherwise return false.
+<!--
+IE9 throws exceptions in almost every case when querying the state of justify*,
+and Opera 11.11 returns false in every case except some seemingly random crazy
+ones.
+
+Firefox 6.0a2 returns true for the state of justify* if anything in the range
+has the right alignment, not if everything does. This isn't consistent with
+how state works for the inline commands, nor with WebKit.
+
+Chrome 14 dev counts text-align on inline elements, which is wrong, because the
+property has no effect. It also counts it on non-editable elements, which is
+wrong, because then the state for justify* wouldn't necessarily be true after
+executing it. (Chrome actually does align the non-editable elements, but
+that's just a bug.) Chrome further returns false for justify* if the
+justification is just the default inherited justification, e.g., left for LTR.
+This doesn't seem to make sense either.
+
+State is kind of redundant here, because it's true if and only if indeterminate
+is false and the value is equal to the desired value. However, I'll support it
+anyway, since Gecko/WebKit do.
+-->
+
+<p><span>Value</span>: <span>Block-extend</span> the <span>active range</span>,
+and return the <span>alignment value</span> of the first <span title="visible
+node">visible</span> <span>editable</span> [[node]] that is [[contained]] in
+the result and has no [[children]]. If there is no such [[node]], return
+"left".
+<!--
+Not bidi-safe, but it's a pretty marginal corner case. Firefox 6.0a2 behaves
+weirdly here: it keys off the start node of the active range, even if that's
+not contained. Thus {<div align=center>foo</div>} has value "left" and
+indeterminate false, which would suggest that the whole selection is aligned
+left, but that's not the case. Chrome 14 dev returns the state cast to a
+string, as usual. Opera 11.11 always returns the empty string.
+-->
<!-- @} -->
<h3><dfn>The <code title>justifyFull</code> command</dfn></h3>
@@ -6473,15 +6471,22 @@
<var>alignment</var> "justify".
<p><span>Indeterminate</span>: <span>Block-extend</span> the <span>active
-range</span>. Return true if among <span>editable</span> nodes [[contained]]
-in the result, at least one has <span>alignment value</span> "justify" and at
+range</span>. Return true if among <span title="visible node">visible</span>
+<span>editable</span> [[nodes]] that are [[contained]] in the result and have
+no [[children]], at least one has <span>alignment value</span> "justify" and at
least one does not. Otherwise return false.
-<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>.
+<p><span>State</span>: <span>Block-extend</span> the <span>active range</span>.
+Return true if there is at least one <span title="visible node">visible</span>
+<span>editable</span> [[node]] that is [[contained]] in the result and has no
+[[children]], and all such [[nodes]] have <span>alignment value</span>
+"justify". Otherwise return false.
+
+<p><span>Value</span>: <span>Block-extend</span> the <span>active range</span>,
+and return the <span>alignment value</span> of the first <span title="visible
+node">visible</span> <span>editable</span> [[node]] that is [[contained]] in
+the result and has no [[children]]. If there is no such [[node]], return
+"left".
<!-- @} -->
<h3><dfn>The <code title>justifyLeft</code> command</dfn></h3>
@@ -6490,15 +6495,22 @@
<var>alignment</var> "left".
<p><span>Indeterminate</span>: <span>Block-extend</span> the <span>active
-range</span>. Return true if among <span>editable</span> nodes [[contained]]
-in the result, at least one has <span>alignment value</span> "left" and at
+range</span>. Return true if among <span title="visible node">visible</span>
+<span>editable</span> [[nodes]] that are [[contained]] in the result and have
+no [[children]], at least one has <span>alignment value</span> "left" and at
least one does not. Otherwise return false.
-<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>.
+<p><span>State</span>: <span>Block-extend</span> the <span>active range</span>.
+Return true if there is at least one <span title="visible node">visible</span>
+<span>editable</span> [[node]] that is [[contained]] in the result and has no
+[[children]], and all such [[nodes]] have <span>alignment value</span> "left".
+Otherwise return false.
+
+<p><span>Value</span>: <span>Block-extend</span> the <span>active range</span>,
+and return the <span>alignment value</span> of the first <span title="visible
+node">visible</span> <span>editable</span> [[node]] that is [[contained]] in
+the result and has no [[children]]. If there is no such [[node]], return
+"left".
<!-- @} -->
<h3><dfn>The <code title>justifyRight</code> command</dfn></h3>
@@ -6507,15 +6519,22 @@
<var>alignment</var> "right".
<p><span>Indeterminate</span>: <span>Block-extend</span> the <span>active
-range</span>. Return true if among <span>editable</span> nodes [[contained]]
-in the result, at least one has <span>alignment value</span> "right" and at
+range</span>. Return true if among <span title="visible node">visible</span>
+<span>editable</span> [[nodes]] that are [[contained]] in the result and have
+no [[children]], at least one has <span>alignment value</span> "right" and at
least one does not. Otherwise return false.
-<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>.
+<p><span>State</span>: <span>Block-extend</span> the <span>active range</span>.
+Return true if there is at least one <span title="visible node">visible</span>
+<span>editable</span> [[node]] that is [[contained]] in the result and has no
+[[children]], and all such [[nodes]] have <span>alignment value</span> "right".
+Otherwise return false.
+
+<p><span>Value</span>: <span>Block-extend</span> the <span>active range</span>,
+and return the <span>alignment value</span> of the first <span title="visible
+node">visible</span> <span>editable</span> [[node]] that is [[contained]] in
+the result and has no [[children]]. If there is no such [[node]], return
+"left".
<!-- @} -->
<h3><dfn>The <code title>outdent</code> command</dfn></h3>
--- a/tests.js Wed Jun 29 11:40:29 2011 -0600
+++ b/tests.js Wed Jun 29 12:42:49 2011 -0600
@@ -2412,6 +2412,8 @@
'<div align=left>{<div align=center>foo</div>bar}</div>',
'<div align=center>{<div align=left>foo</div><img src=/img/lion.svg>}</div>',
'<div align=left>{<div align=center>foo</div><img src=/img/lion.svg>}</div>',
+ '<div align=center>{<div align=left>foo</div><!-- bar -->}</div>',
+ '<div align=left>{<div align=center>foo</div><!-- bar -->}</div>',
],
//@}
justifyfull: [