<!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>[205768] 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/205768">205768</a></dd>
<dt>Author</dt> <dd>achristensen@apple.com</dd>
<dt>Date</dt> <dd>2016-09-09 14:29:47 -0700 (Fri, 09 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>
Source/WebCore:
Text replacement candidates don't always overwrite the entire original string
https://bugs.webkit.org/show_bug.cgi?id=161779
&lt;rdar://problem/28033492&gt;

Patch by Tim Horton &lt;timothy_horton@apple.com&gt; on 2016-09-09
Reviewed by Simon Fraser.

New test: editing/mac/spelling/accept-candidate-replacing-multiple-words.html.

* editing/Editor.cpp:
(WebCore::Editor::contextRangeForCandidateRequest):
Factor contextRangeForCandidateRequest out of the WebKits, into Editor.
This just expands to paragraph boundaries from the cursor.

(WebCore::Editor::selectTextCheckingResult):
Add selectTextCheckingResult, which, given a TextCheckingResult,
selects the range represented by the result's location and length, which
indicate the portion of the context string that the result refers to.
In the case of accepting a candidate, we want to select that range
so that our insertion will overwrite it.

(WebCore::Editor::handleAcceptedCandidate):
Make use of selectTextCheckingResult instead of just assuming that we want
to replace the word to the left of the insertion point.

(WebCore::Editor::stringForCandidateRequest): Deleted.
* editing/Editor.h:

* testing/Internals.cpp:
(WebCore::Internals::handleAcceptedCandidate):
* testing/Internals.h:
* testing/Internals.idl:
Internals' handleAcceptedCandidate assumed (wrongly) that the length
of a TextCheckerResult was the length of the candidate, when really it is
the length of the text that the candidate would replace. Adjust this,
and expose the replacement range to JavaScript, so we can test this.

Tools:
URLParser: Fix and optimize parsing file URLs ending with a host but no slash
https://bugs.webkit.org/show_bug.cgi?id=161815

Reviewed by Geoffrey Garen.

* TestWebKitAPI/Tests/WebCore/URLParser.cpp:
(TestWebKitAPI::TEST_F):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformURLParsercpp">trunk/Source/WebCore/platform/URLParser.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebCoreURLParsercpp">trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (205767 => 205768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-09 21:20:02 UTC (rev 205767)
+++ trunk/Source/WebCore/ChangeLog        2016-09-09 21:29:47 UTC (rev 205768)
</span><span class="lines">@@ -66,6 +66,20 @@
</span><span class="cx"> 
</span><span class="cx"> 2016-09-09  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><ins>+        URLParser: Fix and optimize parsing file URLs ending with a host but no slash
+        https://bugs.webkit.org/show_bug.cgi?id=161815
+
+        Reviewed by Geoffrey Garen.
+
+        Covered by new API tests.
+
+        * platform/URLParser.cpp:
+        (WebCore::bufferView):
+        (WebCore::URLParser::copyURLPartsUntil):
+        (WebCore::URLParser::parse):
+
+2016-09-09  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
</ins><span class="cx">         URLParser: Handle \ in path according to spec
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=161805
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformURLParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/URLParser.cpp (205767 => 205768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/URLParser.cpp        2016-09-09 21:20:02 UTC (rev 205767)
+++ trunk/Source/WebCore/platform/URLParser.cpp        2016-09-09 21:29:47 UTC (rev 205768)
</span><span class="lines">@@ -150,12 +150,12 @@
</span><span class="cx">         || scheme == &quot;wss&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static StringView bufferView(const StringBuilder&amp; builder, unsigned length)
</del><ins>+static StringView bufferView(const StringBuilder&amp; builder, unsigned start, unsigned length)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(builder.length() &gt;= length);
</span><span class="cx">     if (builder.is8Bit())
</span><del>-        return StringView(builder.characters8(), length);
-    return StringView(builder.characters16(), length);
</del><ins>+        return StringView(builder.characters8() + start, length);
+    return StringView(builder.characters16() + start, length);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> enum class URLParser::URLPart {
</span><span class="lines">@@ -236,7 +236,7 @@
</span><span class="cx">         m_url.m_protocolIsInHTTPFamily = base.m_protocolIsInHTTPFamily;
</span><span class="cx">         m_url.m_schemeEnd = base.m_schemeEnd;
</span><span class="cx">     }
</span><del>-    m_urlIsSpecial = isSpecialScheme(bufferView(m_buffer, m_url.m_schemeEnd));
</del><ins>+    m_urlIsSpecial = isSpecialScheme(bufferView(m_buffer, 0, m_url.m_schemeEnd));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static const char* dotASCIICode = &quot;2e&quot;;
</span><span class="lines">@@ -444,7 +444,7 @@
</span><span class="cx">                 m_buffer.append(toASCIILower(*c));
</span><span class="cx">             else if (*c == ':') {
</span><span class="cx">                 m_url.m_schemeEnd = m_buffer.length();
</span><del>-                StringView urlScheme = bufferView(m_buffer, m_url.m_schemeEnd);
</del><ins>+                StringView urlScheme = bufferView(m_buffer, 0, m_url.m_schemeEnd);
</ins><span class="cx">                 m_url.m_protocolIsInHTTPFamily = urlScheme == &quot;http&quot; || urlScheme == &quot;https&quot;;
</span><span class="cx">                 if (urlScheme == &quot;file&quot;) {
</span><span class="cx">                     m_urlIsSpecial = true;
</span><span class="lines">@@ -761,8 +761,7 @@
</span><span class="cx">                 if (!parseHost(authorityOrHostBegin, c))
</span><span class="cx">                     return failure(input);
</span><span class="cx">                 
</span><del>-                // FIXME: Don't allocate a new string for this comparison.
-                if (m_buffer.toString().substring(m_url.m_passwordEnd) == &quot;localhost&quot;)  {
</del><ins>+                if (bufferView(m_buffer, m_url.m_passwordEnd, m_buffer.length() - m_url.m_passwordEnd) == &quot;localhost&quot;)  {
</ins><span class="cx">                     m_buffer.resize(m_url.m_passwordEnd);
</span><span class="cx">                     m_url.m_hostEnd = m_buffer.length();
</span><span class="cx">                     m_url.m_portEnd = m_url.m_hostEnd;
</span><span class="lines">@@ -954,24 +953,19 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        m_url.m_pathAfterLastSlash = m_url.m_userStart + 1;
-        m_url.m_pathEnd = m_url.m_pathAfterLastSlash;
-        m_url.m_queryEnd = m_url.m_pathAfterLastSlash;
-        m_url.m_fragmentEnd = m_url.m_pathAfterLastSlash;
</del><span class="cx">         if (!parseHost(authorityOrHostBegin, c))
</span><span class="cx">             return failure(input);
</span><span class="cx">         
</span><del>-        // FIXME: Don't allocate a new string for this comparison.
-        if (m_buffer.toString().substring(m_url.m_passwordEnd) == &quot;localhost&quot;)  {
</del><ins>+        if (bufferView(m_buffer, m_url.m_passwordEnd, m_buffer.length() - m_url.m_passwordEnd) == &quot;localhost&quot;)  {
</ins><span class="cx">             m_buffer.resize(m_url.m_passwordEnd);
</span><span class="cx">             m_url.m_hostEnd = m_buffer.length();
</span><span class="cx">             m_url.m_portEnd = m_url.m_hostEnd;
</span><del>-            m_buffer.append('/');
-            m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 1;
-            m_url.m_pathEnd = m_url.m_pathAfterLastSlash;
-            m_url.m_queryEnd = m_url.m_pathAfterLastSlash;
-            m_url.m_fragmentEnd = m_url.m_pathAfterLastSlash;
</del><span class="cx">         }
</span><ins>+        m_buffer.append('/');
+        m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 1;
+        m_url.m_pathEnd = m_url.m_pathAfterLastSlash;
+        m_url.m_queryEnd = m_url.m_pathAfterLastSlash;
+        m_url.m_fragmentEnd = m_url.m_pathAfterLastSlash;
</ins><span class="cx">         break;
</span><span class="cx">     case State::PathStart:
</span><span class="cx">         LOG_FINAL_STATE(&quot;PathStart&quot;);
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (205767 => 205768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-09-09 21:20:02 UTC (rev 205767)
+++ trunk/Tools/ChangeLog        2016-09-09 21:29:47 UTC (rev 205768)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-09-09  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        URLParser: Fix and optimize parsing file URLs ending with a host but no slash
+        https://bugs.webkit.org/show_bug.cgi?id=161815
+
+        Reviewed by Geoffrey Garen.
+
+        * TestWebKitAPI/Tests/WebCore/URLParser.cpp:
+        (TestWebKitAPI::TEST_F):
+
</ins><span class="cx"> 2016-09-08  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Expose Apple Pencil data to Touch events
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebCoreURLParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp (205767 => 205768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp        2016-09-09 21:20:02 UTC (rev 205767)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp        2016-09-09 21:29:47 UTC (rev 205768)
</span><span class="lines">@@ -157,6 +157,8 @@
</span><span class="cx">     checkURL(&quot;file:////&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;//&quot;, &quot;&quot;, &quot;&quot;, &quot;file:////&quot;}); // This matches Firefox and URL::parse which I believe are correct, but not Chrome.
</span><span class="cx">     checkURL(&quot;file:/path&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;/path&quot;, &quot;&quot;, &quot;&quot;, &quot;file:///path&quot;});
</span><span class="cx">     checkURL(&quot;file://host/path&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;host&quot;, 0, &quot;/path&quot;, &quot;&quot;, &quot;&quot;, &quot;file://host/path&quot;});
</span><ins>+    checkURL(&quot;file://host&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;host&quot;, 0, &quot;/&quot;, &quot;&quot;, &quot;&quot;, &quot;file://host/&quot;});
+    checkURL(&quot;file://host/&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;host&quot;, 0, &quot;/&quot;, &quot;&quot;, &quot;&quot;, &quot;file://host/&quot;});
</ins><span class="cx">     checkURL(&quot;file:///path&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;/path&quot;, &quot;&quot;, &quot;&quot;, &quot;file:///path&quot;});
</span><span class="cx">     checkURL(&quot;file:////path&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;//path&quot;, &quot;&quot;, &quot;&quot;, &quot;file:////path&quot;});
</span><span class="cx">     checkURL(&quot;file://localhost/path&quot;, {&quot;file&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;/path&quot;, &quot;&quot;, &quot;&quot;, &quot;file:///path&quot;});
</span><span class="lines">@@ -423,6 +425,12 @@
</span><span class="cx">     checkRelativeURLDifferences(&quot;notspecial:\\\\foo.com&quot;, &quot;http://example.org/foo/bar&quot;,
</span><span class="cx">         {&quot;notspecial&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;\\\\foo.com&quot;, &quot;&quot;, &quot;&quot;, &quot;notspecial:\\\\foo.com&quot;},
</span><span class="cx">         {&quot;notspecial&quot;, &quot;&quot;, &quot;&quot;, &quot;foo.com&quot;, 0, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;notspecial://foo.com&quot;});
</span><ins>+    checkURLDifferences(&quot;file://notuser:notpassword@test&quot;,
+        {&quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;file://notuser:notpassword@test&quot;},
+        {&quot;file&quot;, &quot;notuser&quot;, &quot;notpassword&quot;, &quot;test&quot;, 0, &quot;/&quot;, &quot;&quot;, &quot;&quot;, &quot;file://notuser:notpassword@test/&quot;});
+    checkURLDifferences(&quot;file://notuser:notpassword@test/&quot;,
+        {&quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, 0, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;file://notuser:notpassword@test/&quot;},
+        {&quot;file&quot;, &quot;notuser&quot;, &quot;notpassword&quot;, &quot;test&quot;, 0, &quot;/&quot;, &quot;&quot;, &quot;&quot;, &quot;file://notuser:notpassword@test/&quot;});
</ins><span class="cx">     
</span><span class="cx">     // This behavior matches Chrome and Firefox, but not WebKit using URL::parse.
</span><span class="cx">     // The behavior of URL::parse is clearly wrong because reparsing file://path would make path the host.
</span></span></pre>
</div>
</div>

</body>
</html>