Simplify the enabled definition again
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Thu, 07 Jul 2011 14:50:34 -0600
changeset 371 e9b08040054c
parent 370 4a50bcd41e11
child 372 52911b299925
Simplify the enabled definition again

When I tested again, it looks like browsers actually behaved differently
from how I thought, such that my changed definition didn't make much
sense.
editcommands.html
implementation.js
source.html
tests.js
--- a/editcommands.html	Thu Jul 07 14:09:34 2011 -0600
+++ b/editcommands.html	Thu Jul 07 14:50:34 2011 -0600
@@ -449,40 +449,35 @@
 those listed in <a href=#miscellaneous-commands>Miscellaneous commands</a> are
 always <a href=#enabled>enabled</a>.  The other <a href=#command title=command>commands</a>
 defined here are <a href=#enabled>enabled</a> if the <a href=#active-range>active range</a> is not
-null, and either there is some <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> <a href=#effectively-contained>effectively contained</a> in
-it that is an <a href=#editing-host>editing host</a> or the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendant</a> of an
-<a href=#editing-host>editing host</a>, or 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> or <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</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=#editing-host>editing host</a> or the <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendant</a> of an <a href=#editing-host>editing
-host</a>.
+null, and disabled otherwise.
 
 <!--
-Testing with bold and formatBlock:
-
-IE9 seems to return false if there's no selection or it's entirely outside
-anything editable, but true if any part of the selection descends from anything
-editable, even if it's fully contained in something non-editable (provided it
-descends from something editable).
+Testing with bold:
+
+IE10PP2 seems to return true if the active range's start node is editable,
+false otherwise.
 
 Firefox 6.0a2 seems to always return true if there's anything editable on the
 page, and throw otherwise.
 
-Chrome 14 dev seems to do something like return true if every node effectively
-contained in the selection is editable, false otherwise.
+Chrome 14 dev seems to behave the same as IE10PP2.
 
 Opera 11.11 seems to always return true if there's anything editable on the
 page, and false otherwise.
 
-Firefox and Opera behave more or less uselessly.  Chrome is not ideal because
-we want commands to be enabled if they'll have any effect at all, and basically
-all commands have an effect if there are some non-editable nodes effectively
-contained in the selection as I've specced it currently.  IE is conservative,
-in that it will return true in some cases even if running the command will have
-no effect, but it's pretty simple and it will only return false if there's no
-way the command will have an effect.
-
-Thus I go with IE.  Note that at least createLink and unlink can have an effect
-if the entire selection is non-editable, if something descends from an editable
-<a>, so we want to remain enabled in that case.
+Firefox and Opera behave more or less uselessly.  IE doesn't make much sense,
+in that whether a command is enabled seems meaningless: it will execute it on
+all nodes in the selection, editable or not.  Chrome's definition makes sense
+in that it will only run the command if it's enabled, but it doesn't make much
+sense to only have the command run if the start is editable.
+
+It's not clear to me what the point of this command is.  There's no way we're
+going to always return true if the command will do something and false if it
+won't.  I just stuck with a really conservative definition that happens to be
+convenient: if there's nothing selected, obviously nothing will work, and we
+want to bail out early in that case anyway because all the algorithms will talk
+about the active range.  If there are use-cases for it to be more precise, I
+could make it so.
 -->
 
 
--- a/implementation.js	Thu Jul 07 14:09:34 2011 -0600
+++ b/implementation.js	Thu Jul 07 14:50:34 2011 -0600
@@ -578,27 +578,12 @@
 	// "If command is not supported, raise a NOT_SUPPORTED_ERR exception."
 	setupEditCommandMethod(command, "action", range);
 
-	// "Return true if command is enabled, false otherwise."
-	//
 	// "Among commands defined in this specification, those listed in
 	// Miscellaneous commands are always enabled. The other commands defined
