<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[164316] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/164316">164316</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2014-02-18 14:23:17 -0800 (Tue, 18 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>setSelectionRange should set selection without validation
https://bugs.webkit.org/show_bug.cgi?id=128949

Reviewed by Enrica Casucci.

Source/WebCore: 

Since positionForIndex in HTMLTextFormControlElement always returns a candidate Position, we don't have to
validate selection in setSelectionRange.

Also fixed various bugs uncovered by this change.

This patch also fixes fast/forms/input-select-webkit-user-select-none.html, which used to assert wrong outcome
so that WebKit's behavior matches that of Chrome and Firefox.

Test: fast/forms/input-select-webkit-user-select-none.html

* dom/Position.h:
(WebCore::positionInParentBeforeNode): This function had a bug that when node is a child of the shadow root
it would return a null Position. Allow a position anchored inside a shadow root.
(WebCore::positionInParentAfterNode): Ditto.

* editing/FrameSelection.cpp:
(WebCore::FrameSelection::moveWithoutValidationTo): Renamed from moveTo and avoided selection validation.
* editing/FrameSelection.h:

* editing/htmlediting.cpp:
(WebCore::updatePositionForNodeRemoval): Fixed the bug that this function doesn't update positions before
or after children even if the shadow host of the anchor node is getting removed. Move the position before
the shadow host to be removed in both situations.

* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::setSelectionRange): moveTo is renamed to moveWithoutValidationTo.
(WebCore::HTMLTextFormControlElement::selectionChanged): Check if the cached selection offsets are different
in lieu of FrameSelection::isRange() since they're equivalent here.
(WebCore::positionForIndex): Return the position inside or after the last br when there is one to match
the canonicalization algorithm we have. It's probably harmless to return the last position in the inner text
element anyways since most of our codebase supports that but this would avoid having to rebaseline dozens
of tests and reduces the risk of this patch.

LayoutTests: 

Fixed input-select-webkit-user-select-none.html which was erroneously asserting selectionStart and selectionEnd
of a text field to be zero when it has -webkit-user-select: none. This doesn't not match behaviors of Chrome
and Firefox. They both retain the programatically set selection offsets since such style should not bleed into
the shadow DOM of the text field in the first place.

New behavior matches the latest Firefox and Chrome although we still have the bug that user cannot select text
inside such a text field.

Also modernized LayoutTests/editing/selection/5497643.html to make the expected results more readable and made
the test more robust against changes in the node index of textarea element.

