<!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>[205044] 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/205044">205044</a></dd>
<dt>Author</dt> <dd>bdakin@apple.com</dd>
<dt>Date</dt> <dd>2016-08-26 14:11:55 -0700 (Fri, 26 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>charactersAroundPosition can be wrong because it crosses editing boundaries
https://bugs.webkit.org/show_bug.cgi?id=161215
-and corresponding-
rdar://problem/27933564

Reviewed by Ryosuke Niwa.

Source/WebCore:

charactersAroundPosition() should not cross editing boundaries. This patch fixes 
that by making nextCharacterBoundaryInDirection() take an 
EditingBoundaryCrossingRule parameter to pass onto VisiblePosition::next() and 
VisiblePosition::previous().

* editing/VisibleUnits.cpp:
(WebCore::nextCharacterBoundaryInDirection):
(WebCore::positionOfNextBoundaryOfGranularity):
(WebCore::charactersAroundPosition):

LayoutTests:

New test.
* editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt: Added.
* editing/mac/spelling/accept-candidate-without-crossing-editing-boundary.html: Added.

This test is going back to its pre-https://trac.webkit.org/changeset/195078 state. 
That change caused this test to have a different layout because it caused more 
layouts to happen. Now that we don’t allow the call to charactersAroundPosition() 
to cross editing boundaries, those layouts don’t happen, and we have the old 
behavior back.
* platform/mac/fast/dom/focus-contenteditable-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacfastdomfocuscontenteditableexpectedtxt">trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreeditingVisibleUnitscpp">trunk/Source/WebCore/editing/VisibleUnits.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestseditingmacspellingacceptcandidatewithoutcrossingeditingboundaryexpectedtxt">trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt</a></li>
<li><a href="#trunkLayoutTestseditingmacspellingacceptcandidatewithoutcrossingeditingboundaryhtml">trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (205043 => 205044)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-08-26 20:59:16 UTC (rev 205043)
+++ trunk/LayoutTests/ChangeLog        2016-08-26 21:11:55 UTC (rev 205044)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-08-26  Beth Dakin  &lt;bdakin@apple.com&gt;
+
+        charactersAroundPosition can be wrong because it crosses editing boundaries
+        https://bugs.webkit.org/show_bug.cgi?id=161215
+        -and corresponding-
+        rdar://problem/27933564
+
+        Reviewed by Ryosuke Niwa.
+
+        New test.
+        * editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt: Added.
+        * editing/mac/spelling/accept-candidate-without-crossing-editing-boundary.html: Added.
+
+        This test is going back to its pre-https://trac.webkit.org/changeset/195078 state. 
+        That change caused this test to have a different layout because it caused more 
+        layouts to happen. Now that we don’t allow the call to charactersAroundPosition() 
+        to cross editing boundaries, those layouts don’t happen, and we have the old 
+        behavior back.
+        * platform/mac/fast/dom/focus-contenteditable-expected.txt:
+
</ins><span class="cx"> 2016-08-26  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Test and address issues in IndexedDB.requestData
</span></span></pre></div>
<a id="trunkLayoutTestseditingmacspellingacceptcandidatewithoutcrossingeditingboundaryexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt (0 => 205044)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt                                (rev 0)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt        2016-08-26 21:11:55 UTC (rev 205044)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 1 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 1 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 1 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 2 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 2 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldInsertText:happy replacingDOMRange:range from 0 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 2 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 5 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 5 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldInsertText:  replacingDOMRange:range from 5 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 5 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 5 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 5 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 6 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document to 6 of #text &gt; DIV &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This test verifies that accepted candidates replace the text before the caret.
+
+happy 
+
+
</ins></span></pre></div>
<a id="trunkLayoutTestseditingmacspellingacceptcandidatewithoutcrossingeditingboundaryhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary.html (0 => 205044)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary.html                                (rev 0)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary.html        2016-08-26 21:11:55 UTC (rev 205044)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=../../editing.js&gt;&lt;/script&gt;
+&lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+function editingTest() {
+    edit = document.getElementById('edit');
+    edit.focus();
+    typeCharacterCommand('h');
+    typeCharacterCommand('a');
+    if (window.internals)
+        internals.handleAcceptedCandidate(&quot;happy&quot;);
+
+    if (window.testRunner)
+        testRunner.dumpAsText(true);
+}
+
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p&gt;This test verifies that accepted candidates replace the text before the caret.&lt;/p&gt;
+&lt;div style=&quot;border:1px solid black;&quot;&gt;
+    &lt;div contenteditable=&quot;true&quot; id=&quot;edit&quot;&gt;&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;visibility:hidden;&quot;&gt;
+    &lt;br&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;width: 1px; height: 1px;&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+runEditingTest();
+&lt;/script&gt;
+&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="trunkLayoutTestsplatformmacfastdomfocuscontenteditableexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt (205043 => 205044)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt        2016-08-26 20:59:16 UTC (rev 205043)
+++ trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt        2016-08-26 21:11:55 UTC (rev 205044)
</span><span class="lines">@@ -6,7 +6,7 @@
</span><span class="cx">       RenderBlock (anonymous) at (0,0) size 769x36
</span><span class="cx">         RenderText {#text} at (0,0) size 509x18
</span><span class="cx">           text run at (0,0) width 509: &quot;This test will try to call focus() on a contenteditable div, and then a normal div. &quot;
</span><del>-        RenderBR {BR} at (0,0) size 0x0
</del><ins>+        RenderBR {BR} at (508,14) size 1x0
</ins><span class="cx">         RenderText {#text} at (0,18) size 379x18
</span><span class="cx">           text run at (0,18) width 379: &quot;The window should scroll to reveal the contenteditable div.&quot;
</span><span class="cx">       RenderBlock {DIV} at (0,36) size 500x800
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (205043 => 205044)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-08-26 20:59:16 UTC (rev 205043)
+++ trunk/Source/WebCore/ChangeLog        2016-08-26 21:11:55 UTC (rev 205044)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2016-08-26  Beth Dakin  &lt;bdakin@apple.com&gt;
+
+        charactersAroundPosition can be wrong because it crosses editing boundaries
+        https://bugs.webkit.org/show_bug.cgi?id=161215
+        -and corresponding-
+        rdar://problem/27933564
+
+        Reviewed by Ryosuke Niwa.
+
+        charactersAroundPosition() should not cross editing boundaries. This patch fixes 
+        that by making nextCharacterBoundaryInDirection() take an 
+        EditingBoundaryCrossingRule parameter to pass onto VisiblePosition::next() and 
+        VisiblePosition::previous().
+
+        * editing/VisibleUnits.cpp:
+        (WebCore::nextCharacterBoundaryInDirection):
+        (WebCore::positionOfNextBoundaryOfGranularity):
+        (WebCore::charactersAroundPosition):
+
</ins><span class="cx"> 2016-08-26  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Test and address issues in IndexedDB.requestData
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingVisibleUnitscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/VisibleUnits.cpp (205043 => 205044)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/VisibleUnits.cpp        2016-08-26 20:59:16 UTC (rev 205043)
+++ trunk/Source/WebCore/editing/VisibleUnits.cpp        2016-08-26 21:11:55 UTC (rev 205044)
</span><span class="lines">@@ -1637,9 +1637,9 @@
</span><span class="cx">     return (prevBoundary &lt; vp &amp;&amp; vp &lt; nextBoundary);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static VisiblePosition nextCharacterBoundaryInDirection(const VisiblePosition&amp; vp, SelectionDirection direction)
</del><ins>+static VisiblePosition nextCharacterBoundaryInDirection(const VisiblePosition&amp; vp, SelectionDirection direction, EditingBoundaryCrossingRule rule)
</ins><span class="cx"> {
</span><del>-    return directionIsDownstream(direction) ? vp.next() : vp.previous();
</del><ins>+    return directionIsDownstream(direction) ? vp.next(rule) : vp.previous(rule);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static VisiblePosition nextWordBoundaryInDirection(const VisiblePosition&amp; vp, SelectionDirection direction)
</span><span class="lines">@@ -1779,7 +1779,7 @@
</span><span class="cx"> {
</span><span class="cx">     switch (granularity) {
</span><span class="cx">     case CharacterGranularity:
</span><del>-        return nextCharacterBoundaryInDirection(vp, direction);
</del><ins>+        return nextCharacterBoundaryInDirection(vp, direction, CanCrossEditingBoundary);
</ins><span class="cx">     case WordGranularity:
</span><span class="cx">         return nextWordBoundaryInDirection(vp, direction);
</span><span class="cx">     case SentenceGranularity:
</span><span class="lines">@@ -1891,14 +1891,14 @@
</span><span class="cx">     VisiblePosition startPosition = position;
</span><span class="cx">     VisiblePosition endPosition = position;
</span><span class="cx"> 
</span><del>-    VisiblePosition nextPosition = nextCharacterBoundaryInDirection(position, DirectionForward);
</del><ins>+    VisiblePosition nextPosition = nextCharacterBoundaryInDirection(position, DirectionForward, CannotCrossEditingBoundary);
</ins><span class="cx">     if (nextPosition.isNotNull())
</span><span class="cx">         endPosition = nextPosition;
</span><span class="cx"> 
</span><del>-    VisiblePosition previousPosition = nextCharacterBoundaryInDirection(position, DirectionBackward);
</del><ins>+    VisiblePosition previousPosition = nextCharacterBoundaryInDirection(position, DirectionBackward, CannotCrossEditingBoundary);
</ins><span class="cx">     if (previousPosition.isNotNull()) {
</span><span class="cx">         startPosition = previousPosition;
</span><del>-        previousPosition = nextCharacterBoundaryInDirection(previousPosition, DirectionBackward);
</del><ins>+        previousPosition = nextCharacterBoundaryInDirection(previousPosition, DirectionBackward, CannotCrossEditingBoundary);
</ins><span class="cx">         if (previousPosition.isNotNull())
</span><span class="cx">             startPosition = previousPosition;
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>