--- a/autoimplementation.html Mon May 16 13:23:48 2011 -0600
+++ b/autoimplementation.html Mon May 16 14:40:09 2011 -0600
@@ -958,6 +958,17 @@
'<ol><li>foo<ol><li>[bar]</ol>baz</ol>',
'<ol><li>foo<ol><li>bar</ol>[baz]</ol>',
'<ol><li>[foo<ol><li>bar]</ol>baz</ol>',
+
+ // Random stuff
+ 'foo<ol><li>[bar<li>baz]</ol>quz',
+ 'foo<ol start=5><li>[bar]</ol>baz',
+ 'foo<ol id=abc><li>[bar]</ol>baz',
+ 'foo<ol style=color:red><li>[bar]</ol>baz',
+ 'foo<ol><li value=5>[bar]</ol>baz',
+ 'foo<ol><li id=abc>[bar]</ol>baz',
+ 'foo<ol><li style=color:red>[bar]</ol>baz',
+ '<ol><li>foo</li><ol><li value=5>[bar]</ol></ol>',
+ '<ul><li>foo</li><ol><li value=5>[bar]</ol></ul>',
],
removeformat: [
'foo[]bar',
--- a/editcommands.html Mon May 16 13:23:48 2011 -0600
+++ b/editcommands.html Mon May 16 14:40:09 2011 -0600
@@ -2992,12 +2992,33 @@
<li>For each <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> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in <var title="">node list</var>:
<ol>
- <li>If some <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-ancestor title=concept-tree-ancestor>ancestor</a> of <var title="">node</var> is in <var title="">node list</var>,
+ <li>If the last member of <var title="">node list</var> is an <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-ancestor title=concept-tree-ancestor>ancestor</a> of
+ <var title="">node</var>, or if <var title="">node</var> is not <a href=#editable>editable</a>,
continue with the next <var title="">node</var>.
- <li>If <var title="">node</var> 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>, or is an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, or
- is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> whose <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 an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, append it to
- <var title="">node list</var>.
+ <!--
+ This step is kind of weird. For regular outdenting, we start at the inside
+ and outdent going out, so that we remove the innermost indentation, on the
+ theory that that will produce the cleanest markup (remove the most nodes).
+ For lists, we remove the outermost indentation, because it makes a
+ difference whether we remove inner or outer indentation, and logically we
+ want to remove outer. E.g.,
+
+ <ol><li>foo</li><ul><li>bar</li></ul></ol>
+
+ should become
+
+ foo<ul><li>bar</li></ul>
+
+ not
+
+ foo<ol><li>bar</li></ol>.
+
+ But this is a bit weird and I'm wondering if it's really correct.
+ -->
+ <li>If <var title="">node</var> has no <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-tree-descendant title=concept-tree-descendant>descendants</a>, or is
+ an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, or is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> whose <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 an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or
+ <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, append it to <var title="">node list</var>.
</ol>
<li>While <var title="">node list</var> is not empty:
@@ -3045,8 +3066,6 @@
<ol>
<li>If <var title="">node</var> is not <a href=#editable>editable</a>, abort these steps.
- <p class=XXX>Handle this better for nested editable/non-editable.
-
<li>If <var title="">node</var> is an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code> with no attributes except
possibly <code class=external data-anolis-spec=html title=attr-ol-reversed><a href=http://www.whatwg.org/html/#attr-ol-reversed>reversed</a></code>,
<code class=external data-anolis-spec=html title=attr-ol-start><a href=http://www.whatwg.org/html/#attr-ol-start>start</a></code>, and/or <code class=external data-anolis-spec=html title=attr-ol-type><a href=http://www.whatwg.org/html/#attr-ol-type>type</a></code>; or is an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or
@@ -3057,7 +3076,7 @@
<div class=XXX>
<p>We don't handle a case like
- </p><xmp><ol><ol style="color: red"><li>foo<li>bar</ol><li>baz</xmp>
+ </p><xmp><ol><ol style="color: red"><li>foo<li>bar</ol><li>baz</ol></xmp>
<p>If the inner <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> is selected to be outdented, "foo" and "bar" will stop
being red. It seems nontrivial to handle this case in general, since we
@@ -3066,20 +3085,11 @@
</div>
<ol>
- <li>While <var title="">node</var> has <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>:
-
- <ol>
- <li>Let <var title="">child</var> be the first <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>child</a> of <var title="">node</var>.
-
- <li>If <var title="">child</var> is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> and the <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> of
- <var title="">node</var> is not an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, <a href=#set-the-tag-name>set the tag name</a>
- of <var title="">child</var> to "div", and set <var title="">child</var> to the result.
-
- <li>Insert <var title="">child</var> into the <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> of <var title="">node</var>
- immediately before <var title="">node</var>, <a href=#preserving-ranges>preserving ranges</a>.
- </ol>
-
- <li>Remove <var title="">node</var> from 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>Let <var title="">children</var> be the <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> of <var title="">node</var>.
+
+ <li>Remove <var title="">node</var>, <a href=#preserving-its-descendants>preserving its descendants</a>.
+
+ <li><a href=#fix-orphaned-list-items>Fix orphaned list items</a> in <var title="">children</var>.
<li>Abort these steps.
</ol>
@@ -3092,13 +3102,11 @@
<li>Unset the <code class=external data-anolis-spec=html title=attr-ol-reversed><a href=http://www.whatwg.org/html/#attr-ol-reversed>reversed</a></code>, <code class=external data-anolis-spec=html title=attr-ol-start><a href=http://www.whatwg.org/html/#attr-ol-start>start</a></code>, and <code class=external data-anolis-spec=html title=attr-ol-type><a href=http://www.whatwg.org/html/#attr-ol-type>type</a></code> attributes of <var title="">node</var>, if any are
set.
- <li><a href=#set-the-tag-name>Set the tag name</a> of <var title="">node</var> to "div", and set
- <var title="">node</var> to the result.
-
- <li>For each <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> <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>child</a> <var title="">child</var> of <var title="">node</var>, unset
- the <code class=external data-anolis-spec=html title=attr-li-value><a href=http://www.whatwg.org/html/#attr-li-value>value</a></code> attribute
- of <var title="">child</var> if set, then <a href=#set-the-tag-name>set the tag name</a> of
- <var title="">child</var> to "div".
+ <li>Let <var title="">children</var> be the <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> of <var title="">node</var>.
+
+ <li><a href=#set-the-tag-name>Set the tag name</a> of <var title="">node</var> to "div".
+
+ <li><a href=#fix-orphaned-list-items>Fix orphaned list items</a> in <var title="">children</var>.
<li>Abort these steps.
</ol>
@@ -3108,31 +3116,9 @@
created by IE, this might change the direction of some children, but then
their direction was probably changed incorrectly in the first place, so no
harm. -->
- <li>If <var title="">node</var> is an <a href=#indentation-element>indentation element</a>:
-
- <ol>
- <li>If <var title="">node</var>'s <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> and first <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>child</a> are both
- <a href=#inline-node title="inline node">inline nodes</a>, and its <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code>
- is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, then call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
- <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, and insert the result into
- <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> immediately before <var title="">node</var>.
-
- <li>If <var title="">node</var>'s last <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>child</a> and <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> are both <a href=#inline-node title="inline node">inline nodes</a>, and its last <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>child</a> is not a
- <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, then call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
- <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, and insert the result into
- <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> immediately after <var title="">node</var>.
-
- <!-- Just to be pedantic . . . it could happen! -->
- <li>If <var title="">node</var> 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 its <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> and
- <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code> are both <a href=#inline-node title="inline node">inline nodes</a>, and
- its <code class=external data-anolis-spec=domcore title=dom-Node-previousSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-previoussibling>previousSibling</a></code> is not a <code class=external data-anolis-spec=html title="the br element"><a href=http://www.whatwg.org/html/#the-br-element>br</a></code>, then call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
- <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, and insert the result into
- <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> immediately before <var title="">node</var>.
-
- <li>Remove <var title="">node</var>, <a href=#preserving-its-descendants>preserving its descendants</a>.
-
- <li>Abort these steps.
- </ol>
+ <li>If <var title="">node</var> is an <a href=#indentation-element>indentation element</a>, remove
+ <var title="">node</var>, <a href=#preserving-its-descendants>preserving its descendants</a>. Then abort these
+ steps.
<!-- No browser handles the case of Firefox 4.0 in CSS mode, where it adds a
margin attribute to an existing element, including Firefox itself. So let's
@@ -3143,9 +3129,6 @@
Firefox in CSS mode, for instance (color, font-family, etc.). -->
<ol>
- <li><a href=#set-the-tag-name>Set the tag name</a> of <var title="">node</var> to "div", and set
- <var title="">node</var> to the result.
-
<li>Unset the <code class=external data-anolis-spec=html title=classes><a href=http://www.whatwg.org/html/#classes>class</a></code> and
<code class=external data-anolis-spec=html title="the dir attribute"><a href=http://www.whatwg.org/html/#the-dir-attribute>dir</a></code>
attributes of <var title="">node</var>, if any.
@@ -3153,6 +3136,8 @@
<li>Unset the margin, padding, and border CSS properties of
<var title="">node</var>.
+ <li><a href=#set-the-tag-name>Set the tag name</a> of <var title="">node</var> to "div".
+
<li>Abort these steps.
</ol>
@@ -3256,16 +3241,28 @@
<li><a href=#split-the-parent>Split the parent</a> of <var title="">node list</var>, with <var title="">new
parent</var> null.
- <li>For each <var title="">node</var> in <var title="">node list</var>:
+ <li><a href=#fix-orphaned-list-items>Fix orphaned list items</a> in <var title="">node list</var>.
+</ol>
+
+<p>To <dfn id=fix-orphaned-list-items>fix orphaned list items</dfn> in 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> <var title="">node
+list</var>:
+
+<ol>
+ <li>For each <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> <var title="">item</var> in <var title="">node list</var>:
<ol>
- <li>If <var title="">node</var> is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> with no attributes and 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>
- is not an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, remove <var title="">node</var> from 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>,
- <a href=#preserving-its-descendants>preserving its descendants</a>.
-
- <li>Otherwise, if <var title="">node</var> is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> and 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> is not an
- <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, <a href=#set-the-tag-name>set the tag name</a> of <var title="">node</var> to
- "div".
+ <li>If <var title="">item</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 not an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code>, unset
+ <var title="">item</var>'s <code class=external data-anolis-spec=html title=attr-li-value><a href=http://www.whatwg.org/html/#attr-li-value>value</a></code> attribute, if set.
+ <!-- IE9, Firefox 4.0, and Opera 11.10 keep the value attribute even if
+ the parent is now a ul. Chrome 12 dev strips it even if the parent is
+ now an ol. The spec makes more sense. -->
+
+ <li>If <var title="">item</var> has no attributes and 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> is not an
+ <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, remove <var title="">item</var>, <a href=#preserving-its-descendants>preserving its
+ descendants</a>.
+
+ <li>Otherwise, if <var title="">item</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 not an <code class=external data-anolis-spec=html title="the ol element"><a href=http://www.whatwg.org/html/#the-ol-element>ol</a></code> or
+ <code class=external data-anolis-spec=html title="the ul element"><a href=http://www.whatwg.org/html/#the-ul-element>ul</a></code>, <a href=#set-the-tag-name>set the tag name</a> of <var title="">item</var> to "div".
</ol>
</ol>
--- a/implementation.js Mon May 16 13:23:48 2011 -0600
+++ b/implementation.js Mon May 16 14:40:09 2011 -0600
@@ -584,6 +584,16 @@
&& (isEditingHost(node.parentNode) || isEditable(node.parentNode));
}
+function hasEditableDescendants(node) {
+ for (var i = 0; i < node.childNodes.length; i++) {
+ if (isEditable(node.childNodes[i])
+ || hasEditableDescendants(node.childNodes[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* "A Node is effectively contained in a Range if either it is contained in the
* Range; or it is the Range's start node, it is a Text node, and its length is
@@ -2851,18 +2861,16 @@
continue;
}
- // "If some ancestor of node is in node list, continue with the
- // next node."
- //
- // We only need to check the last node on the list, if you think
- // about it.
- if (isAncestor(nodeList[nodeList.length - 1], node)) {
+ // "If the last member of node list is an ancestor of node, or if
+ // node is not editable, continue with the next node."
+ if (isAncestor(nodeList[nodeList.length - 1], node)
+ || !isEditable(node)) {
continue;
}
- // "If node has no children, or is an ol or ul, or is an li whose
- // parent is an ol or ul, append it to node list."
- if (!node.hasChildNodes()
+ // "If node has no editable descendants, or is an ol or ul, or is
+ // an li whose parent is an ol or ul, append it to node list."
+ if (!hasEditableDescendants(node)
|| isHtmlElement(node, "OL")
|| isHtmlElement(node, "UL")
|| (isHtmlElement(node, "LI")
@@ -3240,27 +3248,14 @@
|| isHtmlElement(node.parentNode, "UL")
|| [].every.call(node.attributes, function (attr) { return ["reversed", "start", "type"].indexOf(attr.name) != -1 })
)) {
- // "While node has children:"
- while (node.hasChildNodes()) {
- // "Let child be the first child of node."
- var child = node.firstChild;
-
- // "If child is an li and the parent of node is not an ol or ul,
- // set the tag name of child to "div", and set child to the
- // result."
- if (isHtmlElement(child, "LI")
- && !isHtmlElement(node.parentNode, "OL")
- && !isHtmlElement(node.parentNode, "UL")) {
- child = setTagName(child, "div");
- }
-
- // "Insert child into the parent of node immediately before node,
- // preserving ranges."
- movePreservingRanges(child, node.parentNode, getNodeIndex(node));
- }
-
- // "Remove node from its parent."
- node.parentNode.removeChild(node);
+ // "Let children be the children of node."
+ var children = [].slice.call(node.childNodes);
+
+ // "Remove node, preserving its descendants."
+ removePreservingDescendants(node);
+
+ // "Fix orphaned list items in children."
+ fixOrphanedListItems(children);
// "Abort these steps."
return;
@@ -3275,69 +3270,28 @@
node.removeAttribute("start");
node.removeAttribute("type");
- // "Set the tag name of node to "div", and set node to the result."
- node = setTagName(node, "div");
-
- // "For each li child child of node, unset the value attribute of child
- // if set, then set the tag name of child to "div"."
- for (var i = 0; i < node.childNodes.length; i++) {
- var child = node.childNodes[i];
-
- if (isHtmlElement(child, "LI")) {
- child.removeAttribute("value");
- setTagName(child, "div");
- }
- }
+ // "Let children be the children of node."
+ var children = [].slice.call(node.childNodes);
+
+ // "Set the tag name of node to "div"."
+ setTagName(node, "div");
+
+ // "Fix orphaned list items in children."
+ fixOrphanedListItems(children);
// "Abort these steps."
return;
}
- // "If node is an indentation element:"
+ // "If node is an indentation element, remove node, preserving its
+ // descendants. Then abort these steps."
if (isIndentationElement(node)) {
- // "If node's previousSibling and first child are both inline nodes,
- // and its previousSibling is not a br, then call createElement("br")
- // on the ownerDocument of node, and insert the result into node's
- // parent immediately before node."
- if (isInlineNode(node.previousSibling)
- && isInlineNode(node.firstChild)
- && !isHtmlElement(node.previousSibling, "BR")) {
- node.parentNode.insertBefore(node.ownerDocument.createElement("br"), node);
- }
-
- // "If node's last child and nextSibling are both inline nodes, and its
- // last child is not a br, then call createElement("br") on the
- // ownerDocument of node, and insert the result into node's parent
- // immediately after node."
- if (isInlineNode(node.lastChild)
- && isInlineNode(node.nextSibling)
- && !isHtmlElement(node.lastChild, "BR")) {
- node.parentNode.insertBefore(node.ownerDocument.createElement("br"), node.nextSibling);
- }
-
- // "If node has no children, and its previousSibling and nextSibling
- // are both inline nodes, and its previousSibling is not a br, then
- // call createElement("br") on the ownerDocument of node, and insert
- // the result into node's parent immediately before node."
- if (!node.hasChildNodes()
- && isInlineNode(node.previousSibling)
- && isInlineNode(node.nextSibling)
- && !isHtmlElement(node.previousSibling, "BR")) {
- node.parentNode.insertBefore(node.ownerDocument.createElement("br"), node);
- }
-
- // "Remove node, preserving its descendants."
removePreservingDescendants(node);
-
- // "Abort these steps."
return;
}
// "If node is a potential indentation element:"
if (isPotentialIndentationElement(node)) {
- // "Set the tag name of node to "div", and set node to the result."
- node = setTagName(node, "div");
-
// "Unset the class and dir attributes of node, if any."
node.removeAttribute("class");
node.removeAttribute("dir");
@@ -3350,6 +3304,9 @@
node.removeAttribute("style");
}
+ // "Set the tag name of node to "div"."
+ setTagName(node, "div");
+
// "Abort these steps."
return;
}
@@ -3444,24 +3401,36 @@
// "Split the parent of node list, with new parent null."
splitParent(nodeList, null);
- // "For each node in node list:"
+ // "Fix orphaned list items in node list."
+ fixOrphanedListItems(nodeList);
+}
+
+function fixOrphanedListItems(nodeList) {
+ // "For each li item in node list:"
for (var i = 0; i < nodeList.length; i++) {
- var node = nodeList[i];
-
- // "If node is an li with no attributes and its parent is not an ol or
- // ul, remove node from its parent, preserving its descendants."
- if (isHtmlElement(node, "LI")
- && !node.attributes.length
- && !isHtmlElement(node.parentNode, "OL")
- && !isHtmlElement(node.parentNode, "UL")) {
- removePreservingDescendants(node);
-
- // "Otherwise, if node is an li and its parent is not an ol or ul, set
- // the tag name of node to "div"."
- } else if (isHtmlElement(node, "LI")
- && !isHtmlElement(node.parentNode, "OL")
- && !isHtmlElement(node.parentNode, "UL")) {
- setTagName(node, "div");
+ var item = nodeList[i];
+ if (!isHtmlElement(item, "LI")) {
+ continue;
+ }
+
+ // "If item's parent is not an ol, unset item's value attribute, if
+ // set."
+ if (!isHtmlElement(item.parentNode, "OL")) {
+ item.removeAttribute("value");
+ }
+
+ // "If item has no attributes and its parent is not an ol or ul, remove
+ // item, preserving its descendants."
+ if (!item.attributes.length
+ && !isHtmlElement(item.parentNode, "OL")
+ && !isHtmlElement(item.parentNode, "UL")) {
+ removePreservingDescendants(item);
+
+ // "Otherwise, if item's parent is not an ol or ul, set the tag name of
+ // item to "div"."
+ } else if (!isHtmlElement(item.parentNode, "OL")
+ && !isHtmlElement(item.parentNode, "UL")) {
+ setTagName(item, "div");
}
}
}
--- a/source.html Mon May 16 13:23:48 2011 -0600
+++ b/source.html Mon May 16 14:40:09 2011 -0600
@@ -3040,12 +3040,33 @@
<li>For each [[node]] <var>node</var> [[contained]] in <var>node list</var>:
<ol>
- <li>If some [[ancestor]] of <var>node</var> is in <var>node list</var>,
+ <li>If the last member of <var>node list</var> is an [[ancestor]] of
+ <var>node</var>, or if <var>node</var> is not <span>editable</span>,
continue with the next <var>node</var>.
- <li>If <var>node</var> has no [[children]], or is an [[ol]] or [[ul]], or
- is an [[li]] whose [[parent]] is an [[ol]] or [[ul]], append it to
- <var>node list</var>.
+ <!--
+ This step is kind of weird. For regular outdenting, we start at the inside
+ and outdent going out, so that we remove the innermost indentation, on the
+ theory that that will produce the cleanest markup (remove the most nodes).
+ For lists, we remove the outermost indentation, because it makes a
+ difference whether we remove inner or outer indentation, and logically we
+ want to remove outer. E.g.,
+
+ <ol><li>foo</li><ul><li>bar</li></ul></ol>
+
+ should become
+
+ foo<ul><li>bar</li></ul>
+
+ not
+
+ foo<ol><li>bar</li></ol>.
+
+ But this is a bit weird and I'm wondering if it's really correct.
+ -->
+ <li>If <var>node</var> has no <span>editable</span> [[descendants]], or is
+ an [[ol]] or [[ul]], or is an [[li]] whose [[parent]] is an [[ol]] or
+ [[ul]], append it to <var>node list</var>.
</ol>
<li>While <var>node list</var> is not empty:
@@ -3093,8 +3114,6 @@
<ol>
<li>If <var>node</var> is not <span>editable</span>, abort these steps.
- <p class=XXX>Handle this better for nested editable/non-editable.
-
<li>If <var>node</var> is an [[ol]] or [[ul]] with no attributes except
possibly <code data-anolis-spec=html title=attr-ol-reversed>reversed</code>,
<code data-anolis-spec=html title=attr-ol-start>start</code>, and/or <code
@@ -3106,7 +3125,7 @@
<div class=XXX>
<p>We don't handle a case like
- <xmp><ol><ol style="color: red"><li>foo<li>bar</ol><li>baz</xmp>
+ <xmp><ol><ol style="color: red"><li>foo<li>bar</ol><li>baz</ol></xmp>
<p>If the inner [[ol]] is selected to be outdented, "foo" and "bar" will stop
being red. It seems nontrivial to handle this case in general, since we
@@ -3115,20 +3134,11 @@
</div>
<ol>
- <li>While <var>node</var> has [[children]]:
-
- <ol>
- <li>Let <var>child</var> be the first [[child]] of <var>node</var>.
-
- <li>If <var>child</var> is an [[li]] and the [[parent]] of
- <var>node</var> is not an [[ol]] or [[ul]], <span>set the tag name</span>
- of <var>child</var> to "div", and set <var>child</var> to the result.
-
- <li>Insert <var>child</var> into the [[parent]] of <var>node</var>
- immediately before <var>node</var>, <span>preserving ranges</span>.
- </ol>
-
- <li>Remove <var>node</var> from its [[parent]].
+ <li>Let <var>children</var> be the [[children]] of <var>node</var>.
+
+ <li>Remove <var>node</var>, <span>preserving its descendants</span>.
+
+ <li><span>Fix orphaned list items</span> in <var>children</var>.
<li>Abort these steps.
</ol>
@@ -3144,13 +3154,11 @@
title=attr-ol-type>type</code> attributes of <var>node</var>, if any are
set.
- <li><span>Set the tag name</span> of <var>node</var> to "div", and set
- <var>node</var> to the result.
-
- <li>For each [[li]] [[child]] <var>child</var> of <var>node</var>, unset
- the <code data-anolis-spec=html title=attr-li-value>value</code> attribute
- of <var>child</var> if set, then <span>set the tag name</span> of
- <var>child</var> to "div".
+ <li>Let <var>children</var> be the [[children]] of <var>node</var>.
+
+ <li><span>Set the tag name</span> of <var>node</var> to "div".
+
+ <li><span>Fix orphaned list items</span> in <var>children</var>.
<li>Abort these steps.
</ol>
@@ -3160,36 +3168,9 @@
created by IE, this might change the direction of some children, but then
their direction was probably changed incorrectly in the first place, so no
harm. -->
- <li>If <var>node</var> is an <span>indentation element</span>:
-
- <ol>
- <li>If <var>node</var>'s [[previoussibling]] and first [[child]] are both
- <span title="inline node">inline nodes</span>, and its [[previoussibling]]
- is not a [[br]], then call <code data-anolis-spec=domcore
- title=dom-Document-createElement>createElement("br")</code> on the
- [[ownerdocument]] of <var>node</var>, and insert the result into
- <var>node</var>'s [[parent]] immediately before <var>node</var>.
-
- <li>If <var>node</var>'s last [[child]] and [[nextsibling]] are both <span
- title="inline node">inline nodes</span>, and its last [[child]] is not a
- [[br]], then call <code data-anolis-spec=domcore
- title=dom-Document-createElement>createElement("br")</code> on the
- [[ownerdocument]] of <var>node</var>, and insert the result into
- <var>node</var>'s [[parent]] immediately after <var>node</var>.
-
- <!-- Just to be pedantic . . . it could happen! -->
- <li>If <var>node</var> has no [[children]], and its [[previoussibling]] and
- [[nextsibling]] are both <span title="inline node">inline nodes</span>, and
- its [[previoussibling]] is not a [[br]], then call <code
- data-anolis-spec=domcore
- title=dom-Document-createElement>createElement("br")</code> on the
- [[ownerdocument]] of <var>node</var>, and insert the result into
- <var>node</var>'s [[parent]] immediately before <var>node</var>.
-
- <li>Remove <var>node</var>, <span>preserving its descendants</span>.
-
- <li>Abort these steps.
- </ol>
+ <li>If <var>node</var> is an <span>indentation element</span>, remove
+ <var>node</var>, <span>preserving its descendants</span>. Then abort these
+ steps.
<!-- No browser handles the case of Firefox 4.0 in CSS mode, where it adds a
margin attribute to an existing element, including Firefox itself. So let's
@@ -3200,9 +3181,6 @@
Firefox in CSS mode, for instance (color, font-family, etc.). -->
<ol>
- <li><span>Set the tag name</span> of <var>node</var> to "div", and set
- <var>node</var> to the result.
-
<li>Unset the <code data-anolis-spec=html title=classes>class</code> and
<code data-anolis-spec=html title="the dir attribute">dir</code>
attributes of <var>node</var>, if any.
@@ -3210,6 +3188,8 @@
<li>Unset the margin, padding, and border CSS properties of
<var>node</var>.
+ <li><span>Set the tag name</span> of <var>node</var> to "div".
+
<li>Abort these steps.
</ol>
@@ -3313,16 +3293,29 @@
<li><span>Split the parent</span> of <var>node list</var>, with <var>new
parent</var> null.
- <li>For each <var>node</var> in <var>node list</var>:
+ <li><span>Fix orphaned list items</span> in <var>node list</var>.
+</ol>
+
+<p>To <dfn>fix orphaned list items</dfn> in a list of [[nodes]] <var>node
+list</var>:
+
+<ol>
+ <li>For each [[li]] <var>item</var> in <var>node list</var>:
<ol>
- <li>If <var>node</var> is an [[li]] with no attributes and its [[parent]]
- is not an [[ol]] or [[ul]], remove <var>node</var> from its [[parent]],
- <span>preserving its descendants</span>.
-
- <li>Otherwise, if <var>node</var> is an [[li]] and its [[parent]] is not an
- [[ol]] or [[ul]], <span>set the tag name</span> of <var>node</var> to
- "div".
+ <li>If <var>item</var>'s [[parent]] is not an [[ol]], unset
+ <var>item</var>'s <code data-anolis-spec=html
+ title=attr-li-value>value</code> attribute, if set.
+ <!-- IE9, Firefox 4.0, and Opera 11.10 keep the value attribute even if
+ the parent is now a ul. Chrome 12 dev strips it even if the parent is
+ now an ol. The spec makes more sense. -->
+
+ <li>If <var>item</var> has no attributes and its [[parent]] is not an
+ [[ol]] or [[ul]], remove <var>item</var>, <span>preserving its
+ descendants</span>.
+
+ <li>Otherwise, if <var>item</var>'s [[parent]] is not an [[ol]] or
+ [[ul]], <span>set the tag name</span> of <var>item</var> to "div".
</ol>
</ol>