author | Aryeh Gregor <AryehGregor+gitcommit@gmail.com> |
Thu, 22 Sep 2011 14:03:58 -0600 | |
changeset 618 | e60077322f8a |
parent 617 | 89fed05c54e0 |
child 619 | 031902d853b9 |
conformancetest/data.js | ||
editing.html | ||
implementation.js | ||
source.html |
--- a/conformancetest/data.js Thu Sep 22 13:53:40 2011 -0600 +++ b/conformancetest/data.js Thu Sep 22 14:03:58 2011 -0600 @@ -2129,11 +2129,11 @@ {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["foo [] bar", [["stylewithcss","false"],["delete",""]], - "foo []bar", + "foo [] bar", {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], ["foo [] bar", [["stylewithcss","true"],["delete",""]], - "foo []bar", + "foo [] bar", {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["foo []bar", [["stylewithcss","false"],["delete",""]], @@ -2153,11 +2153,11 @@ {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["foo <span> </span>[] bar", [["stylewithcss","false"],["delete",""]], - "foo {}bar", + "foo {} bar", {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], ["foo <span> </span>[] bar", [["stylewithcss","true"],["delete",""]], - "foo {}bar", + "foo {} bar", {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["foo <span> </span> []bar", [["stylewithcss","false"],["delete",""]], @@ -2201,11 +2201,11 @@ {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["<p>foo </p><p>[] bar</p>", [["stylewithcss","false"],["delete",""]], - "<p>foo {} bar</p>", + "<p>foo{}bar</p>", {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], ["<p>foo </p><p>[] bar</p>", [["stylewithcss","true"],["delete",""]], - "<p>foo {} bar</p>", + "<p>foo{}bar</p>", {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["foo<table><tr><td>[]bar</table>baz", [["stylewithcss","false"],["delete",""]], @@ -3905,11 +3905,11 @@ {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["foo<b> [ bar]</b>", [["stylewithcss","false"],["delete",""]], - "foo<b> []</b>", + "foo<b> []</b>", {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], ["foo<b> [ bar]</b>", [["stylewithcss","true"],["delete",""]], - "foo<b> []</b>", + "foo<b> []</b>", {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], ["<b>[foo ] </b>bar", [["stylewithcss","false"],["delete",""]], @@ -8305,11 +8305,11 @@ {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], ["foo [] bar", [["stylewithcss","false"],["forwarddelete",""]], - "foo []bar", + "foo [] bar", {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], ["foo [] bar", [["stylewithcss","true"],["forwarddelete",""]], - "foo []bar", + "foo [] bar", {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], ["foo [] bar", [["stylewithcss","false"],["forwarddelete",""]], @@ -8329,11 +8329,11 @@ {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], ["foo []<span> </span> bar", [["stylewithcss","false"],["forwarddelete",""]], - "foo {}bar", + "foo {} bar", {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], ["foo []<span> </span> bar", [["stylewithcss","true"],["forwarddelete",""]], - "foo {}bar", + "foo {} bar", {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], ["foo <span> </span>[] bar", [["stylewithcss","false"],["forwarddelete",""]], @@ -17017,19 +17017,19 @@ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], ["foo[] ", [["stylewithcss","false"],["inserttext"," "]], - "foo [] ", + "foo []", {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], ["foo[] ", [["stylewithcss","true"],["inserttext"," "]], - "foo [] ", + "foo []", {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], [" foo [] ", [["stylewithcss","false"],["inserttext"," "]], - " foo [] ", + " foo []", {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], [" foo [] ", [["stylewithcss","true"],["inserttext"," "]], - " foo [] ", + " foo []", {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], ["foo[]<span> </span>", [["stylewithcss","false"],["inserttext"," "]], @@ -17049,19 +17049,19 @@ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], [" []foo", [["stylewithcss","false"],["inserttext"," "]], - " []foo", + " []foo", {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], [" []foo", [["stylewithcss","true"],["inserttext"," "]], - " []foo", + " []foo", {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], [" [] foo ", [["stylewithcss","false"],["inserttext"," "]], - " [] foo ", + " []foo ", {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], [" [] foo ", [["stylewithcss","true"],["inserttext"," "]], - " [] foo ", + " []foo ", {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], ["<span> </span>[]foo", [["stylewithcss","false"],["inserttext"," "]],
--- a/editing.html Thu Sep 22 13:53:40 2011 -0600 +++ b/editing.html Thu Sep 22 14:03:58 2011 -0600 @@ -4662,6 +4662,12 @@ <li>If the <a href=#active-range>active range</a> is null, abort these steps and do nothing. + <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>. + + <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>. + <li>Let <var title="">start node</var>, <var title="">start offset</var>, <var title="">end node</var>, and <var title="">end offset</var> be the <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>nodes</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offsets</a>. @@ -4881,7 +4887,7 @@ − <var title="">start offset</var>)</a></code> on <var title="">start node</var>. <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at (<var title="">start node</var>, - <var title="">start offset</var>). + <var title="">start offset</var>), with <var title="">fix collapsed space</var> false. <li>If <var title="">direction</var> is "forward", call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToStart><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetostart>collapseToStart()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>. @@ -4957,10 +4963,10 @@ <code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(0, <var title="">end offset</var>)</a></code> on it. <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s - <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>. + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>, with <var title="">fix collapsed space</var> false. <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s - <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>. + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>, with <var title="">fix collapsed space</var> false. <li> <div class=comments> @@ -5403,7 +5409,8 @@ </ol> <p>To <dfn id=canonicalize-whitespace>canonicalize whitespace</dfn> at (<var title="">node</var>, -<var title="">offset</var>): +<var title="">offset</var>), given an optional boolean argument <var title="">fix collapsed +space</var> that defaults to true: <ol> <li>If <var title="">node</var> is neither <a href=#editable>editable</a> nor an <a href=#editing-host>editing @@ -5444,14 +5451,19 @@ </ol> <li> - <p class=comments>Now we collapse any consecutive spaces. + <p class=comments>Now we collapse any consecutive spaces, if <var title="">fix + collapsed space</var> is true. <p>Let <var title="">end node</var> equal <var title="">start node</var> and <var title="">end offset</var> equal <var title="">start offset</var>. <li>Let <var title="">length</var> equal zero. - <li>Let <var title="">follows space</var> be false. + <li> + <p class=comments>This tries to delete spaces at the beginning of a line (<a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=14119">bug 14119</a>). + + <p>Let <var title="">collapse spaces</var> be true if <var title="">start offset</var> is zero + and <var title="">start node</var> <a href=#follows-a-line-break>follows a line break</a>, otherwise false. <li>Repeat the following steps: @@ -5478,14 +5490,15 @@ space (0x0020) or non-breaking space (0x00A0): <ol> - <li>If <var title="">follows space</var> is true and the <var title="">end offset</var>th - <a href=http://dev.w3.org/2006/webapi/WebIDL/#dfn-code-unit>code unit</a> of <var title="">end node</var>'s <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 a space (0x0020), call + <li>If <var title="">fix collapsed space</var> is true, and <var title="">collapse + spaces</var> is true, and the <var title="">end offset</var>th <a href=http://dev.w3.org/2006/webapi/WebIDL/#dfn-code-unit>code unit</a> of + <var title="">end node</var>'s <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 a space (0x0020): call <code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(<var title="">end offset</var>, 1)</a></code> on <var title="">end node</var>, then continue this loop from the beginning. - <li>Set <var title="">follows space</var> to true if the <var title="">end offset</var>th - <a href=http://dev.w3.org/2006/webapi/WebIDL/#dfn-code-unit>code unit</a> of <var title="">end node</var>'s <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 a space (0x0020), false - otherwise. + <li>Set <var title="">collapse spaces</var> to true if the <var title="">end offset</var>th + <a href=http://dev.w3.org/2006/webapi/WebIDL/#dfn-code-unit>code unit</a> of <var title="">end node</var>'s <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 a space (0x0020), + false otherwise. <li>Add one to <var title="">end offset</var>. @@ -5496,6 +5509,44 @@ </ol> <li> + <p class=comments>We've already stripped leading whitespace, and collapsed + consecutive spaces. Now we try to strip any collapsed trailing whitespace + (<a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=14119">bug 14119</a> + again). + + <p>If <var title="">fix collapsed space</var> is true, then while (<var title="">start + node</var>, <var title="">start offset</var>) is <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-bp-before title=concept-bp-before>before</a> (<var title="">end node</var>, + <var title="">end offset</var>): + + <ol> + <li>If <var title="">end 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> <a href=#in-the-same-editing-host>in the same editing + host</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="">end offset</var> − 1, set <var title="">end + node</var> to 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>, then set <var title="">end offset</var> to <var title="">end + 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>. + + <li>Otherwise, if <var title="">end offset</var> is zero and <var title="">end node</var>'s + <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is <a href=#in-the-same-editing-host>in the same editing host</a>, set <var title="">end + offset</var> to <var title="">end node</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a>, then set <var title="">end + node</var> to its <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>. + + <li>Otherwise, if <var title="">end node</var> is 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 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>'s <a href=http://dev.w3.org/csswg/cssom/#resolved-value>resolved value</a> for "white-space" is neither "pre" nor "pre-wrap" + and <var title="">end offset</var> is <var title="">end 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 the last + <a href=http://dev.w3.org/2006/webapi/WebIDL/#dfn-code-unit>code unit</a> of <var title="">end node</var>'s <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 a space (0x0020) and + <var title="">end node</var> <a href=#precedes-a-line-break>precedes a line break</a>: + + <ol> + <li>Subtract one from <var title="">end offset</var>. + + <li>Subtract one from <var title="">length</var>. + + <li>Call <code class=external data-anolis-spec=domcore title=dom-CharacterData-deleteData><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-deletedata>deleteData(<var title="">end offset</var>, 1)</a></code> on <var title="">end node</var>. + </ol> + + <li>Otherwise, break from this loop. + </ol> + + <li> <p class=comments>Finally we replace with the canonical sequence. <p>Let <var title="">replacement whitespace</var> be the <a href=#canonical-space-sequence>canonical space @@ -6845,8 +6896,8 @@ <p class=comments>Needed so that if there are multiple consecutive spaces we backspace over all at once. - <p><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at (<a href=#active-range>active range</a>'s - <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a>). + <p><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>. <li>Let <var title="">node</var> and <var title="">offset</var> be the <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a>. @@ -7578,8 +7629,8 @@ <li>If the <a href=#active-range>active range</a> is not <code class=external data-anolis-spec=domrange title=dom-Range-collapsed><a href=http://html5.org/specs/dom-range.html#dom-range-collapsed>collapsed</a></code>, <a href=#delete-the-selection>delete the selection</a> and abort these steps. - <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at (<a href=#active-range>active range</a>'s - <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a>, <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a>). + <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>. <li>Let <var title="">node</var> and <var title="">offset</var> be the <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>node</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offset</a>. @@ -8787,19 +8838,18 @@ 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 <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, set <var title="">node</var> to 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>, then set <var title="">offset</var> to zero. - <li> - <p class=comments><var title="">value</var> may change back to a space when we - canonicalize, even if this step is triggered. - - <p>If <var title="">value</var> is a space (U+0020), and either <var title="">node</var> is 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> whose <a href=http://dev.w3.org/csswg/cssom/#resolved-value>resolved value</a> for "white-space" is neither "pre" nor - "pre-wrap" or <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> 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 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> whose <a href=http://dev.w3.org/csswg/cssom/#resolved-value>resolved value</a> for "white-space" is neither "pre" nor - "pre-wrap", set <var title="">value</var> to a non-breaking space (U+00A0). - <li><a href=#record-current-overrides>Record current overrides</a>, and let <var title="">overrides</var> be the result. + <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>. + + <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at (<var title="">node</var>, + <var title="">offset</var>). + + <li>Let (<var title="">node</var>, <var title="">offset</var>) be the <a href=#active-range>active + range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>. + <li>If <var title="">node</var> is 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: <ol> @@ -8838,10 +8888,10 @@ <li><a href=#restore-states-and-values>Restore states and values</a> from <var title="">overrides</var>. <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s - <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>. + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a>, with <var title="">fix collapsed space</var> false. <li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s - <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>. + <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a>, with <var title="">fix collapsed space</var> false. <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapseToEnd><a href=http://html5.org/specs/dom-range.html#dom-selection-collapsetoend>collapseToEnd()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>. </ol>
--- a/implementation.js Thu Sep 22 13:53:40 2011 -0600 +++ b/implementation.js Thu Sep 22 14:03:58 2011 -0600 @@ -4373,6 +4373,12 @@ return; } + // "Canonicalize whitespace at the active range's start." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); + + // "Canonicalize whitespace at the active range's end." + canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset); + // "Let start node, start offset, end node, and end offset be the active // range's start and end nodes and offsets." var startNode = getActiveRange().startContainer; @@ -4560,8 +4566,9 @@ // node." startNode.deleteData(startOffset, endOffset - startOffset); - // "Canonicalize whitespace at (start node, start offset)." - canonicalizeWhitespace(startNode, startOffset); + // "Canonicalize whitespace at (start node, start offset), with fix + // collapsed space false." + canonicalizeWhitespace(startNode, startOffset, false); // "If direction is "forward", call collapseToStart() on the context // object's Selection." @@ -4646,11 +4653,13 @@ endNode.deleteData(0, endOffset); } - // "Canonicalize whitespace at the active range's start." - canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); - - // "Canonicalize whitespace at the active range's end." - canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset); + // "Canonicalize whitespace at the active range's start, with fix collapsed + // space false." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset, false); + + // "Canonicalize whitespace at the active range's end, with fix collapsed + // space false." + canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset, false); // "If block merging is false, or start block or end block is null, or // start block is not in the same editing host as end block, or start block @@ -5098,7 +5107,13 @@ return buffer; } -function canonicalizeWhitespace(node, offset) { +function canonicalizeWhitespace(node, offset, fixCollapsedSpace) { + if (fixCollapsedSpace === undefined) { + // "an optional boolean argument fix collapsed space that defaults to + // true" + fixCollapsedSpace = true; + } + // "If node is neither editable nor an editing host, abort these steps." if (!isEditable(node) && !isEditingHost(node)) { return; @@ -5152,8 +5167,9 @@ // "Let length equal zero." var length = 0; - // "Let follows space be false." - var followsSpace = false; + // "Let collapse spaces be true if start offset is zero and start node + // follows a line break, otherwise false." + var collapseSpaces = startOffset == 0 && followsLineBreak(startNode); // "Repeat the following steps:" while (true) { @@ -5182,18 +5198,20 @@ && ["pre", "pre-wrap"].indexOf(getComputedStyle(endNode.parentNode).whiteSpace) == -1 && endOffset != getNodeLength(endNode) && /[ \xa0]/.test(endNode.data[endOffset])) { - // "If follows space is true and the end offsetth element of end - // node's data is a space (0x0020), call deleteData(end offset, 1) - // on end node, then continue this loop from the beginning." - if (followsSpace + // "If fix collapsed space is true, and collapse spaces is true, + // and the end offsetth code unit of end node's data is a space + // (0x0020): call deleteData(end offset, 1) on end node, then + // continue this loop from the beginning." + if (fixCollapsedSpace + && collapseSpaces && " " == endNode.data[endOffset]) { endNode.deleteData(endOffset, 1); continue; } - // "Set follows space to true if the end offsetth element of end + // "Set collapse spaces to true if the end offsetth element of end // node's data is a space (0x0020), false otherwise." - followsSpace = " " == endNode.data[endOffset]; + collapseSpaces = " " == endNode.data[endOffset]; // "Add one to end offset." endOffset++; @@ -5207,6 +5225,52 @@ } } + // "If fix collapsed space is true, then while (start node, start offset) + // is before (end node, end offset):" + if (fixCollapsedSpace) { + while (getPosition(startNode, startOffset, endNode, endOffset) == "before") { + // "If end node has a child in the same editing host with index end + // offset − 1, set end node to that child, then set end offset to end + // node's length." + if (0 <= endOffset - 1 + && endOffset - 1 < endNode.childNodes.length + && inSameEditingHost(endNode, endNode.childNodes[endOffset - 1])) { + endNode = endNode.childNodes[endOffset - 1]; + endOffset = getNodeLength(endNode); + + // "Otherwise, if end offset is zero and end node's parent is in the + // same editing host, set end offset to end node's index, then set end + // node to its parent." + } else if (endOffset == 0 + && inSameEditingHost(endNode, endNode.parentNode)) { + endOffset = getNodeIndex(endNode); + endNode = endNode.parentNode; + + // "Otherwise, if end node is a Text node and its parent's resolved + // value for "white-space" is neither "pre" nor "pre-wrap" and end + // offset is end node's length and the last code unit of end node's + // data is a space (0x0020) and end node precedes a line break:" + } else if (endNode.nodeType == Node.TEXT_NODE + && ["pre", "pre-wrap"].indexOf(getComputedStyle(endNode.parentNode).whiteSpace) == -1 + && endOffset == getNodeLength(endNode) + && endNode.data[endNode.data.length - 1] == " " + && precedesLineBreak(endNode)) { + // "Subtract one from end offset." + endOffset--; + + // "Subtract one from length." + length--; + + // "Call deleteData(end offset, 1) on end node." + endNode.deleteData(endOffset, 1); + + // "Otherwise, break from this loop." + } else { + break; + } + } + } + // "Let replacement whitespace be the canonical space sequence of length // length. non-breaking start is true if start offset is zero and start // node follows a line break, and false otherwise. non-breaking end is true @@ -5886,8 +5950,7 @@ return; } - // "Canonicalize whitespace at (active range's start node, active - // range's start offset)." + // "Canonicalize whitespace at the active range's start." canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); // "Let node and offset be the active range's start node and offset." @@ -6498,8 +6561,7 @@ return; } - // "Canonicalize whitespace at (active range's start node, active - // range's start offset)." + // "Canonicalize whitespace at the active range's start." canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); // "Let node and offset be the active range's start node and offset." @@ -7506,21 +7568,21 @@ offset = 0; } - // "If value is a space (U+0020), and either node is an Element whose - // resolved value for "white-space" is neither "pre" nor "pre-wrap" or - // node is not an Element but its parent is an Element whose resolved - // value for "white-space" is neither "pre" nor "pre-wrap", set value - // to a non-breaking space (U+00A0)." - var refElement = node.nodeType == Node.ELEMENT_NODE ? node : node.parentNode; - if (value == " " - && refElement.nodeType == Node.ELEMENT_NODE - && ["pre", "pre-wrap"].indexOf(getComputedStyle(refElement).whiteSpace) == -1) { - value = "\xa0"; - } - // "Record current overrides, and let overrides be the result." var overrides = recordCurrentOverrides(); + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + getActiveRange().setEnd(node, offset); + + // "Canonicalize whitespace at (node, offset)." + canonicalizeWhitespace(node, offset); + + // "Let (node, offset) be the active range's start." + node = getActiveRange().startContainer; + offset = getActiveRange().startOffset; + // "If node is a Text node:" if (node.nodeType == Node.TEXT_NODE) { // "Call insertData(offset, value) on node." @@ -7532,7 +7594,10 @@ // "Call extend(node, offset + 1) on the context object's // Selection." - getSelection().extend(node, offset + 1); + // + // Work around WebKit bug: the extend() can throw if the text we're + // adding is trailing whitespace. + try { getSelection().extend(node, offset + 1); } catch(e) {} getActiveRange().setEnd(node, offset + 1); // "Otherwise:" @@ -7566,11 +7631,13 @@ // "Restore states and values from overrides." restoreStatesAndValues(overrides); - // "Canonicalize whitespace at the active range's start." - canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); - - // "Canonicalize whitespace at the active range's end." - canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset); + // "Canonicalize whitespace at the active range's start, with fix + // collapsed space false." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset, false); + + // "Canonicalize whitespace at the active range's end, with fix + // collapsed space false." + canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset, false); // "Call collapseToEnd() on the context object's Selection." getSelection().collapseToEnd();
--- a/source.html Thu Sep 22 13:53:40 2011 -0600 +++ b/source.html Thu Sep 22 14:03:58 2011 -0600 @@ -4693,6 +4693,12 @@ <li>If the <span>active range</span> is null, abort these steps and do nothing. + <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s + [[rangestart]]. + + <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s + [[rangeend]]. + <li>Let <var>start node</var>, <var>start offset</var>, <var>end node</var>, and <var>end offset</var> be the <span>active range</span>'s [[rangestart]] and [[rangeend]] [[bpnodes]] and [[bpoffsets]]. @@ -4913,7 +4919,7 @@ − <var>start offset</var>]] on <var>start node</var>. <li><span>Canonicalize whitespace</span> at (<var>start node</var>, - <var>start offset</var>). + <var>start offset</var>), with <var>fix collapsed space</var> false. <li>If <var>direction</var> is "forward", call [[collapsetostart]] on the [[contextobject]]'s [[selection]]. @@ -4989,10 +4995,10 @@ [[deletedata|0, <var>end offset</var>]] on it. <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s - [[rangestart]]. + [[rangestart]], with <var>fix collapsed space</var> false. <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s - [[rangeend]]. + [[rangeend]], with <var>fix collapsed space</var> false. <li> <div class=comments> @@ -5441,7 +5447,8 @@ </ol> <p>To <dfn>canonicalize whitespace</dfn> at (<var>node</var>, -<var>offset</var>): +<var>offset</var>), given an optional boolean argument <var>fix collapsed +space</var> that defaults to true: <ol> <li>If <var>node</var> is neither <span>editable</span> nor an <span>editing @@ -5482,14 +5489,20 @@ </ol> <li> - <p class=comments>Now we collapse any consecutive spaces. + <p class=comments>Now we collapse any consecutive spaces, if <var>fix + collapsed space</var> is true. <p>Let <var>end node</var> equal <var>start node</var> and <var>end offset</var> equal <var>start offset</var>. <li>Let <var>length</var> equal zero. - <li>Let <var>follows space</var> be false. + <li> + <p class=comments>This tries to delete spaces at the beginning of a line (<a + href=http://www.w3.org/Bugs/Public/show_bug.cgi?id=14119>bug 14119</a>). + + <p>Let <var>collapse spaces</var> be true if <var>start offset</var> is zero + and <var>start node</var> <span>follows a line break</span>, otherwise false. <li>Repeat the following steps: @@ -5516,14 +5529,15 @@ space (0x0020) or non-breaking space (0x00A0): <ol> - <li>If <var>follows space</var> is true and the <var>end offset</var>th - [[codeunit]] of <var>end node</var>'s [[cddata]] is a space (0x0020), call + <li>If <var>fix collapsed space</var> is true, and <var>collapse + spaces</var> is true, and the <var>end offset</var>th [[codeunit]] of + <var>end node</var>'s [[cddata]] is a space (0x0020): call [[deletedata|<var>end offset</var>, 1]] on <var>end node</var>, then continue this loop from the beginning. - <li>Set <var>follows space</var> to true if the <var>end offset</var>th - [[codeunit]] of <var>end node</var>'s [[cddata]] is a space (0x0020), false - otherwise. + <li>Set <var>collapse spaces</var> to true if the <var>end offset</var>th + [[codeunit]] of <var>end node</var>'s [[cddata]] is a space (0x0020), + false otherwise. <li>Add one to <var>end offset</var>. @@ -5534,6 +5548,44 @@ </ol> <li> + <p class=comments>We've already stripped leading whitespace, and collapsed + consecutive spaces. Now we try to strip any collapsed trailing whitespace + (<a href=http://www.w3.org/Bugs/Public/show_bug.cgi?id=14119>bug 14119</a> + again). + + <p>If <var>fix collapsed space</var> is true, then while (<var>start + node</var>, <var>start offset</var>) is [[bpbefore]] (<var>end node</var>, + <var>end offset</var>): + + <ol> + <li>If <var>end node</var> has a [[child]] <span>in the same editing + host</span> with [[index]] <var>end offset</var> − 1, set <var>end + node</var> to that [[child]], then set <var>end offset</var> to <var>end + node</var>'s [[length]]. + + <li>Otherwise, if <var>end offset</var> is zero and <var>end node</var>'s + [[parent]] is <span>in the same editing host</span>, set <var>end + offset</var> to <var>end node</var>'s [[index]], then set <var>end + node</var> to its [[parent]]. + + <li>Otherwise, if <var>end node</var> is a [[text]] node and its + [[parent]]'s [[resval]] for "white-space" is neither "pre" nor "pre-wrap" + and <var>end offset</var> is <var>end node</var>'s [[length]] and the last + [[codeunit]] of <var>end node</var>'s [[cddata]] is a space (0x0020) and + <var>end node</var> <span>precedes a line break</span>: + + <ol> + <li>Subtract one from <var>end offset</var>. + + <li>Subtract one from <var>length</var>. + + <li>Call [[deletedata|<var>end offset</var>, 1]] on <var>end node</var>. + </ol> + + <li>Otherwise, break from this loop. + </ol> + + <li> <p class=comments>Finally we replace with the canonical sequence. <p>Let <var>replacement whitespace</var> be the <span>canonical space @@ -6903,8 +6955,8 @@ <p class=comments>Needed so that if there are multiple consecutive spaces we backspace over all at once. - <p><span>Canonicalize whitespace</span> at (<span>active range</span>'s - [[startnode]], <span>active range</span>'s [[startoffset]]). + <p><span>Canonicalize whitespace</span> at the <span>active range</span>'s + [[rangestart]]. <li>Let <var>node</var> and <var>offset</var> be the <span>active range</span>'s [[rangestart]] [[bpnode]] and [[bpoffset]]. @@ -7643,8 +7695,8 @@ title=dom-Range-collapsed>collapsed</code>, <span>delete the selection</span> and abort these steps. - <li><span>Canonicalize whitespace</span> at (<span>active range</span>'s - [[startnode]], <span>active range</span>'s [[startoffset]]). + <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s + [[rangestart]]. <li>Let <var>node</var> and <var>offset</var> be the <span>active range</span>'s [[rangestart]] [[bpnode]] and [[bpoffset]]. @@ -8861,19 +8913,18 @@ and that [[child]] is a [[text]] node, set <var>node</var> to that [[child]], then set <var>offset</var> to zero. - <li> - <p class=comments><var>value</var> may change back to a space when we - canonicalize, even if this step is triggered. - - <p>If <var>value</var> is a space (U+0020), and either <var>node</var> is an - [[element]] whose [[resval]] for "white-space" is neither "pre" nor - "pre-wrap" or <var>node</var> is not an [[element]] but its [[parent]] is an - [[element]] whose [[resval]] for "white-space" is neither "pre" nor - "pre-wrap", set <var>value</var> to a non-breaking space (U+00A0). - <li><span>Record current overrides</span>, and let <var>overrides</var> be the result. + <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the + [[contextobject]]'s [[selection]]. + + <li><span>Canonicalize whitespace</span> at (<var>node</var>, + <var>offset</var>). + + <li>Let (<var>node</var>, <var>offset</var>) be the <span>active + range</span>'s [[rangestart]]. + <li>If <var>node</var> is a [[text]] node: <ol> @@ -8914,10 +8965,10 @@ <li><span>Restore states and values</span> from <var>overrides</var>. <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s - [[rangestart]]. + [[rangestart]], with <var>fix collapsed space</var> false. <li><span>Canonicalize whitespace</span> at the <span>active range</span>'s - [[rangeend]]. + [[rangeend]], with <var>fix collapsed space</var> false. <li>Call [[collapsetoend]] on the [[contextobject]]'s [[selection]]. </ol>