<!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>[194888] 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/194888">194888</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-01-12 00:23:36 -0800 (Tue, 12 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Inconsistencies in main resource load delegates when loading from history
https://bugs.webkit.org/show_bug.cgi?id=150927

Reviewed by Michael Catanzaro.

Source/WebCore:

When restoring a page from the page cache, even though there
isn't an actual load of resources, we are still emitting the load
delegates to let the API layer know there are contents being
loaded in the web view. This makes the page cache restoring
transparent for the API layer. However, when restoring a page from
the cache, all the delegates are emitted after the load is
committed. This is not consistent with real loads, where we first
load the main resource and once we get a response we commit the
load. This inconsistency is problematic if the API layer expects
to always have a main resource with a response when the load is
committed. This is the case of the GTK+ port, for example. So,
this patch ensures that when a page is restored from the page
cache, the main resource load delegates that are emitted until a
response is received in normal loads, are emitted before the load
is committed.

Test: http/tests/loading/main-resource-delegates-on-back-navigation.html

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::commitProvisionalLoad): When loading from
the page cache, send delegate messages up to didReceiveResponse
for the main resource before the load is committed, and the
remaining messages afterwards.

LayoutTests:

Add test to check that main resource load delegates are emitted in
the same order before the load is committed when loading a page
from history with the page cache enabled and disabled.

