--- a/editcommands.html Wed Jun 22 13:08:34 2011 -0600
+++ b/editcommands.html Wed Jun 22 13:42:55 2011 -0600
@@ -459,6 +459,24 @@
browsers (at least not in Opera 11.11), and also it breaks assumptions
elsewhere. E.g., if it gets turned into a p.
+<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
+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>.
+
+<p class=XXX>I don't know if the visible/invisible node definitions are really
+the way we want to do things. If they are, they need some adjustment, like to
+handle collapsed whitespace nodes.
+
+<p>A <dfn id=collapsed-block-prop>collapsed block prop</dfn> is either a <a href=#collapsed-line-break>collapsed line
+break</a> that is not an <a href=#extraneous-line-break>extraneous line break</a>, or 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> that is an <a href=#inline-node>inline node</a> and whose <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> are all
+either <a href=#invisible-node title="invisible node">invisible nodes</a> or <a href=#collapsed-block-prop title="collapsed block prop">collapsed block props</a> and that has at least
+one <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> that is a <a href=#collapsed-block-prop>collapsed block prop</a>.
+
<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>
@@ -2645,18 +2663,6 @@
<p>The <dfn id=default-single-line-container-name>default single-line container name</dfn> is "p".
<!-- 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
-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>.
-
-<p class=XXX>I don't know if the visible/invisible node definitions are really
-the way we want to do things. If they are, they need some adjustment, like to
-handle collapsed whitespace nodes and collapsed br's.
-
<h3 id=assorted-block-formatting-command-algorithms><span class=secno>7.2 </span>Assorted block formatting command algorithms</h3>
@@ -3515,11 +3521,11 @@
winds up empty after merging, we'll add a new br child at the end so it
doesn't collapse.
-->
- <li>If <var title="">start block</var> has one <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>, which 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>, remove
- 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> from it.
-
- <li>If <var title="">end block</var> has one <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>, which 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>, remove 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> from it.
+ <li>If <var title="">start block</var> has one <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>, which is a <a href=#collapsed-block-prop>collapsed
+ block prop</a>, remove 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> from it.
+
+ <li>If <var title="">end block</var> has one <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>, which is a <a href=#collapsed-block-prop>collapsed
+ block prop</a>, remove 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> from it.
<li>If <var title="">start block</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="">end block</var>:
<!-- Just repeatedly blow up the end block. -->
@@ -4987,6 +4993,10 @@
<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>.
+ <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> 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 a <a href=#collapsed-block-prop>collapsed block
+ prop</a>, add one to <var title="">offset</var>.
+
<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
--- a/implementation.js Wed Jun 22 13:08:34 2011 -0600
+++ b/implementation.js Wed Jun 22 13:42:55 2011 -0600
@@ -713,6 +713,62 @@
return origHeight == finalHeight;
}
+// "A visible node is a node that either is a prohibited paragraph child, or a
+// 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, "img")
+ || (isHtmlElement(node, "br") && !isExtraneousLineBreak(node))) {
+ return true;
+ }
+ for (var i = 0; i < node.childNodes.length; i++) {
+ if (isVisibleNode(node.childNodes[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// "An invisible node is a node that is not a visible node."
+function isInvisibleNode(node) {
+ return node && !isVisibleNode(node);
+}
+
+// "A collapsed block prop is either a collapsed line break that is not an
+// extraneous line break, or an Element that is an inline node and whose
+// children are all either invisible nodes or collapsed block props and that
+// has at least one child that is a collapsed block prop."
+function isCollapsedBlockProp(node) {
+ if (isCollapsedLineBreak(node)
+ && !isExtraneousLineBreak(node)) {
+ return true;
+ }
+
+ if (!isInlineNode(node)
+ || node.nodeType != Node.ELEMENT_NODE) {
+ return false;
+ }
+
+ var hasCollapsedBlockPropChild = false;
+ for (var i = 0; i < node.childNodes.length; i++) {
+ if (!isInvisibleNode(node.childNodes[i])
+ && !isCollapsedBlockProp(node.childNodes[i])) {
+ return false;
+ }
+ if (isCollapsedBlockProp(node.childNodes[i])) {
+ hasCollapsedBlockPropChild = true;
+ }
+ }
+
+ return hasCollapsedBlockPropChild;
+}
+
//@}
/////////////////////////////
@@ -3120,33 +3176,6 @@
// "The default single-line container name is "p"."
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 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, "img")
- || (isHtmlElement(node, "br") && !isExtraneousLineBreak(node))) {
- return true;
- }
- for (var i = 0; i < node.childNodes.length; i++) {
- if (isVisibleNode(node.childNodes[i])) {
- return true;
- }
- }
- return false;
-}
-
-// "An invisible node is a node that is not a visible node."
-function isInvisibleNode(node) {
- return node && !isVisibleNode(node);
-}
-
//@}
///// Assorted block formatting command algorithms /////
@@ -4025,15 +4054,17 @@
return;
}
- // "If start block has one child, which is a br, remove its child from it."
+ // "If start block has one child, which is a collapsed block prop, remove
+ // its child from it."
if (startBlock.children.length == 1
- && isHtmlElement(startBlock.firstChild, "br")) {
+ && isCollapsedBlockProp(startBlock.firstChild)) {
startBlock.removeChild(startBlock.firstChild);
}
- // "If end block has one child, which is a br, remove its child from it."
+ // "If end block has one child, which is a collapsed block prop, remove its
+ // child from it."
if (endBlock.children.length == 1
- && isHtmlElement(endBlock.firstChild, "br")) {
+ && isCollapsedBlockProp(endBlock.firstChild)) {
endBlock.removeChild(endBlock.firstChild);
}
@@ -5244,6 +5275,12 @@
&& isInvisibleNode(node.childNodes[offset])) {
node.removeChild(node.childNodes[offset]);
+ // "Otherwise, if node has a child with index offset and that child
+ // is a collapsed block prop, add one to offset."
+ } else if (offset < node.childNodes.length
+ && isCollapsedBlockProp(node.childNodes[offset])) {
+ 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 Wed Jun 22 13:08:34 2011 -0600
+++ b/source.html Wed Jun 22 13:42:55 2011 -0600
@@ -401,6 +401,25 @@
browsers (at least not in Opera 11.11), and also it breaks assumptions
elsewhere. E.g., if it gets turned into a p.
+<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
+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>.
+
+<p class=XXX>I don't know if the visible/invisible node definitions are really
+the way we want to do things. If they are, they need some adjustment, like to
+handle collapsed whitespace nodes.
+
+<p>A <dfn>collapsed block prop</dfn> is either a <span>collapsed line
+break</span> that is not an <span>extraneous line break</span>, or an
+[[element]] that is an <span>inline node</span> and whose [[children]] are all
+either <span title="invisible node">invisible nodes</span> or <span
+title="collapsed block prop">collapsed block props</span> and that has at least
+one [[child]] that is a <span>collapsed block prop</span>.
+
<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
@@ -2621,18 +2640,6 @@
<p>The <dfn>default single-line container name</dfn> is "p".
<!-- 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
-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>.
-
-<p class=XXX>I don't know if the visible/invisible node definitions are really
-the way we want to do things. If they are, they need some adjustment, like to
-handle collapsed whitespace nodes and collapsed br's.
<!-- @} -->
<h3>Assorted block formatting command algorithms</h3>
@@ -3499,11 +3506,11 @@
winds up empty after merging, we'll add a new br child at the end so it
doesn't collapse.
-->
- <li>If <var>start block</var> has one [[child]], which is a [[br]], remove
- its [[child]] from it.
-
- <li>If <var>end block</var> has one [[child]], which is a [[br]], remove its
- [[child]] from it.
+ <li>If <var>start block</var> has one [[child]], which is a <span>collapsed
+ block prop</span>, remove its [[child]] from it.
+
+ <li>If <var>end block</var> has one [[child]], which is a <span>collapsed
+ block prop</span>, remove its [[child]] from it.
<li>If <var>start block</var> is an [[ancestor]] of <var>end block</var>:
<!-- Just repeatedly blow up the end block. -->
@@ -4989,6 +4996,10 @@
<var>offset</var> and that [[child]] is an <span>editable</span>
<span>invisible node</span>, remove that [[child]] from <var>node</var>.
+ <li>Otherwise, if <var>node</var> has a [[child]] with [[index]]
+ <var>offset</var> and that [[child]] is a <span>collapsed block
+ prop</span>, add one to <var>offset</var>.
+
<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
--- a/tests.js Wed Jun 22 13:08:34 2011 -0600
+++ b/tests.js Wed Jun 22 13:42:55 2011 -0600
@@ -923,6 +923,19 @@
'<p>foo[]<br></p>bar',
'foo[]<br><p>bar</p>',
+ '<p>{}<br></p>foo',
+ '<p>{}<span><br></span></p>foo',
+ 'foo{}<p><br>',
+ 'foo{}<p><span><br></span>',
+ 'foo{}<br><p><br>',
+ 'foo{}<span><br></span><p><br>',
+ 'foo{}<br><p><span><br></span>',
+ 'foo{}<span><br></span><p><span><br></span>',
+ 'foo{}<p>',
+ '<table><tr><td>{}</table>foo',
+ '<table><tr><td>{}<br></table>foo',
+ '<table><tr><td>{}<span><br></span></table>foo',
+
'<div><p>foo[]</p></div><p>bar</p>',
'<p>foo[]</p><div><p>bar</p></div>',
'<div><p>foo[]</p></div><div><p>bar</p></div>',