-	// here are enabled if the active range is not null, and either there is
-	// some node effectively contained in it that is an editing host or the
-	// descendant of an editing host, or its start node or end node is an
-	// editing host or the descendant of an editing host."
-	if (["copy", "cut", "paste", "selectall", "stylewithcss", "usecss"].indexOf(command) != -1) {
-		return true;
-	}
-
-	return Boolean(getActiveRange()
-	&& (getAllEffectivelyContainedNodes(getActiveRange(), function(node) {
-		return isEditingHost(node)
-			|| getAncestors(node).some(isEditingHost);
-	}).length
-	|| isEditingHost(getActiveRange().startContainer)
-	|| getAncestors(getActiveRange().startContainer).some(isEditingHost)
-	|| isEditingHost(getActiveRange().endContainer)
-	|| getAncestors(getActiveRange().endContainer).some(isEditingHost)));
+	// here are enabled if the active range is not null, and disabled
+	// otherwise."
+	return ["copy", "cut", "paste", "selectall", "stylewithcss", "usecss"].indexOf(command) != -1
+		|| getActiveRange() !== null;
 }
 
 function myQueryCommandIndeterm(command, range) {
--- a/source.html	Thu Jul 07 14:09:34 2011 -0600
+++ b/source.html	Thu Jul 07 14:50:34 2011 -0600
@@ -387,40 +387,35 @@
 those listed in <a href=#miscellaneous-commands>Miscellaneous commands</a> are
 always <span>enabled</span>.  The other <span title=command>commands</span>
 defined here are <span>enabled</span> if the <span>active range</span> is not
-null, and either there is some [[node]] <span>effectively contained</span> in
-it that is an <span>editing host</span> or the [[descendant]] of an
-<span>editing host</span>, or its [[startnode]] or [[endnode]] is an
-<span>editing host</span> or the [[descendant]] of an <span>editing
-host</span>.
+null, and disabled otherwise.
 
 <!--
-Testing with bold and formatBlock:
-
-IE9 seems to return false if there's no selection or it's entirely outside
-anything editable, but true if any part of the selection descends from anything
-editable, even if it's fully contained in something non-editable (provided it
-descends from something editable).
+Testing with bold:
+
+IE10PP2 seems to return true if the active range's start node is editable,
+false otherwise.
 
 Firefox 6.0a2 seems to always return true if there's anything editable on the
 page, and throw otherwise.
 
-Chrome 14 dev seems to do something like return true if every node effectively
-contained in the selection is editable, false otherwise.
+Chrome 14 dev seems to behave the same as IE10PP2.
 
 Opera 11.11 seems to always return true if there's anything editable on the
 page, and false otherwise.
 
-Firefox and Opera behave more or less uselessly.  Chrome is not ideal because
-we want commands to be enabled if they'll have any effect at all, and basically
-all commands have an effect if there are some non-editable nodes effectively
-contained in the selection as I've specced it currently.  IE is conservative,
-in that it will return true in some cases even if running the command will have
-no effect, but it's pretty simple and it will only return false if there's no
-way the command will have an effect.
-
-Thus I go with IE.  Note that at least createLink and unlink can have an effect
-if the entire selection is non-editable, if something descends from an editable
-<a>, so we want to remain enabled in that case.
+Firefox and Opera behave more or less uselessly.  IE doesn't make much sense,
+in that whether a command is enabled seems meaningless: it will execute it on
+all nodes in the selection, editable or not.  Chrome's definition makes sense
+in that it will only run the command if it's enabled, but it doesn't make much
+sense to only have the command run if the start is editable.
+
+It's not clear to me what the point of this command is.  There's no way we're
+going to always return true if the command will do something and false if it
+won't.  I just stuck with a really conservative definition that happens to be
+convenient: if there's nothing selected, obviously nothing will work, and we
+want to bail out early in that case anyway because all the algorithms will talk
+about the active range.  If there are use-cases for it to be more precise, I
+could make it so.
 -->
 <!-- @} -->
 
--- a/tests.js	Thu Jul 07 14:09:34 2011 -0600
+++ b/tests.js	Thu Jul 07 14:50:34 2011 -0600
@@ -108,9 +108,13 @@
 
 		'foo<span contenteditable=false>[bar]</span>baz',
 		'fo[o<span contenteditable=false>bar</span>b]az',
+		'foo<span contenteditable=false>ba[r</span>b]az',
+		'fo[o<span contenteditable=false>b]ar</span>baz',
 		'fo[<b>o</b><span contenteditable=false>bar</span><b>b</b>]az',
 		'<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>',
 		'<span contenteditable=false>fo[o<span contenteditable=true>bar</span>b]az</span>',
+		'<span contenteditable=false>foo<span contenteditable=true>ba[r</span>b]az</span>',
+		'<span contenteditable=false>fo[o<span contenteditable=true>b]ar</span>baz</span>',
 		'<span contenteditable=false>fo[<b>o<span contenteditable=true>bar</span>b</b>]az</span>',
 
 		'<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>',