* http/tests/loading/main-resource-delegates-on-back-navigation-expected.txt: Added.
* http/tests/loading/main-resource-delegates-on-back-navigation.html: Added.
* http/tests/loading/resources/page-go-back-onload.html: Added.
* loader/go-back-cached-main-resource-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsloadergobackcachedmainresourceexpectedtxt">trunk/LayoutTests/loader/go-back-cached-main-resource-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoadercpp">trunk/Source/WebCore/loader/FrameLoader.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestsloadingmainresourcedelegatesonbacknavigationexpectedtxt">trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingmainresourcedelegatesonbacknavigationhtml">trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation.html</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourcespagegobackonloadhtml">trunk/LayoutTests/http/tests/loading/resources/page-go-back-onload.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (194887 => 194888)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-01-12 07:39:16 UTC (rev 194887)
+++ trunk/LayoutTests/ChangeLog        2016-01-12 08:23:36 UTC (rev 194888)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-01-11  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        Inconsistencies in main resource load delegates when loading from history
+        https://bugs.webkit.org/show_bug.cgi?id=150927
+
+        Reviewed by Michael Catanzaro.
+
+        Add test to check that main resource load delegates are emitted in
+        the same order before the load is committed when loading a page
+        from history with the page cache enabled and disabled.
+
+        * http/tests/loading/main-resource-delegates-on-back-navigation-expected.txt: Added.
+        * http/tests/loading/main-resource-delegates-on-back-navigation.html: Added.
+        * http/tests/loading/resources/page-go-back-onload.html: Added.
+        * loader/go-back-cached-main-resource-expected.txt:
+
</ins><span class="cx"> 2016-01-11  Johan K. Jensen  &lt;jj@johanjensen.dk&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: console.count() shouldn't show a colon in front of a number
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingmainresourcedelegatesonbacknavigationexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation-expected.txt (0 => 194888)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation-expected.txt        2016-01-12 08:23:36 UTC (rev 194888)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html - didFinishLoading
+main frame - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/page-go-back-onload.html 
+main frame - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/page-go-back-onload.html - willSendRequest &lt;NSURLRequest URL http://127.0.0.1:8000/loading/resources/page-go-back-onload.html, main document URL http://127.0.0.1:8000/loading/resources/page-go-back-onload.html, http method GET&gt; redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/page-go-back-onload.html - didReceiveResponse &lt;NSURLResponse http://127.0.0.1:8000/loading/resources/page-go-back-onload.html, http status code 200&gt;
+main frame - didCancelClientRedirectForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/page-go-back-onload.html - didFinishLoading
+main frame - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html - willSendRequest &lt;NSURLRequest URL http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html, main document URL http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html, http method GET&gt; redirectResponse (null)
+http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html - didReceiveResponse &lt;NSURLResponse http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html, http status code 200&gt;
+main frame - didCommitLoadForFrame
+http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html - didFinishLoading
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+main frame - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/page-go-back-onload.html 
+main frame - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/page-go-back-onload.html - willSendRequest &lt;NSURLRequest URL http://127.0.0.1:8000/loading/resources/page-go-back-onload.html, main document URL http://127.0.0.1:8000/loading/resources/page-go-back-onload.html, http method GET&gt; redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/page-go-back-onload.html - didReceiveResponse &lt;NSURLResponse http://127.0.0.1:8000/loading/resources/page-go-back-onload.html, http status code 200&gt;
+main frame - didCancelClientRedirectForFrame
+main frame - didCommitLoadForFrame
+http://127.0.0.1:8000/loading/resources/page-go-back-onload.html - didFinishLoading
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+main frame - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html - willSendRequest &lt;NSURLRequest URL http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html, main document URL http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html, http method GET&gt; redirectResponse (null)
+http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html - didReceiveResponse &lt;NSURLResponse http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html, http status code 200&gt;
+main frame - didCommitLoadForFrame
+http://127.0.0.1:8000/loading/main-resource-delegates-on-back-navigation.html - didFinishLoading
+main frame - didFinishLoadForFrame
+Test that main resource load delegates are the same when page cache is enabled and disabled
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingmainresourcedelegatesonbacknavigationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation.html (0 => 194888)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/main-resource-delegates-on-back-navigation.html        2016-01-12 08:23:36 UTC (rev 194888)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+Test that main resource load delegates are the same when page cache is enabled and disabled
+&lt;script&gt;
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpResourceLoadCallbacks();
+    testRunner.waitUntilDone();
+}
+
+window.addEventListener('pageshow', function() {
+    if (!sessionStorage.testLoadCount)
+        sessionStorage.testLoadCount = 1;
+    else
+        sessionStorage.testLoadCount = parseInt(sessionStorage.testLoadCount, 10) + 1
+    var pageCacheEnabled;
+    switch(parseInt(sessionStorage.testLoadCount, 10)) {
+    case 1:
+        pageCacheEnabled = 0;
+        break;
+    case 2:
+        pageCacheEnabled = 1;
+        break;
+    case 3:
+        setTimeout(function() {
+            delete sessionStorage.testLoadCount;
+            testRunner.notifyDone();
+        }, 0);
+        break;
+    }
+
+    if (window.testRunner)
+        testRunner.overridePreference(&quot;WebKitUsesPageCachePreferenceKey&quot;, pageCacheEnabled);
+
+    setTimeout(function() {
+        window.location.href = &quot;resources/page-go-back-onload.html&quot;;
+    }, 0);
+}, false);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourcespagegobackonloadhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resources/page-go-back-onload.html (0 => 194888)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resources/page-go-back-onload.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resources/page-go-back-onload.html        2016-01-12 08:23:36 UTC (rev 194888)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+&lt;script&gt;
+window.addEventListener(&quot;load&quot;, function() {
+    setTimeout(function() {
+        history.back();
+    }, 0);
+}, false);
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsloadergobackcachedmainresourceexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/loader/go-back-cached-main-resource-expected.txt (194887 => 194888)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/loader/go-back-cached-main-resource-expected.txt        2016-01-12 07:39:16 UTC (rev 194887)
+++ trunk/LayoutTests/loader/go-back-cached-main-resource-expected.txt        2016-01-12 08:23:36 UTC (rev 194888)
</span><span class="lines">@@ -11,7 +11,7 @@
</span><span class="cx"> resources/other-page.html - willSendRequest &lt;NSURLRequest URL resources/other-page.html, main document URL resources/other-page.html, http method GET&gt; redirectResponse (null)
</span><span class="cx"> resources/other-page.html - didReceiveResponse &lt;NSURLResponse resources/other-page.html, http status code 0&gt;
</span><span class="cx"> resources/other-page.html - didFinishLoading
</span><del>-resources/first-page.html - willSendRequest &lt;NSURLRequest URL resources/first-page.html, main document URL (null), http method GET&gt; redirectResponse (null)
</del><ins>+resources/first-page.html - willSendRequest &lt;NSURLRequest URL resources/first-page.html, main document URL resources/first-page.html, http method GET&gt; redirectResponse (null)
</ins><span class="cx"> resources/first-page.html - didReceiveResponse &lt;NSURLResponse resources/first-page.html, http status code 0&gt;
</span><span class="cx"> resources/first-page.html - didFinishLoading
</span><span class="cx"> This test check the following situation:
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (194887 => 194888)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-12 07:39:16 UTC (rev 194887)
+++ trunk/Source/WebCore/ChangeLog        2016-01-12 08:23:36 UTC (rev 194888)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2016-01-11  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        Inconsistencies in main resource load delegates when loading from history
+        https://bugs.webkit.org/show_bug.cgi?id=150927
+
+        Reviewed by Michael Catanzaro.
+
+        When restoring a page from the page cache, even though there
+        isn't an actual load of resources, we are still emitting the load
+        delegates to let the API layer know there are contents being
+        loaded in the web view. This makes the page cache restoring
+        transparent for the API layer. However, when restoring a page from
+        the cache, all the delegates are emitted after the load is
+        committed. This is not consistent with real loads, where we first
+        load the main resource and once we get a response we commit the
+        load. This inconsistency is problematic if the API layer expects
+        to always have a main resource with a response when the load is
+        committed. This is the case of the GTK+ port, for example. So,
+        this patch ensures that when a page is restored from the page
+        cache, the main resource load delegates that are emitted until a
+        response is received in normal loads, are emitted before the load
+        is committed.
+
+        Test: http/tests/loading/main-resource-delegates-on-back-navigation.html
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::commitProvisionalLoad): When loading from
+        the page cache, send delegate messages up to didReceiveResponse
+        for the main resource before the load is committed, and the
+        remaining messages afterwards.
+
</ins><span class="cx"> 2016-01-09  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Cocoa] Add SPI to opt out a URL scheme from the memory cache
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (194887 => 194888)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoader.cpp        2016-01-12 07:39:16 UTC (rev 194887)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp        2016-01-12 08:23:36 UTC (rev 194888)
</span><span class="lines">@@ -1800,6 +1800,14 @@
</span><span class="cx"> #endif
</span><span class="cx">         prepareForCachedPageRestore();
</span><span class="cx"> 
</span><ins>+        // Start request for the main resource and dispatch didReceiveResponse before the load is committed for
+        // consistency with all other loads. See https://bugs.webkit.org/show_bug.cgi?id=150927.
+        ResourceError mainResouceError;
+        unsigned long mainResourceIdentifier;
+        ResourceRequest mainResourceRequest(cachedPage-&gt;documentLoader()-&gt;request());
+        requestFromDelegate(mainResourceRequest, mainResourceIdentifier, mainResouceError);
+        notifier().dispatchDidReceiveResponse(cachedPage-&gt;documentLoader(), mainResourceIdentifier, cachedPage-&gt;documentLoader()-&gt;response());
+
</ins><span class="cx">         // FIXME: This API should be turned around so that we ground CachedPage into the Page.
</span><span class="cx">         cachedPage-&gt;restore(*m_frame.page());
</span><span class="cx"> 
</span><span class="lines">@@ -1813,6 +1821,10 @@
</span><span class="cx">         if (!title.isNull())
</span><span class="cx">             m_client.dispatchDidReceiveTitle(title);
</span><span class="cx"> 
</span><ins>+        // Send remaining notifications for the main resource.
+        notifier().sendRemainingDelegateMessages(m_documentLoader.get(), mainResourceIdentifier, mainResourceRequest, ResourceResponse(),
+            nullptr, static_cast&lt;int&gt;(m_documentLoader-&gt;response().expectedContentLength()), 0, mainResouceError);
+
</ins><span class="cx">         checkCompleted();
</span><span class="cx">     } else
</span><span class="cx">         didOpenURL();
</span><span class="lines">@@ -1839,7 +1851,9 @@
</span><span class="cx">         m_frame.view()-&gt;forceLayout();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-        for (auto&amp; response : m_documentLoader-&gt;responses()) {
</del><ins>+        // Main resource delegates were already sent, so we skip the first response here.
+        for (unsigned i = 1; i &lt; m_documentLoader-&gt;responses().size(); ++i) {
+            const auto&amp; response = m_documentLoader-&gt;responses()[i];
</ins><span class="cx">             // FIXME: If the WebKit client changes or cancels the request, this is not respected.
</span><span class="cx">             ResourceError error;
</span><span class="cx">             unsigned long identifier;
</span></span></pre>
</div>
</div>

</body>
</html>