--- a/implementation.js Wed May 25 12:39:44 2011 -0600+++ b/implementation.js Wed May 25 13:24:14 2011 -0600@@ -575,31 +575,10 @@ newParent = newParentInstructions(); }- // "If new parent's parent is null:"+ // "If new parent's parent is null, insert new parent into the parent of+ // the first member of node list immediately before the first member of+ // node list." if (!newParent.parentNode) {- // "If new parent is not an allowed child of the parent of the first- // member of node list, but is an allowed child of some ancestor of the- // first member of node list that is in the same editing host as the- // first member of node list, then while new parent is not an allowed- // child of the parent of the first member of node list, split the- // parent of node list."- var ancestor = nodeList[0].parentNode;- while (ancestor) {- if (isAllowedChild(newParent, ancestor)- && inSameEditingHost(ancestor, nodeList[0])) {- while (!isAllowedChild(newParent, nodeList[0].parentNode)) {- splitParent(nodeList);- }- break;- }- ancestor = ancestor.parentNode;- }- if (!ancestor && !isAllowedChild(newParent, nodeList[0].parentNode)) {- throw "Is this an error? Investigate.";- }-- // "Insert new parent into the parent of the first member of node list- // immediately before the first member of node list." nodeList[0].parentNode.insertBefore(newParent, nodeList[0]); }@@ -3305,6 +3284,33 @@ } }+function fixDisallowedAncestors(node) {+ // "If node is an allowed child of its parent, or it is not an allowed+ // child of any of its ancestors in the same editing host, abort these+ // steps and do nothing."+ if (isAllowedChild(node, node.parentNode)) {+ return;+ }+ var ancestor = node.parentNode;+ var hasAllowedAncestor = false;+ while (inSameEditingHost(node, ancestor)) {+ if (isAllowedChild(node, ancestor)) {+ hasAllowedAncestor = true;+ break;+ }+ ancestor = ancestor.parentNode;+ }+ if (!hasAllowedAncestor) {+ return;+ }++ // "While node is not an allowed child of its parent, split the parent of+ // the one-node list consisting of node."+ while (!isAllowedChild(node, node.parentNode)) {+ splitParent([node]);+ }+}+ function indentNodes(nodeList) { // "If node list is empty, do nothing and abort these steps." if (!nodeList.length) {@@ -3332,10 +3338,14 @@ // "Wrap node list, with sibling criteria matching any indentation element, // and new parent instructions to return the result of calling- // createElement("blockquote") on the ownerDocument of first node."- wrap(nodeList,+ // createElement("blockquote") on the ownerDocument of first node. Let new+ // parent be the result."+ var newParent = wrap(nodeList, function(node) { return isIndentationElement(node) }, function() { return firstNode.ownerDocument.createElement("blockquote") });++ // "Fix disallowed ancestors of new parent."+ fixDisallowedAncestors(newParent); } function outdentNode(node) {@@ -3614,19 +3624,15 @@ sublist.push(nodeList.shift()); }- // "If sublist contains more than one member, call- // createElement("li") on the context object and let node be the- // result. Insert node into the parent of the first member of- // sublist immediately before the first member of sublist. Then- // wrap sublist, with sibling criteria matching nothing and new- // parent instructions returning node."+ // "If sublist contains more than one member, wrap sublist, with+ // sibling criteria matching nothing and new parent instructions+ // returning the result of calling createElement("li") on the+ // context object. Let node be the result." var node; if (sublist.length > 1) {- node = document.createElement("li");- sublist[0].parentNode.insertBefore(node, sublist[0]); node = wrap(sublist, function() { return false },- function() { return node });+ function() { return document.createElement("li") }); // "Otherwise, let node be the sole member of sublist." } else {@@ -3696,25 +3702,20 @@ continue; }- // "If node is not an li, call createElement("li") on the context- // object and let new item be the result. Insert new item into- // node's parent immediately before node. Then wrap the one-node- // list consisting of node, with sibling criteria matching nothing- // and new parent instructions returning new item. Then set node to- // new item."+ // "If node is not an li, wrap the one-node list consisting of+ // node, with sibling criteria matching nothing and new parent+ // instructions returning the result of calling createElement("li")+ // on the context object. Set node to the result." if (!isHtmlElement(node, "LI")) {- var newItem = document.createElement("li");- node.parentNode.insertBefore(newItem, node);- wrap([node],+ node = wrap([node], function() { return false },- function() { return newItem });- node = newItem;+ function() { return document.createElement("li") }); } // "Wrap the one-node list consisting of node, with the sibling // criteria matching any HTML element with local name tag name, and // the new parent instructions being the following:"- wrap([node],+ var newParent = wrap([node], function(node) { return isHtmlElement(node, tagName) }, function() { // "If the parent of node is not an editable indentation@@ -3747,6 +3748,9 @@ // "Return the last child of list." return list.lastChild; });++ // "Fix disallowed ancestors of the previous step's result."+ fixDisallowedAncestors(newParent); } } }

