--- a/editcommands.html Wed Jun 29 12:42:49 2011 -0600
+++ b/editcommands.html Wed Jun 29 13:14:53 2011 -0600
@@ -5317,6 +5317,8 @@
the "in the same editing host" thing handles it?
</div>
+ <p class=XXX>We probably don't want to break out of tables and such here.
+
<li>Let <var title="">node list</var> be a list of <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>, initially empty.
<li>For each <var title="">node</var> in <var title="">original node list</var>, <a href=#fix-prohibited-paragraph-descendants>fix
@@ -5425,7 +5427,102 @@
</ol>
</ol>
-<p class=XXX>Spec value/indeterm.
+<p><a href=#indeterminate>Indeterminate</a>:
+<!--
+Firefox 6.0a2 throws, Chrome 14 dev always returns false, Opera 11.11 doesn't
+support indeterm to start with, IE9 was uncooperative in testing so I'm not
+sure what it does. I'm speccing it just because it makes sense.
+-->
+<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 all <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 <var title="">new
+ range</var> 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>.
+
+ <li>If <var title="">node list</var> is empty, return false.
+
+ <li>Let <var title="">type</var> be null.
+
+ <li>For each <var title="">node</var> in <var title="">node list</var>:
+
+ <ol>
+ <li>While <var title="">node</var>'s <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> is <a href=#editable>editable</a> and
+ <a href=#in-the-same-editing-host>in the same editing host</a> as <var title="">node</var>, and
+ <var title="">node</var> is not an <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a>
+ "address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", or "pre", 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>.
+
+ <p class=XXX>This doesn't really make sense if there's an intervening table
+ or something.
+
+ <li>Let <var title="">current type</var> be the empty string.
+
+ <li>If <var title="">node</var> is an <a href=#editable>editable</a> <a href=#html-element>HTML
+ element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> "address", "div", "h1", "h2", "h3", "h4",
+ "h5", "h6", "p", or "pre", set <var title="">current type</var> to <var title="">node</var>'s
+ <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a>.
+
+ <li>If <var title="">type</var> is null, set <var title="">type</var> to <var title="">current
+ type</var>.
+
+ <li>Otherwise, if <var title="">type</var> does not equal <var title="">current type</var>,
+ return true.
+ </ol>
+
+ <li>Return false.
+</ol>
+
+<p><a href=#value>Value</a>:
+<!--
+IE9 returns human-readable strings like "Normal" (p/div/etc.), "Formatted"
+(pre), "Heading 1" (h1), etc. Firefox 6.0a2 and Chrome 14 dev both return the
+appropriate tag name in lowercase, or the empty string if there is no
+appropriate tag. Opera 11.11 behaves the same, but with uppercase.
+
+IE9 looks like it recognizes address, h*, pre, dd, dt, ol, ul, and dir, with
+everything else registering as "Normal". Firefox 6.0a2 recognizes only the
+arguments it accepts for formatBlock, namely address, h*, p, and pre. Chrome
+14 dev recognizes address, div, h*, dd, dl, dt, p, pre plus lots of random
+other stuff like blockquote and section. I'll go with everything that
+execCommand("formatblock") accepts as an argument, which at the time of this
+writing means what Firefox supports plus div.
+-->
+<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</var> be 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
+ <var title="">new range</var> 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 the empty string.
+
+ <li>While <var title="">node</var>'s <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> is <a href=#editable>editable</a> and <a href=#in-the-same-editing-host>in
+ the same editing host</a> as <var title="">node</var>, and <var title="">node</var> is not
+ an <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> "address", "div", "h1", "h2",
+ "h3", "h4", "h5", "h6", "p", or "pre", 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>.
+ <!--
+ Opera 11.11 doesn't require it be editable, so it will return "DIV" instead of
+ "" for <div contenteditable>foo</div>.
+
+ Chrome 14 dev will report "div" for <div><ol><li>foo</ol></div> or such.
+ Opera 11.11 reports "". IE and Firefox didn't cooperate with testing. Opera
+ makes somewhat more sense, but formatBlock is actually broken in that case
+ right now anyway for any wrapper other than div, so I'll punt on a solution.
+ -->
+ <p class=XXX>This doesn't really make sense if there's an intervening table
+ or something.
+
+ <li>If <var title="">node</var> is an <a href=#editable>editable</a> <a href=#html-element>HTML element</a>
+ with <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> "address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p",
+ or "pre", return its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a>, <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#converted-to-lowercase>converted
+ to lowercase</a>.
+ <!-- Actually, we don't really need to specify "editable", since it has to be
+ editable. -->
+
+ <li>Return the empty string.
+</ol>
<h3 id=the-forwarddelete-command><span class=secno>8.11 </span><dfn>The <code title="">forwardDelete</code> command</dfn></h3>
--- a/implementation.js Wed Jun 29 12:42:49 2011 -0600
+++ b/implementation.js Wed Jun 29 13:14:53 2011 -0600
@@ -5595,6 +5595,100 @@
function() { return document.createElement(value) });
}
}
+ }, indeterm: function() {
+ // "Block-extend the active range, and let new range be the result."
+ var newRange = blockExtendRange(getActiveRange());
+
+ // "Let node list be all visible editable nodes that are contained in
+ // new range and have no children."
+ var nodeList = collectAllContainedNodes(newRange, function(node) {
+ return isVisibleNode(node)
+ && isEditable(node)
+ && !node.hasChildNodes();
+ });
+
+ // "If node list is empty, return false."
+ if (!nodeList.length) {
+ return false;
+ }
+
+ // "Let type be null."
+ var type = null;
+
+ // "For each node in node list:"
+ for (var i = 0; i < nodeList.length; i++) {
+ var node = nodeList[i];
+
+ // "While node's parent is editable and in the same editing host as
+ // node, and node is not an HTML element with local name "address",
+ // "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", or "pre", set
+ // node to its parent."
+ while (isEditable(node.parentNode)
+ && inSameEditingHost(node, node.parentNode)
+ && !isHtmlElement(node, ["address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre"])) {
+ node = node.parentNode;
+ }
+
+ // "Let current type be the empty string."
+ var currentType = "";
+
+ // "If node is an editable HTML element with local name "address",
+ // "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", or "pre", set
+ // current type to node's local name."
+ if (isEditable(node)
+ && isHtmlElement(node, ["address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre"])) {
+ currentType = node.tagName;
+ }
+
+ // "If type is null, set type to current type."
+ if (type === null) {
+ type = currentType;
+
+ // "Otherwise, if type does not equal current type, return true."
+ } else if (type != currentType) {
+ return true;
+ }
+ }
+
+ // "Return false."
+ return false;
+ }, value: function() {
+ // "Block-extend the active range, and let new range be the result."
+ var newRange = blockExtendRange(getActiveRange());
+
+ // "Let node be the first visible editable node that is contained in
+ // new range and has no children. If there is no such node, return the
+ // empty string."
+ var nodes = collectAllContainedNodes(newRange, function(node) {
+ return isVisibleNode(node)
+ && isEditable(node)
+ && !node.hasChildNodes();
+ });
+ if (!nodes.length) {
+ return "";
+ }
+ var node = nodes[0];
+
+ // "While node's parent is editable and in the same editing host as
+ // node, and node is not an HTML element with local name "address",
+ // "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", or "pre", set node
+ // to its parent."
+ while (isEditable(node.parentNode)
+ && inSameEditingHost(node, node.parentNode)
+ && !isHtmlElement(node, ["address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre"])) {
+ node = node.parentNode;
+ }
+
+ // "If node is an editable HTML element with local name "address",
+ // "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", or "pre", return its
+ // local name, converted to lowercase."
+ if (isEditable(node)
+ && isHtmlElement(node, ["address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre"])) {
+ return node.tagName.toLowerCase();
+ }
+
+ // "Return the empty string."
+ return "";
}
};
//@}
--- a/source.html Wed Jun 29 12:42:49 2011 -0600
+++ b/source.html Wed Jun 29 13:14:53 2011 -0600
@@ -5326,6 +5326,8 @@
the "in the same editing host" thing handles it?
</div>
+ <p class=XXX>We probably don't want to break out of tables and such here.
+
<li>Let <var>node list</var> be a list of [[nodes]], initially empty.
<li>For each <var>node</var> in <var>original node list</var>, <span>fix
@@ -5434,7 +5436,102 @@
</ol>
</ol>
-<p class=XXX>Spec value/indeterm.
+<p><span>Indeterminate</span>:
+<!--
+Firefox 6.0a2 throws, Chrome 14 dev always returns false, Opera 11.11 doesn't
+support indeterm to start with, IE9 was uncooperative in testing so I'm not
+sure what it does. I'm speccing it just because it makes sense.
+-->
+<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 all <span title="visible node">visible</span>
+ <span>editable</span> [[nodes]] that are [[contained]] in <var>new
+ range</var> and have no [[children]].
+
+ <li>If <var>node list</var> is empty, return false.
+
+ <li>Let <var>type</var> be null.
+
+ <li>For each <var>node</var> in <var>node list</var>:
+
+ <ol>
+ <li>While <var>node</var>'s [[parent]] is <span>editable</span> and
+ <span>in the same editing host</span> as <var>node</var>, and
+ <var>node</var> is not an <span>HTML element</span> with [[localname]]
+ "address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p", or "pre", set
+ <var>node</var> to its [[parent]].
+
+ <p class=XXX>This doesn't really make sense if there's an intervening table
+ or something.
+
+ <li>Let <var>current type</var> be the empty string.
+
+ <li>If <var>node</var> is an <span>editable</span> <span>HTML
+ element</span> with [[localname]] "address", "div", "h1", "h2", "h3", "h4",
+ "h5", "h6", "p", or "pre", set <var>current type</var> to <var>node</var>'s
+ [[localname]].
+
+ <li>If <var>type</var> is null, set <var>type</var> to <var>current
+ type</var>.
+
+ <li>Otherwise, if <var>type</var> does not equal <var>current type</var>,
+ return true.
+ </ol>
+
+ <li>Return false.
+</ol>
+
+<p><span>Value</span>:
+<!--
+IE9 returns human-readable strings like "Normal" (p/div/etc.), "Formatted"
+(pre), "Heading 1" (h1), etc. Firefox 6.0a2 and Chrome 14 dev both return the
+appropriate tag name in lowercase, or the empty string if there is no
+appropriate tag. Opera 11.11 behaves the same, but with uppercase.
+
+IE9 looks like it recognizes address, h*, pre, dd, dt, ol, ul, and dir, with
+everything else registering as "Normal". Firefox 6.0a2 recognizes only the
+arguments it accepts for formatBlock, namely address, h*, p, and pre. Chrome
+14 dev recognizes address, div, h*, dd, dl, dt, p, pre plus lots of random
+other stuff like blockquote and section. I'll go with everything that
+execCommand("formatblock") accepts as an argument, which at the time of this
+writing means what Firefox supports plus div.
+-->
+<ol>
+ <li><span>Block-extend</span> the <span>active range</span>, and let <var>new
+ range</var> be the result.
+
+ <li>Let <var>node</var> be the first <span title="visible
+ node">visible</span> <span>editable</span> [[node]] that is [[contained]] in
+ <var>new range</var> and has no [[children]]. If there is no such [[node]],
+ return the empty string.
+
+ <li>While <var>node</var>'s [[parent]] is <span>editable</span> and <span>in
+ the same editing host</span> as <var>node</var>, and <var>node</var> is not
+ an <span>HTML element</span> with [[localname]] "address", "div", "h1", "h2",
+ "h3", "h4", "h5", "h6", "p", or "pre", set <var>node</var> to its [[parent]].
+ <!--
+ Opera 11.11 doesn't require it be editable, so it will return "DIV" instead of
+ "" for <div contenteditable>foo</div>.
+
+ Chrome 14 dev will report "div" for <div><ol><li>foo</ol></div> or such.
+ Opera 11.11 reports "". IE and Firefox didn't cooperate with testing. Opera
+ makes somewhat more sense, but formatBlock is actually broken in that case
+ right now anyway for any wrapper other than div, so I'll punt on a solution.
+ -->
+ <p class=XXX>This doesn't really make sense if there's an intervening table
+ or something.
+
+ <li>If <var>node</var> is an <span>editable</span> <span>HTML element</span>
+ with [[localname]] "address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "p",
+ or "pre", return its [[localname]], <span data-anolis-spec=domcore>converted
+ to lowercase</span>.
+ <!-- Actually, we don't really need to specify "editable", since it has to be
+ editable. -->
+
+ <li>Return the empty string.
+</ol>
<!-- @} -->
<h3><dfn>The <code title>forwardDelete</code> command</dfn></h3>
--- a/tests.js Wed Jun 29 12:42:49 2011 -0600
+++ b/tests.js Wed Jun 29 13:14:53 2011 -0600
@@ -1015,9 +1015,17 @@
['<h1>', '<pre>[foo<br>bar]</pre>'],
['<h1>', '<p>[foo</p>bar]'],
+ ['<h1>', '[foo<p>bar]</p>'],
['<p>', '<div>[foo<p>bar]</p></div>'],
['<p>', '<xmp>[foo]</xmp>'],
['<div>', '<xmp>[foo]</xmp>'],
+
+ // For queryCommandIndeterm() and queryCommandValue()
+ '<div><ol><li>[foo]</ol></div>',
+ '<div><table><tr><td>[foo]</table></div>',
+ '<p>[foo<h1>bar]</h1>',
+ '<h1>[foo</h1><h2>bar]</h2>',
+ '<div>[foo</div>bar]',
],
//@}
forwarddelete: [