--- a/editcommands.html Tue Jun 21 15:28:14 2011 -0600
+++ b/editcommands.html Tue Jun 21 16:18:46 2011 -0600
@@ -446,6 +446,19 @@
Or its ancestor has a fixed height? Would it be better to use some DOM-based
definition?
+<p>An <dfn id=extraneous-line-break>extraneous line break</dfn> is 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> that has no visual effect,
+in that removing it from the DOM would not change layout, except that 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>
+that is the sole child of 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> is not extraneous.
+
+<p class=XXX>Also possibly a bad definition. Again, I test by just removing it
+and seeing what happens. (Actually, setting display: none, so that it doesn't
+mess up ranges.)
+
+<p class=XXX>The thing about li is a not very nice hack. The issue is that an
+li won't collapse even if it has no children at all, but that's not true in all
+browsers (at least not in Opera 11.11), and also it breaks assumptions
+elsewhere. E.g., if it gets turned into a p.
+
<p>Each <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/html/#htmldocument>HTMLDocument</a></code> has a boolean <dfn id=css-styling-flag>CSS styling flag</dfn> associated
with it, which must initially be false. (<a href=#the-stylewithcss-command>The <code title="">styleWithCSS</code> command</a> can be used to modify or query it, by
means of the <code><a href=#execcommand()>execCommand()</a></code> and <code><a href=#querycommandstate()>queryCommandState()</a></code>
@@ -531,26 +544,38 @@
<var title="">node</var>:
<ol>
- <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, or it is an <a href=#inline-node>inline
- node</a>, do nothing and abort these steps.
-
- <li>If the <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> of <var title="">node</var> is 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>, and the
- <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> of the <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> of <var title="">node</var> is an
- <a href=#inline-node>inline node</a> that 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>, remove the <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>
- of <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="">ref</var> be the <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> of <var title="">node</var>.
+
+ <li>If <var title="">ref</var> is null, abort these steps.
+
+ <li>While <var title="">ref</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>, set <var title="">ref</var> to its
+ <code class=external data-anolis-spec=domcore title=dom-Node-lastChild><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-lastchild>lastChild</a></code>.
+
+ <li>While <var title="">ref</var> is an <a href=#invisible-node>invisible node</a> but not an
+ <a href=#extraneous-line-break>extraneous line break</a>, and <var title="">ref</var> does not equal
+ <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>, set <var title="">ref</var> to the <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> before it in
+ <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#tree-order>tree order</a>.
+
+ <li>If <var title="">ref</var> is an <a href=#editable>editable</a> <a href=#extraneous-line-break>extraneous line
+ break</a>, remove it 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>.
</ol>
<p>To <dfn id=remove-extraneous-line-breaks-at-the-end-of>remove extraneous line breaks at the end of</dfn> 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>
<var title="">node</var>:
<ol>
- <li>If <var title="">node</var> is not an <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>, or it is an <a href=#inline-node>inline
- node</a>, do nothing and abort these steps.
-
- <li>If <var title="">node</var> has at least two <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 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 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>, and its second-to-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 an <a href=#inline-node>inline node</a>
- that 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>, remove the 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> of <var title="">node</var> from
- <var title="">node</var>.
+ <li>Let <var title="">ref</var> be <var title="">node</var>.
+
+ <li>While <var title="">ref</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>, set <var title="">ref</var> to its
+ <code class=external data-anolis-spec=domcore title=dom-Node-lastChild><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-lastchild>lastChild</a></code>.
+
+ <li>While <var title="">ref</var> is an <a href=#invisible-node>invisible node</a> but not an
+ <a href=#extraneous-line-break>extraneous line break</a>, and <var title="">ref</var> does not equal
+ <var title="">node</var>, set <var title="">ref</var> to the <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> before it in
+ <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#tree-order>tree order</a>.
+
+ <li>If <var title="">ref</var> is an <a href=#editable>editable</a> <a href=#extraneous-line-break>extraneous line
+ break</a>, remove it 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>.
</ol>
<p>To <dfn id=remove-extraneous-line-breaks-from>remove extraneous line breaks from</dfn> 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>, first
@@ -675,8 +700,10 @@
<var title="">original parent</var>.
<li>If <var title="">node list</var>'s last member's <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> is null,
- <a href=#remove-extraneous-line-breaks-at-the-end-of>remove extraneous line breaks at the end of</a> <var title="">node
- list</var>'s last member'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>.
+ but 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 null, <a href=#remove-extraneous-line-breaks-at-the-end-of>remove extraneous line breaks at the
+ end of</a> <var title="">node list</var>'s last member'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>.
+ <!-- The parent might be null if it's a br that we removed in the last step,
+ in which case this step isn't necessary. -->
</ol>
<p>To remove 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> <var title="">node</var> while <dfn id=preserving-its-descendants>preserving its
@@ -2562,9 +2589,9 @@
<!-- Possibly to be made configurable later. -->
<p>A <dfn id=visible-node>visible node</dfn> is 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 either is a <a href=#prohibited-paragraph-child>prohibited
-paragraph child</a>, or a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node whose <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is not empty, or 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> or <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code>, or any <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> with 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>descendant</a> that is a
-<a href=#visible-node>visible node</a>.
+paragraph child</a>, or a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node whose <code class=external data-anolis-spec=domcore title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> is not empty, or
+an <code class=external data-anolis-spec=html title="the img element"><a href=http://www.whatwg.org/html/#the-img-element>img</a></code>, or 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> that is not an <a href=#extraneous-line-break>extraneous line break</a>, or
+any <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> with 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>descendant</a> that is a <a href=#visible-node>visible node</a>.
<p>An <dfn id=invisible-node>invisible node</dfn> is 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 not a <a href=#visible-node>visible
node</a>.
@@ -4903,27 +4930,6 @@
<var title="">offset</var> and that <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 an <a href=#editable>editable</a>
<a href=#invisible-node>invisible node</a>, remove that <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> from <var title="">node</var>.
- <!-- We need these extra two steps in forwardDelete, relative to delete, to
- skip over line breaks at the end of blocks. -->
- <li>Otherwise, if <var title="">offset</var> is one less than <var title="">node</var>'s
- <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a>, and <var title="">node</var> is a <a href=#prohibited-paragraph-child>prohibited paragraph
- child</a> whose 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 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>, add one to
- <var title="">offset</var>.
-
- <li>Otherwise, if <var title="">node</var> has a <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> with <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>
- <var title="">offset</var> + 1, and its <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 <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">offset</var> is
- 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>, and its <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 <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> <var title="">offset</var> + 1 is a
- <a href=#prohibited-paragraph-child>prohibited paragraph child</a>, add one to <var title="">offset</var>.
-
- <div class=XXX>
- <p>These two steps don't correctly handle things like
-
- </p><xmp><p>foo<span><br></span></p></xmp>
-
- <p>For that matter, nor do most cases where we deal with line breaks like
- this. Should add a bunch of tests for this and change stuff so we pass.
- </div>
-
<li>Otherwise, if <var title="">offset</var> is the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of
<var title="">node</var> and <var title="">node</var> is not a <a href=#prohibited-paragraph-child>prohibited paragraph
child</a>, or if <var title="">node</var> is an <a href=#invisible-node>invisible node</a>, set
@@ -5527,6 +5533,10 @@
<li><a href=#split-the-parent>Split the parent</a> of the one-<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> list consisting of
<var title="">container</var>.
+ <li>If <var title="">container</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>, 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 <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a> and append the result as
+ the 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> of <var title="">container</var>.
+
<li><a href=#fix-disallowed-ancestors>Fix disallowed ancestors</a> of <var title="">container</var>.
<li>Abort these steps.
--- a/implementation.js Tue Jun 21 15:28:14 2011 -0600
+++ b/implementation.js Tue Jun 21 16:18:46 2011 -0600
@@ -683,6 +683,36 @@
return origHeight != finalHeight;
}
+// "An extraneous line break is a br that has no visual effect, in that
+// removing it from the DOM would not change layout, except that a br that is
+// the sole child of an li is not extraneous."
+function isExtraneousLineBreak(br) {
+ if (!isHtmlElement(br, "br")) {
+ return false;
+ }
+
+ if (isHtmlElement(br.parentNode, "li")
+ && br.parentNode.childNodes.length == 1) {
+ return false;
+ }
+
+ var ref = br.parentNode;
+ while (getComputedStyle(ref).display == "inline") {
+ ref = ref.parentNode;
+ }
+ var style = br.hasAttribute("style") ? br.getAttribute("style") : null;
+ var origHeight = ref.offsetHeight;
+ br.setAttribute("style", "display:none");
+ var finalHeight = ref.offsetHeight;
+ if (style === null) {
+ br.removeAttribute("style");
+ } else {
+ br.setAttribute("style", style);
+ }
+
+ return origHeight == finalHeight;
+}
+
//@}
/////////////////////////////
@@ -806,41 +836,58 @@
}
function removeExtraneousLineBreaksBefore(node) {
- // "If node is not an Element, or it is an inline node, do nothing and
- // abort these steps."
- if (!node
- || node.nodeType != Node.ELEMENT_NODE
- || isInlineNode(node)) {
+ // "Let ref be the previousSibling of node."
+ var ref = node.previousSibling;
+
+ // "If ref is null, abort these steps."
+ if (!ref) {
return;
}
- // "If the previousSibling of node is a br, and the previousSibling of the
- // previousSibling of node is an inline node that is not a br, remove the
- // previousSibling of node from its parent."
- if (isHtmlElement(node.previousSibling, "BR")
- && isInlineNode(node.previousSibling.previousSibling)
- && !isHtmlElement(node.previousSibling.previousSibling, "BR")) {
- node.parentNode.removeChild(node.previousSibling);
+ // "While ref has children, set ref to its lastChild."
+ while (ref.hasChildNodes()) {
+ ref = ref.lastChild;
+ }
+
+ // "While ref is an invisible node but not an extraneous line break, and
+ // ref does not equal node's parent, set ref to the node before it in tree
+ // order."
+ while (isInvisibleNode(ref)
+ && !isExtraneousLineBreak(ref)
+ && ref != node.parentNode) {
+ ref = previousNode(ref);
+ }
+
+ // "If ref is an editable extraneous line break, remove it from its
+ // parent."
+ if (isEditable(ref)
+ && isExtraneousLineBreak(ref)) {
+ ref.parentNode.removeChild(ref);
}
}
function removeExtraneousLineBreaksAtTheEndOf(node) {
- // "If node is not an Element, or it is an inline node, do nothing and
- // abort these steps."
- if (!node
- || node.nodeType != Node.ELEMENT_NODE
- || isInlineNode(node)) {
- return;
- }
-
- // "If node has at least two children, and its last child is a br, and its
- // second-to-last child is an inline node that is not a br, remove the last
- // child of node from node."
- if (node.childNodes.length >= 2
- && isHtmlElement(node.lastChild, "BR")
- && isInlineNode(node.lastChild.previousSibling)
- && !isHtmlElement(node.lastChild.previousSibling, "BR")) {
- node.removeChild(node.lastChild);
+ // "Let ref be node."
+ var ref = node;
+
+ // "While ref has children, set ref to its lastChild."
+ while (ref.hasChildNodes()) {
+ ref = ref.lastChild;
+ }
+
+ // "While ref is an invisible node but not an extraneous line break, and
+ // ref does not equal node, set ref to the node before it in tree order."
+ while (isInvisibleNode(ref)
+ && !isExtraneousLineBreak(ref)
+ && ref != node) {
+ ref = previousNode(ref);
+ }
+
+ // "If ref is an editable extraneous line break, remove it from its
+ // parent."
+ if (isEditable(ref)
+ && isExtraneousLineBreak(ref)) {
+ ref.parentNode.removeChild(ref);
}
}
@@ -956,9 +1003,11 @@
removeExtraneousLineBreaksBefore(originalParent);
}
- // "If node list's last member's nextSibling is null, remove extraneous
- // line breaks at the end of node list's last member's parent."
- if (!nodeList[nodeList.length - 1].nextSibling) {
+ // "If node list's last member's nextSibling is null, but its parent is not
+ // null, remove extraneous line breaks at the end of node list's last
+ // member's parent."
+ if (!nodeList[nodeList.length - 1].nextSibling
+ && nodeList[nodeList.length - 1].parentNode) {
removeExtraneousLineBreaksAtTheEndOf(nodeList[nodeList.length - 1].parentNode);
}
}
@@ -3013,15 +3062,17 @@
var defaultSingleLineContainerName = "p";
// "A visible node is a node that either is a prohibited paragraph child, or a
-// Text node whose data is not empty, or a br or img, or any node with a
-// descendant that is a visible node."
+// Text node whose data is not empty, or an img, or a br that is not an
+// extraneous line break, or any node with a descendant that is a visible
+// node."
function isVisibleNode(node) {
if (!node) {
return false;
}
if (isProhibitedParagraphChild(node)
|| (node.nodeType == Node.TEXT_NODE && node.length)
- || isHtmlElement(node, ["br", "img"])) {
+ || isHtmlElement(node, "img")
+ || (isHtmlElement(node, "br") && !isExtraneousLineBreak(node))) {
return true;
}
for (var i = 0; i < node.childNodes.length; i++) {
@@ -5134,22 +5185,6 @@
&& isInvisibleNode(node.childNodes[offset])) {
node.removeChild(node.childNodes[offset]);
- // "Otherwise, if offset is one less than node's length, and node
- // is a prohibited paragraph child whose last child is a br, add
- // one to offset."
- } else if (offset == getNodeLength(node) - 1
- && isProhibitedParagraphChild(node)
- && isHtmlElement(node.lastChild, "br")) {
- offset++;
-
- // "Otherwise, if node has a child with index offset + 1, and its
- // child of index offset is a br, and its child of index offset + 1
- // is a prohibited paragraph child, add one to offset."
- } else if (offset + 1 < node.childNodes.length
- && isHtmlElement(node.childNodes[offset], "br")
- && isProhibitedParagraphChild(node.childNodes[offset + 1])) {
- offset++;
-
// "Otherwise, if offset is the length of node and node is not a
// prohibited paragraph child, or if node is an invisible node, set
// offset to one plus the index of node, then set node to its
--- a/source.html Tue Jun 21 15:28:14 2011 -0600
+++ b/source.html Tue Jun 21 16:18:46 2011 -0600
@@ -388,6 +388,19 @@
Or its ancestor has a fixed height? Would it be better to use some DOM-based
definition?
+<p>An <dfn>extraneous line break</dfn> is a [[br]] that has no visual effect,
+in that removing it from the DOM would not change layout, except that a [[br]]
+that is the sole child of an [[li]] is not extraneous.
+
+<p class=XXX>Also possibly a bad definition. Again, I test by just removing it
+and seeing what happens. (Actually, setting display: none, so that it doesn't
+mess up ranges.)
+
+<p class=XXX>The thing about li is a not very nice hack. The issue is that an
+li won't collapse even if it has no children at all, but that's not true in all
+browsers (at least not in Opera 11.11), and also it breaks assumptions
+elsewhere. E.g., if it gets turned into a p.
+
<p>Each [[htmldocument]] has a boolean <dfn>CSS styling flag</dfn> associated
with it, which must initially be false. (<span>The <code
title>styleWithCSS</code> command</span> can be used to modify or query it, by
@@ -476,26 +489,38 @@
<var>node</var>:
<ol>
- <li>If <var>node</var> is not an [[element]], or it is an <span>inline
- node</span>, do nothing and abort these steps.
-
- <li>If the [[previoussibling]] of <var>node</var> is a [[br]], and the
- [[previoussibling]] of the [[previoussibling]] of <var>node</var> is an
- <span>inline node</span> that is not a [[br]], remove the [[previoussibling]]
- of <var>node</var> from its [[parent]].
+ <li>Let <var>ref</var> be the [[previoussibling]] of <var>node</var>.
+
+ <li>If <var>ref</var> is null, abort these steps.
+
+ <li>While <var>ref</var> has [[children]], set <var>ref</var> to its
+ [[lastchild]].
+
+ <li>While <var>ref</var> is an <span>invisible node</span> but not an
+ <span>extraneous line break</span>, and <var>ref</var> does not equal
+ <var>node</var>'s [[parent]], set <var>ref</var> to the [[node]] before it in
+ [[treeorder]].
+
+ <li>If <var>ref</var> is an <span>editable</span> <span>extraneous line
+ break</span>, remove it from its [[parent]].
</ol>
<p>To <dfn>remove extraneous line breaks at the end of</dfn> a [[node]]
<var>node</var>:
<ol>
- <li>If <var>node</var> is not an [[element]], or it is an <span>inline
- node</span>, do nothing and abort these steps.
-
- <li>If <var>node</var> has at least two [[children]], and its last [[child]]
- is a [[br]], and its second-to-last [[child]] is an <span>inline node</span>
- that is not a [[br]], remove the last [[child]] of <var>node</var> from
- <var>node</var>.
+ <li>Let <var>ref</var> be <var>node</var>.
+
+ <li>While <var>ref</var> has [[children]], set <var>ref</var> to its
+ [[lastchild]].
+
+ <li>While <var>ref</var> is an <span>invisible node</span> but not an
+ <span>extraneous line break</span>, and <var>ref</var> does not equal
+ <var>node</var>, set <var>ref</var> to the [[node]] before it in
+ [[treeorder]].
+
+ <li>If <var>ref</var> is an <span>editable</span> <span>extraneous line
+ break</span>, remove it from its [[parent]].
</ol>
<p>To <dfn>remove extraneous line breaks from</dfn> a [[node]], first
@@ -623,8 +648,10 @@
<var>original parent</var>.
<li>If <var>node list</var>'s last member's [[nextsibling]] is null,
- <span>remove extraneous line breaks at the end of</span> <var>node
- list</var>'s last member's [[parent]].
+ but its [[parent]] is not null, <span>remove extraneous line breaks at the
+ end of</span> <var>node list</var>'s last member's [[parent]].
+ <!-- The parent might be null if it's a br that we removed in the last step,
+ in which case this step isn't necessary. -->
</ol>
<p>To remove a [[node]] <var>node</var> while <dfn>preserving its
@@ -2541,9 +2568,9 @@
<!-- Possibly to be made configurable later. -->
<p>A <dfn>visible node</dfn> is a [[node]] that either is a <span>prohibited
-paragraph child</span>, or a [[text]] node whose [[cddata]] is not empty, or a
-[[br]] or [[img]], or any [[node]] with a [[descendant]] that is a
-<span>visible node</span>.
+paragraph child</span>, or a [[text]] node whose [[cddata]] is not empty, or
+an [[img]], or a [[br]] that is not an <span>extraneous line break</span>, or
+any [[node]] with a [[descendant]] that is a <span>visible node</span>.
<p>An <dfn>invisible node</dfn> is a [[node]] that is not a <span>visible
node</span>.
@@ -4907,27 +4934,6 @@
<var>offset</var> and that [[child]] is an <span>editable</span>
<span>invisible node</span>, remove that [[child]] from <var>node</var>.
- <!-- We need these extra two steps in forwardDelete, relative to delete, to
- skip over line breaks at the end of blocks. -->
- <li>Otherwise, if <var>offset</var> is one less than <var>node</var>'s
- [[length]], and <var>node</var> is a <span>prohibited paragraph
- child</span> whose last [[child]] is a [[br]], add one to
- <var>offset</var>.
-
- <li>Otherwise, if <var>node</var> has a [[child]] with [[index]]
- <var>offset</var> + 1, and its [[child]] of [[index]] <var>offset</var> is
- a [[br]], and its [[child]] of [[index]] <var>offset</var> + 1 is a
- <span>prohibited paragraph child</span>, add one to <var>offset</var>.
-
- <div class=XXX>
- <p>These two steps don't correctly handle things like
-
- <xmp><p>foo<span><br></span></p></xmp>
-
- <p>For that matter, nor do most cases where we deal with line breaks like
- this. Should add a bunch of tests for this and change stuff so we pass.
- </div>
-
<li>Otherwise, if <var>offset</var> is the [[nodelength]] of
<var>node</var> and <var>node</var> is not a <span>prohibited paragraph
child</span>, or if <var>node</var> is an <span>invisible node</span>, set
@@ -5541,6 +5547,10 @@
<li><span>Split the parent</span> of the one-[[node]] list consisting of
<var>container</var>.
+ <li>If <var>container</var> has no [[children]], call
+ [[createelement|"br"]] on the [[contextobject]] and append the result as
+ the last [[child]] of <var>container</var>.
+
<li><span>Fix disallowed ancestors</span> of <var>container</var>.
<li>Abort these steps.