--- a/source.html Wed May 25 12:39:44 2011 -0600+++ b/source.html Wed May 25 13:24:14 2011 -0600@@ -574,22 +574,9 @@ <li>Otherwise, run the <span>new parent instructions</span>, and let <var>new parent</var> be the result.- <li>If <var>new parent</var>'s [[parent]] is null:-- <ol>- <li>If <var>new parent</var> is not an <span>allowed child</span> of the- [[parent]] of the first member of <var>node list</var>, but is an- <span>allowed child</span> of some [[ancestor]] of the first member of- <var>node list</var> that is <span>in the same editing host</span> as the- first member of <var>node list</var>, then while <var>new parent</var> is- not an <span>allowed child</span> of the [[parent]] of the first member of- <var>node list</var>, <span>split the parent</span> of <var>node- list</var>.-- <li>Insert <var>new parent</var> into the [[parent]] of the first member of- <var>node list</var> immediately before the first member of <var>node- list</var>.- </ol>+ <li>If <var>new parent</var>'s [[parent]] is null, insert <var>new+ parent</var> into the [[parent]] of the first member of <var>node list</var>+ immediately before the first member of <var>node list</var>. <li>Let <var>original parent</var> be the [[parent]] of the first member of <var>node list</var>.@@ -2575,6 +2562,22 @@ <h3>Assorted block formatting command algorithms</h3>+<p>To <dfn>fix disallowed ancestors</dfn> of a [[node]] <var>node</var>:++<p class=XXX>This works okay for stuff nested in paragraphs or such, but for+fixing lis/table stuff/etc. we probably don't want to do this at all; we+probably want to add ancestor wrappers or something.++<ol>+ <li>If <var>node</var> is an <span>allowed child</span> of its [[parent]], or+ it is not an <span>allowed child</span> of any of its [[ancestors]] <span>in+ the same editing host</span>, abort these steps and do nothing.++ <li>While <var>node</var> is not an <span>allowed child</span> of its+ [[parent]], <span>split the parent</span> of the one-[[node]] list consisting+ of <var>node</var>.+</ol>+ <p>To <dfn>indent</dfn> a list <var>node list</var> of consecutive [[sibling]] [[nodes]]: <!--@@ -2664,7 +2667,8 @@ parent instructions</span> to return the result of calling <code data-anolis-spec=domcore title=dom-Document-createElement>createElement("blockquote")</code> on the- [[ownerdocument]] of <var>first node</var>.+ [[ownerdocument]] of <var>first node</var>. Let <var>new parent</var> be the+ result. <p class=XXX>This indents on both sides, so we don't have to worry about directionality. Preferably we should indent only on the start side, but@@ -2674,6 +2678,8 @@ descendant block has different direction (so should be indented the other way). It's not clear to me that we should worry about it: most browsers don't, and the ones that do get it wrong.++ <li><span>Fix disallowed ancestors</span> of <var>new parent</var>. </ol> <p>To <dfn>fix orphaned list items</dfn> in a list of [[nodes]] <var>node@@ -3442,18 +3448,12 @@ remove the first member from <var>node list</var> and append it to <var>sublist</var>.- <li>If <var>sublist</var> contains more than one member, call <code+ <li>If <var>sublist</var> contains more than one member, <span>wrap</span>+ <var>sublist</var>, with <span>sibling criteria</span> matching nothing and+ <span>new parent instructions</span> returning the result of calling <code data-anolis-spec=domcore title=dom-Document-createElement>createElement("li")</code> on the- [[contextobject]] and let <var>node</var> be the result. Insert- <var>node</var> into the [[parent]] of the first member of- <var>sublist</var> immediately before the first member of- <var>sublist</var>. Then <span>wrap</span> <var>sublist</var>, with- <span>sibling criteria</span> matching nothing and <span>new parent- instructions</span> returning <var>node</var>.-- <p class=XXX>This is a hack to avoid the wrap algorithm trying to reparent- the li. Think of a better way to fix it.+ [[contextobject]]. Let <var>node</var> be the result. <li>Otherwise, let <var>node</var> be the sole member of <var>sublist</var>.@@ -3540,18 +3540,12 @@ elements</span> with [[localname]] <var>other tag name</var> (if any) to <var>node list</var> and continue from the beginning of this loop.- <li>If <var>node</var> is not an [[li]], call <code- data-anolis-spec=domcore+ <li>If <var>node</var> is not an [[li]], <span>wrap</span> the one-[[node]]+ list consisting of <var>node</var>, with <span>sibling criteria</span>+ matching nothing and <span>new parent instructions</span> returning+ the result of calling <code data-anolis-spec=domcore title=dom-Document-createElement>createElement("li")</code> on the- [[contextobject]] and let <var>new item</var> be the result. Insert- <var>new item</var> into <var>node</var>'s [[parent]] immediately before- <var>node</var>. Then <span>wrap</span> the one-[[node]] list consisting- of <var>node</var>, with <span>sibling criteria</span> matching nothing and- <span>new parent instructions</span> returning <var>new item</var>. Then- set <var>node</var> to <var>new item</var>.-- <p class=XXX>This is a hack to avoid the wrap algorithm trying to reparent- the li. Think of a better way to fix it.+ [[contextobject]]. Set <var>node</var> to the result. <li><span>Wrap</span> the one-[[node]] list consisting of <var>node</var>, with the <span>sibling criteria</span> matching any <span>HTML@@ -3582,6 +3576,8 @@ <li>Return the last [[child]] of <var>list</var>. </ol>++ <li><span>Fix disallowed ancestors</span> of the previous step's result. </ol> </ol>@@ -3689,6 +3685,9 @@ the "in the same editing host" thing handles it? </div>+ <p class=XXX>Do we need to fix disallowed ancestors later, or is this step+ enough that it's not an issue?+ <!-- We have two different behaviors, one for div and p and one for everything else. The basic difference is that for div and p, we assume that it should