* editing/selection/5497643-expected.txt: See above.
* editing/selection/5497643.html:
* fast/forms/input-select-webkit-user-select-none-expected.txt: See above.
* fast/forms/input-select-webkit-user-select-none.html:
* editing/deleting/delete-ligature-001-expected.txt: Progression in the editing delegate callbacks dumps.
Now we set selection directly into the text node inside the inner text element.
* platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt: Ditto.
* platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt: Ditto.
* platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt:
Removed.
* platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt:
Removed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestseditingdeletingdeleteligature001expectedtxt">trunk/LayoutTests/editing/deleting/delete-ligature-001-expected.txt</a></li>
<li><a href="#trunkLayoutTestseditingselection5497643expectedtxt">trunk/LayoutTests/editing/selection/5497643-expected.txt</a></li>
<li><a href="#trunkLayoutTestseditingselection5497643html">trunk/LayoutTests/editing/selection/5497643.html</a></li>
<li><a href="#trunkLayoutTestsfastformsinputselectwebkituserselectnoneexpectedtxt">trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastformsinputselectwebkituserselectnonehtml">trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none.html</a></li>
<li><a href="#trunkLayoutTestsplatformmacplatformmaceditingspellingautocorrectionatbeginningofword1expectedtxt">trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacplatformmaceditingspellingautocorrectionatbeginningofword2expectedtxt">trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacmountainlionplatformmaceditingspellingautocorrectionatbeginningofword1expectedtxt">trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacmountainlionplatformmaceditingspellingautocorrectionatbeginningofword2expectedtxt">trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomPositionh">trunk/Source/WebCore/dom/Position.h</a></li>
<li><a href="#trunkSourceWebCoreeditingFrameSelectioncpp">trunk/Source/WebCore/editing/FrameSelection.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingFrameSelectionh">trunk/Source/WebCore/editing/FrameSelection.h</a></li>
<li><a href="#trunkSourceWebCoreeditinghtmleditingcpp">trunk/Source/WebCore/editing/htmlediting.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLTextFormControlElementcpp">trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/ChangeLog        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2014-02-18  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        setSelectionRange should set selection without validation
+        https://bugs.webkit.org/show_bug.cgi?id=128949
+
+        Reviewed by Enrica Casucci.
+
+        Fixed input-select-webkit-user-select-none.html which was erroneously asserting selectionStart and selectionEnd
+        of a text field to be zero when it has -webkit-user-select: none. This doesn't not match behaviors of Chrome
+        and Firefox. They both retain the programatically set selection offsets since such style should not bleed into
+        the shadow DOM of the text field in the first place.
+
+        New behavior matches the latest Firefox and Chrome although we still have the bug that user cannot select text
+        inside such a text field.
+
+        Also modernized LayoutTests/editing/selection/5497643.html to make the expected results more readable and made
+        the test more robust against changes in the node index of textarea element.
+
+        * editing/selection/5497643-expected.txt: See above.
+        * editing/selection/5497643.html:
+        * fast/forms/input-select-webkit-user-select-none-expected.txt: See above.
+        * fast/forms/input-select-webkit-user-select-none.html:
+        * editing/deleting/delete-ligature-001-expected.txt: Progression in the editing delegate callbacks dumps.
+        Now we set selection directly into the text node inside the inner text element.
+        * platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt: Ditto.
+        * platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt: Ditto.
+        * platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt:
+        Removed.
+        * platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt:
+        Removed.
+
</ins><span class="cx"> 2014-02-18  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Convert position:sticky to position:static upon copy and paste
</span></span></pre></div>
<a id="trunkLayoutTestseditingdeletingdeleteligature001expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/editing/deleting/delete-ligature-001-expected.txt (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/deleting/delete-ligature-001-expected.txt        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/editing/deleting/delete-ligature-001-expected.txt        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><del>-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; #document-fragment to 0 of DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</del><ins>+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</ins><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</span><span class="cx"> EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment toDOMRange:range from 2 of #text &gt; DIV &gt; #document-fragment to 2 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</span></span></pre></div>
<a id="trunkLayoutTestseditingselection5497643expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/editing/selection/5497643-expected.txt (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/selection/5497643-expected.txt        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/editing/selection/5497643-expected.txt        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,4 +1,10 @@
</span><del>-ALERT: SUCCESS: Selection is set to position 2 of BODY.
</del><ins>+textareaOffset = nodeIndex(textarea); textarea.setSelectionRange(0, 0); textarea.parentNode.removeChild(textarea);
+PASS getSelection().type is 'Caret'
+PASS getSelection().getRangeAt(0).startContainer is document.body
+PASS getSelection().getRangeAt(0).startOffset is textareaOffset
+PASS successfullyParsed is true
+
+TEST COMPLETE
</ins><span class="cx"> This tests to make sure that a selection inside a textarea is updated when the textarea is removed from the document.
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestseditingselection5497643html"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/editing/selection/5497643.html (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/selection/5497643.html        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/editing/selection/5497643.html        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,15 +1,22 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
</ins><span class="cx"> &lt;p&gt;This tests to make sure that a selection inside a textarea is updated when the textarea is removed from the document.&lt;/p&gt;
</span><span class="cx"> &lt;textarea id=&quot;textarea&quot;&gt;&lt;/textarea&gt;
</span><ins>+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> &lt;script&gt;
</span><span class="cx"> if (window.testRunner)
</span><span class="cx">     window.testRunner.dumpAsText();
</span><ins>+function nodeIndex(node) {
+    return Array.prototype.slice.call(node.parentNode.childNodes).indexOf(node);
+}
</ins><span class="cx"> textarea = document.getElementById(&quot;textarea&quot;);
</span><del>-textarea.setSelectionRange(0, 0);
-textarea.parentNode.removeChild(textarea);
-if (window.getSelection().type == 'Caret' &amp;&amp;
-    window.getSelection().getRangeAt(0).startContainer == document.body &amp;&amp; 
-    window.getSelection().getRangeAt(0).startOffset == 2)
-    alert(&quot;SUCCESS: Selection is set to position 2 of BODY.&quot;)
-else
-    alert(&quot;FAILURE: The selection is not set correctly after textarea was deleted.&quot;)
</del><ins>+evalAndLog(&quot;textareaOffset = nodeIndex(textarea); textarea.setSelectionRange(0, 0); textarea.parentNode.removeChild(textarea);&quot;);
+shouldBe(&quot;getSelection().type&quot;, &quot;'Caret'&quot;);
+shouldBe(&quot;getSelection().getRangeAt(0).startContainer&quot;, &quot;document.body&quot;);
+shouldBe(&quot;getSelection().getRangeAt(0).startOffset&quot;, &quot;textareaOffset&quot;);
+var successfullyParsed = true;
</ins><span class="cx"> &lt;/script&gt;
</span><ins>+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastformsinputselectwebkituserselectnoneexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none-expected.txt (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none-expected.txt        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none-expected.txt        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,5 +1,12 @@
</span><span class="cx"> Tests behavior of select() in case &quot;-webkit-user-select: none&quot; attribute is specified to the input element. The field should not be selected.
</span><span class="cx"> 
</span><ins>+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-PASS
</del><ins>+PASS input.select(); input.selectionStart is 0
+PASS input.selectionEnd is input.value.length
+PASS input.value.length is not 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastformsinputselectwebkituserselectnonehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none.html (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none.html        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/fast/forms/input-select-webkit-user-select-none.html        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,26 +1,25 @@
</span><ins>+&lt;!DOCTYPE html&gt;
</ins><span class="cx"> &lt;html&gt;
</span><del>-&lt;head&gt;
</del><ins>+&lt;body onload=&quot;test()&quot;&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> &lt;script&gt;
</span><ins>+description(&quot;Tests behavior of select() in case &amp;quot;-webkit-user-select: none&amp;quot;&quot;
+    + &quot; attribute is specified to the input element. The field should not be selected.&quot;);
+
</ins><span class="cx"> function test() {
</span><span class="cx">     if (window.testRunner)
</span><span class="cx">         testRunner.dumpAsText();
</span><del>-    var tf = document.getElementById('tf');
-    tf.select();
-    if (tf.selectionStart == 0 &amp;&amp; tf.selectionEnd == 0) { // ;
-        document.getElementById(&quot;result&quot;).innerHTML = &quot;PASS&quot;;
-    } else {
-        document.getElementById(&quot;result&quot;).innerHTML = &quot;FAIL: selection start is &quot;
-            + tf.selectionStart + &quot; and end is &quot; + tf.selectionEnd + &quot;.&quot;;
-    }
</del><ins>+    window.input = document.querySelector('input');
+    shouldBe(&quot;input.select(); input.selectionStart&quot;, &quot;0&quot;);
+    shouldBe(&quot;input.selectionEnd&quot;, &quot;input.value.length&quot;);
+    shouldNotBe(&quot;input.value.length&quot;, &quot;0&quot;);
+    finishJSTest();
</ins><span class="cx"> }
</span><ins>+
+var successfullyParsed = true;
+var jsTestIsAsync = true;
</ins><span class="cx"> &lt;/script&gt;
</span><del>-&lt;/head&gt;
-&lt;body onload=&quot;test()&quot;&gt;
-&lt;p&gt;
-Tests behavior of select() in case &amp;quot;-webkit-user-select: none&amp;quot;
-attribute is specified to the input element. The field should not be selected.
-&lt;/p&gt;
-&lt;p&gt;&lt;input type=&quot;text&quot; id=&quot;tf&quot; value=&quot;input text&quot; style=&quot;-webkit-user-select: none&quot;&gt;&lt;/input&gt;&lt;/p&gt;
-&lt;p id=&quot;result&quot;&gt;TEST NOT RUN YET&lt;/p&gt;
</del><ins>+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;p&gt;&lt;input type=&quot;text&quot; value=&quot;input text&quot; style=&quot;-webkit-user-select: none; -moz-user-select: none;&quot;&gt;&lt;/input&gt;&lt;/p&gt;
</ins><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacplatformmaceditingspellingautocorrectionatbeginningofword1expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><del>-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; #document-fragment to 0 of DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</del><ins>+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</ins><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacplatformmaceditingspellingautocorrectionatbeginningofword2expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/platform/mac/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><del>-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; #document-fragment to 0 of DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</del><ins>+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</ins><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacmountainlionplatformmaceditingspellingautocorrectionatbeginningofword1expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-1-expected.txt        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><del>-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; #document-fragment to 0 of DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</del><ins>+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</ins><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacmountainlionplatformmaceditingspellingautocorrectionatbeginningofword2expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/LayoutTests/platform/mac-mountainlion/platform/mac/editing/spelling/autocorrection-at-beginning-of-word-2-expected.txt        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><del>-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; #document-fragment to 0 of DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</del><ins>+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment toDOMRange:range from 1 of #text &gt; DIV &gt; #document-fragment to 1 of #text &gt; DIV &gt; #document-fragment affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</ins><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/Source/WebCore/ChangeLog        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2014-02-18  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        setSelectionRange should set selection without validation
+        https://bugs.webkit.org/show_bug.cgi?id=128949
+
+        Reviewed by Enrica Casucci.
+
+        Since positionForIndex in HTMLTextFormControlElement always returns a candidate Position, we don't have to
+        validate selection in setSelectionRange.
+
+        Also fixed various bugs uncovered by this change.
+
+        This patch also fixes fast/forms/input-select-webkit-user-select-none.html, which used to assert wrong outcome
+        so that WebKit's behavior matches that of Chrome and Firefox.
+
+        Test: fast/forms/input-select-webkit-user-select-none.html
+
+        * dom/Position.h:
+        (WebCore::positionInParentBeforeNode): This function had a bug that when node is a child of the shadow root
+        it would return a null Position. Allow a position anchored inside a shadow root.
+        (WebCore::positionInParentAfterNode): Ditto.
+
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::moveWithoutValidationTo): Renamed from moveTo and avoided selection validation.
+        * editing/FrameSelection.h:
+
+        * editing/htmlediting.cpp:
+        (WebCore::updatePositionForNodeRemoval): Fixed the bug that this function doesn't update positions before
+        or after children even if the shadow host of the anchor node is getting removed. Move the position before
+        the shadow host to be removed in both situations.
+
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::setSelectionRange): moveTo is renamed to moveWithoutValidationTo.
+        (WebCore::HTMLTextFormControlElement::selectionChanged): Check if the cached selection offsets are different
+        in lieu of FrameSelection::isRange() since they're equivalent here.
+        (WebCore::positionForIndex): Return the position inside or after the last br when there is one to match
+        the canonicalization algorithm we have. It's probably harmless to return the last position in the inner text
+        element anyways since most of our codebase supports that but this would avoid having to rebaseline dozens
+        of tests and reduces the risk of this patch.
+
</ins><span class="cx"> 2014-02-18  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move IndexedDB module, LevelDB code to std::unique_ptr
</span></span></pre></div>
<a id="trunkSourceWebCoredomPositionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Position.h (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Position.h        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/Source/WebCore/dom/Position.h        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -272,17 +272,14 @@
</span><span class="cx"> 
</span><span class="cx"> inline Position positionInParentBeforeNode(const Node* node)
</span><span class="cx"> {
</span><del>-    // FIXME: This should ASSERT(node-&gt;parentNode())
-    // At least one caller currently hits this ASSERT though, which indicates
-    // that the caller is trying to make a position relative to a disconnected node (which is likely an error)
-    // Specifically, editing/deleting/delete-ligature-001.html crashes with ASSERT(node-&gt;parentNode())
-    return Position(Position::findParent(node), node-&gt;nodeIndex(), Position::PositionIsOffsetInAnchor);
</del><ins>+    ASSERT(node-&gt;parentNode());
+    return Position(node-&gt;parentNode(), node-&gt;nodeIndex(), Position::PositionIsOffsetInAnchor);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline Position positionInParentAfterNode(const Node* node)
</span><span class="cx"> {
</span><del>-    ASSERT(Position::findParent(node));
-    return Position(Position::findParent(node), node-&gt;nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
</del><ins>+    ASSERT(node-&gt;parentNode());
+    return Position(node-&gt;parentNode(), node-&gt;nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // positionBeforeNode and positionAfterNode return neighbor-anchored positions, construction is O(1)
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingFrameSelectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/FrameSelection.cpp        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -164,10 +164,12 @@
</span><span class="cx">     setSelection(VisibleSelection(base, extent, affinity, selectionHasDirection), defaultSetSelectionOptions(userTriggered));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void FrameSelection::moveTo(const Position&amp; base, const Position&amp; extent, bool selectionHasDirection, bool shouldSetFocus)
</del><ins>+void FrameSelection::moveWithoutValidationTo(const Position&amp; base, const Position&amp; extent, bool selectionHasDirection, bool shouldSetFocus)
</ins><span class="cx"> {
</span><del>-    setSelection(VisibleSelection(base, extent, DOWNSTREAM, selectionHasDirection),
-        defaultSetSelectionOptions() | (shouldSetFocus ? 0 : DoNotSetFocus));
</del><ins>+    VisibleSelection newSelection;
+    newSelection.setWithoutValidation(base, extent);
+    newSelection.setIsDirectional(selectionHasDirection);
+    setSelection(newSelection, defaultSetSelectionOptions() | (shouldSetFocus ? 0 : DoNotSetFocus));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DragCaretController::setCaretPosition(const VisiblePosition&amp; position)
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingFrameSelectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/FrameSelection.h (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/FrameSelection.h        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/Source/WebCore/editing/FrameSelection.h        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -140,7 +140,7 @@
</span><span class="cx">     void moveTo(const VisiblePosition&amp;, const VisiblePosition&amp;, EUserTriggered = NotUserTriggered);
</span><span class="cx">     void moveTo(const Position&amp;, EAffinity, EUserTriggered = NotUserTriggered);
</span><span class="cx">     void moveTo(const Position&amp;, const Position&amp;, EAffinity, EUserTriggered = NotUserTriggered);
</span><del>-    void moveTo(const Position&amp;, const Position&amp;, bool selectionHasDirection, bool shouldSetFocus);
</del><ins>+    void moveWithoutValidationTo(const Position&amp;, const Position&amp;, bool selectionHasDirection, bool shouldSetFocus);
</ins><span class="cx"> 
</span><span class="cx">     const VisibleSelection&amp; selection() const { return m_selection; }
</span><span class="cx">     void setSelection(const VisibleSelection&amp;, SetSelectionOptions = defaultSetSelectionOptions(), CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity);
</span></span></pre></div>
<a id="trunkSourceWebCoreeditinghtmleditingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/htmlediting.cpp (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/htmlediting.cpp        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/Source/WebCore/editing/htmlediting.cpp        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -988,12 +988,12 @@
</span><span class="cx">         return;
</span><span class="cx">     switch (position.anchorType()) {
</span><span class="cx">     case Position::PositionIsBeforeChildren:
</span><del>-        if (position.containerNode() == node)
</del><ins>+        if (node-&gt;containsIncludingShadowDOM(position.containerNode()))
</ins><span class="cx">             position = positionInParentBeforeNode(node);
</span><span class="cx">         break;
</span><span class="cx">     case Position::PositionIsAfterChildren:
</span><del>-        if (position.containerNode() == node)
-            position = positionInParentAfterNode(node);
</del><ins>+        if (node-&gt;containsIncludingShadowDOM(position.containerNode()))
+            position = positionInParentBeforeNode(node);
</ins><span class="cx">         break;
</span><span class="cx">     case Position::PositionIsOffsetInAnchor:
</span><span class="cx">         if (position.containerNode() == node-&gt;parentNode() &amp;&amp; static_cast&lt;unsigned&gt;(position.offsetInContainerNode()) &gt; node-&gt;nodeIndex())
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLTextFormControlElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp (164315 => 164316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp        2014-02-18 22:23:13 UTC (rev 164315)
+++ trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp        2014-02-18 22:23:17 UTC (rev 164316)
</span><span class="lines">@@ -315,7 +315,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (Frame* frame = document().frame())
</span><del>-        frame-&gt;selection().moveTo(startPosition, endPosition, direction != SelectionHasNoDirection, !hasFocus);
</del><ins>+        frame-&gt;selection().moveWithoutValidationTo(startPosition, endPosition, direction != SelectionHasNoDirection, !hasFocus);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition&amp; position) const
</span><span class="lines">@@ -480,13 +480,8 @@
</span><span class="cx">     // selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus
</span><span class="cx">     cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelectionDirection());
</span><span class="cx">     
</span><del>-    if (!shouldFireSelectEvent)
-        return;
-
-    if (Frame* frame = document().frame()) {
-        if (frame-&gt;selection().isRange())
-            dispatchEvent(Event::create(eventNames().selectEvent, true, false));
-    }
</del><ins>+    if (shouldFireSelectEvent &amp;&amp; m_cachedSelectionStart != m_cachedSelectionEnd)
+        dispatchEvent(Event::create(eventNames().selectEvent, true, false));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLTextFormControlElement::parseAttribute(const QualifiedName&amp; name, const AtomicString&amp; value)
</span><span class="lines">@@ -556,19 +551,22 @@
</span><span class="cx"> static Position positionForIndex(TextControlInnerTextElement* innerText, unsigned index)
</span><span class="cx"> {
</span><span class="cx">     unsigned remainingCharactersToMoveForward = index;
</span><ins>+    Node* lastBrOrText = innerText;
</ins><span class="cx">     for (Node* node = innerText; node; node = NodeTraversal::next(node, innerText)) {
</span><span class="cx">         if (node-&gt;hasTagName(brTag)) {
</span><span class="cx">             if (!remainingCharactersToMoveForward)
</span><span class="cx">                 return positionBeforeNode(node);
</span><span class="cx">             remainingCharactersToMoveForward--;
</span><ins>+            lastBrOrText = node;
</ins><span class="cx">         } else if (node-&gt;isTextNode()) {
</span><span class="cx">             Text&amp; text = toText(*node);
</span><span class="cx">             if (remainingCharactersToMoveForward &lt; text.length())
</span><span class="cx">                 return Position(&amp;text, remainingCharactersToMoveForward);
</span><span class="cx">             remainingCharactersToMoveForward -= text.length();
</span><ins>+            lastBrOrText = node;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><del>-    return lastPositionInNode(innerText);
</del><ins>+    return lastPositionInOrAfterNode(lastBrOrText);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned HTMLTextFormControlElement::indexForPosition(const Position&amp; passedPosition) const
</span></span></pre>
</div>
</div>

</body>
</html>