[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

japhet at chromium.org japhet at chromium.org
Thu Apr 8 00:44:40 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 3047c2a47378e0f32ffa3773da719015dee497a1
Author: japhet at chromium.org <japhet at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Dec 21 16:55:34 2009 +0000

    2009-12-21  Nate Chapin  <japhet at chromium.org>
    
            Reviewed by Darin Adler.
    
            If an image load is started during an unload or beforeunload event, run it
            asynchronously (and allow it to outlive its page) so navigation can continue
            while the load completes.
    
            https://bugs.webkit.org/show_bug.cgi?id=30457
    
            Tests: http/tests/navigation/image-load-in-beforeunload-handler.html
                   http/tests/navigation/image-load-in-unload-handler.html
    
            * loader/DocumentThreadableLoader.cpp:
            (WebCore::DocumentThreadableLoader::loadRequest):
            * loader/FrameLoader.cpp: Rename m_unloadEventBeingDispatched to m_isDispatchingUnloadEvent.
            (WebCore::FrameLoader::FrameLoader):
            (WebCore::FrameLoader::stopLoading):
            (WebCore::FrameLoader::loadURL):
            (WebCore::FrameLoader::loadWithDocumentLoader):
            (WebCore::FrameLoader::stopAllLoaders):
            (WebCore::FrameLoader::continueLoadAfterNavigationPolicy): Set m_isDispatchingBeforeUnloadEvent.
            (WebCore::FrameLoader::pageHidden):
            * loader/FrameLoader.h:
            (WebCore::FrameLoader::isDispatchingUnloadFamilyEvent): Added.
            * loader/Request.cpp:
            (WebCore::Request::Request): Add OutlivePagePolicy to constructor parameters
            * loader/Request.h:
            (WebCore::): Add OutlivePagePolicy enum.
            (WebCore::Request::shouldOutlivePage): Added.
            (WebCore::Request::frame): Added.
            * loader/SubresourceLoader.cpp:
            (WebCore::SubresourceLoader::create): Change one of the security checks to an outlive page check.
            * loader/SubresourceLoader.h:
            * loader/loader.cpp:
            (WebCore::Loader::load): Add OutlivePagePolicy to Request constructor call,
                 ensure requests that should outlive page are done asynchronously.
            (WebCore::Loader::cancelRequests): Remove ending ASSERT since it will now be hard to predict how
                 many requests might possibly outlive a cancel in every case.
            (WebCore::Loader::Host::servePendingRequests): Use the correct frame in the case of a request outliving its page.
            (WebCore::Loader::Host::cancelPendingRequests): Ensure we don't cancel request that should outlive their page.
            (WebCore::Loader::Host::cancelRequests): Ensure we don't cancel request that should outlive their page.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52446 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index ccb20f5..a7c0cc3 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2009-12-21  Nate Chapin  <japhet at chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Tests for https://bugs.webkit.org/show_bug.cgi?id=30457.
+
+        * http/tests/navigation/image-load-in-beforeunload-handler-expected.txt: Added.
+        * http/tests/navigation/image-load-in-beforeunload-handler.html: Added.
+        * http/tests/navigation/image-load-in-unload-handler-expected.txt: Added.
+        * http/tests/navigation/image-load-in-unload-handler.html: Added.
+        * http/tests/navigation/resources/wait-then-notify-done.html: Added.
+
 2009-12-21  Philippe Normand  <pnormand at igalia.com>
 
         Rubber-stamped by Xan Lopez.
diff --git a/LayoutTests/http/tests/navigation/image-load-in-beforeunload-handler-expected.txt b/LayoutTests/http/tests/navigation/image-load-in-beforeunload-handler-expected.txt
new file mode 100644
index 0000000..1d14e99
--- /dev/null
+++ b/LayoutTests/http/tests/navigation/image-load-in-beforeunload-handler-expected.txt
@@ -0,0 +1,8 @@
+<unknown> - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -999, failing URL "http://127.0.0.1:8000/navigation/image-load-in-beforeunload-handler.html">
+http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html, main document URL http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl, main document URL http://127.0.0.1:8000/navigation/image-load-in-beforeunload-handler.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html, http status code 200>
+http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html - didFinishLoading
+http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl, http status code 200>
+http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl - didFinishLoading
+
diff --git a/LayoutTests/http/tests/navigation/image-load-in-beforeunload-handler.html b/LayoutTests/http/tests/navigation/image-load-in-beforeunload-handler.html
new file mode 100644
index 0000000..e87553e
--- /dev/null
+++ b/LayoutTests/http/tests/navigation/image-load-in-beforeunload-handler.html
@@ -0,0 +1,23 @@
+<html><head>
+<title>Image load in unload handler</title>
+<script>
+function navigate() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.dumpResourceLoadCallbacks();
+        layoutTestController.waitUntilDone();
+        var target = document.getElementById("link");
+        eventSender.mouseMoveTo(target.offsetLeft + 2, target.offsetTop + 2);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+}
+
+function requestImage() {
+    var img = new Image(1, 1);
+    img.src = "resources/slow-resource-1-sec.pl";
+}
+</script></head>
+<body onload="navigate();" onbeforeunload="requestImage();">
+<a id="link" href="resources/wait-then-notify-done.html">link</a>
+</body></html>
diff --git a/LayoutTests/http/tests/navigation/image-load-in-unload-handler-expected.txt b/LayoutTests/http/tests/navigation/image-load-in-unload-handler-expected.txt
new file mode 100644
index 0000000..9d0552c
--- /dev/null
+++ b/LayoutTests/http/tests/navigation/image-load-in-unload-handler-expected.txt
@@ -0,0 +1,9 @@
+main frame - has 1 onunload handler(s)
+<unknown> - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -999, failing URL "http://127.0.0.1:8000/navigation/image-load-in-unload-handler.html">
+http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html, main document URL http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html, http status code 200>
+http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html - didFinishLoading
+http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl, main document URL http://127.0.0.1:8000/navigation/resources/wait-then-notify-done.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl, http status code 200>
+http://127.0.0.1:8000/navigation/resources/slow-resource-1-sec.pl - didFinishLoading
+
diff --git a/LayoutTests/http/tests/navigation/image-load-in-unload-handler.html b/LayoutTests/http/tests/navigation/image-load-in-unload-handler.html
new file mode 100644
index 0000000..725bd5c
--- /dev/null
+++ b/LayoutTests/http/tests/navigation/image-load-in-unload-handler.html
@@ -0,0 +1,24 @@
+<html><head>
+<title>Image load in unload handler</title>
+<script>
+function navigate() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.dumpResourceLoadCallbacks();
+        layoutTestController.waitUntilDone();
+        var target = document.getElementById("link");
+        eventSender.mouseMoveTo(target.offsetLeft + 2, target.offsetTop + 2);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+}
+
+function requestImage() {
+    var img = new Image(1, 1);
+    img.src = "resources/slow-resource-1-sec.pl";
+}
+</script>
+</head>
+<body onload="navigate();" onunload="requestImage();">
+<a id="link" href="resources/wait-then-notify-done.html">link</a>
+</body></html>
diff --git a/LayoutTests/http/tests/navigation/resources/wait-then-notify-done.html b/LayoutTests/http/tests/navigation/resources/wait-then-notify-done.html
new file mode 100644
index 0000000..ed43ec4
--- /dev/null
+++ b/LayoutTests/http/tests/navigation/resources/wait-then-notify-done.html
@@ -0,0 +1,9 @@
+<html>
+<script>
+    if (window.layoutTestController) {
+        setTimeout(function() {
+            layoutTestController.notifyDone();
+        }, 2000);
+    }
+</script>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 72d243e..3edb61f 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,46 @@
+2009-12-21  Nate Chapin  <japhet at chromium.org>
+
+        Reviewed by Darin Adler.
+
+        If an image load is started during an unload or beforeunload event, run it
+        asynchronously (and allow it to outlive its page) so navigation can continue 
+        while the load completes.
+
+        https://bugs.webkit.org/show_bug.cgi?id=30457
+
+        Tests: http/tests/navigation/image-load-in-beforeunload-handler.html
+               http/tests/navigation/image-load-in-unload-handler.html
+
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::loadRequest): 
+        * loader/FrameLoader.cpp: Rename m_unloadEventBeingDispatched to m_isDispatchingUnloadEvent.
+        (WebCore::FrameLoader::FrameLoader):
+        (WebCore::FrameLoader::stopLoading):
+        (WebCore::FrameLoader::loadURL):
+        (WebCore::FrameLoader::loadWithDocumentLoader):
+        (WebCore::FrameLoader::stopAllLoaders):
+        (WebCore::FrameLoader::continueLoadAfterNavigationPolicy): Set m_isDispatchingBeforeUnloadEvent.
+        (WebCore::FrameLoader::pageHidden):
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::isDispatchingUnloadFamilyEvent): Added.
+        * loader/Request.cpp:
+        (WebCore::Request::Request): Add OutlivePagePolicy to constructor parameters
+        * loader/Request.h:
+        (WebCore::): Add OutlivePagePolicy enum.
+        (WebCore::Request::shouldOutlivePage): Added.
+        (WebCore::Request::frame): Added.
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::create): Change one of the security checks to an outlive page check.
+        * loader/SubresourceLoader.h:
+        * loader/loader.cpp:
+        (WebCore::Loader::load): Add OutlivePagePolicy to Request constructor call,
+             ensure requests that should outlive page are done asynchronously.
+        (WebCore::Loader::cancelRequests): Remove ending ASSERT since it will now be hard to predict how
+             many requests might possibly outlive a cancel in every case.
+        (WebCore::Loader::Host::servePendingRequests): Use the correct frame in the case of a request outliving its page.
+        (WebCore::Loader::Host::cancelPendingRequests): Ensure we don't cancel request that should outlive their page.
+        (WebCore::Loader::Host::cancelRequests): Ensure we don't cancel request that should outlive their page.
+
 2009-12-18  Adam Roben  <aroben at apple.com>
 
         Fix Windows build warnings
diff --git a/WebCore/loader/DocumentThreadableLoader.cpp b/WebCore/loader/DocumentThreadableLoader.cpp
index de0a0b0..43580e4 100644
--- a/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/WebCore/loader/DocumentThreadableLoader.cpp
@@ -299,7 +299,7 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Secur
 
         // Clear the loader so that any callbacks from SubresourceLoader::create will not have the old loader.
         m_loader = 0;
-        m_loader = SubresourceLoader::create(m_document->frame(), this, request, securityCheck, sendLoadCallbacks, sniffContent);
+        m_loader = SubresourceLoader::create(m_document->frame(), this, request, securityCheck, DoNotOutlivePage, sendLoadCallbacks, sniffContent);
         return;
     }
     
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index e457fd9..7c7aa3e 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -180,7 +180,8 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
     , m_isExecutingJavaScriptFormAction(false)
     , m_didCallImplicitClose(false)
     , m_wasUnloadEventEmitted(false)
-    , m_unloadEventBeingDispatched(false)
+    , m_isDispatchingBeforeUnloadEvent(false)
+    , m_isDispatchingUnloadEvent(false)
     , m_isComplete(false)
     , m_isLoadingMainResource(false)
     , m_needsClear(false)
@@ -517,14 +518,16 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic
                 Node* currentFocusedNode = m_frame->document()->focusedNode();
                 if (currentFocusedNode)
                     currentFocusedNode->aboutToUnload();
-                m_unloadEventBeingDispatched = true;
+                ASSERT(!m_isDispatchingUnloadEvent);
+                m_isDispatchingUnloadEvent = true;
                 if (m_frame->domWindow()) {
                     if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide)
                         m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document());
                     if (!m_frame->document()->inPageCache())
                         m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document());
                 }
-                m_unloadEventBeingDispatched = false;
+                ASSERT(m_isDispatchingUnloadEvent);
+                m_isDispatchingUnloadEvent = false;
                 if (m_frame->document())
                     m_frame->document()->updateStyleIfNeeded();
                 m_wasUnloadEventEmitted = true;
@@ -1908,7 +1911,7 @@ void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const Stri
         return;
     }
 
-    if (m_unloadEventBeingDispatched)
+    if (m_isDispatchingUnloadEvent)
         return;
 
     NavigationAction action(newURL, newLoadType, isFormSubmission, event);
@@ -2034,7 +2037,7 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
 
     ASSERT(m_frame->view());
 
-    if (m_unloadEventBeingDispatched)
+    if (m_isDispatchingUnloadEvent)
         return;
 
     policyChecker()->setLoadType(type);
@@ -2276,7 +2279,7 @@ void FrameLoader::stopLoadingSubframes()
 void FrameLoader::stopAllLoaders(DatabasePolicy databasePolicy)
 {
     ASSERT(!m_frame->document() || !m_frame->document()->inPageCache());
-    if (m_unloadEventBeingDispatched)
+    if (m_isDispatchingUnloadEvent)
         return;
 
     // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
@@ -3433,7 +3436,11 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, Pass
     //       is the user responding Cancel to the form repost nag sheet.
     //    2) User responded Cancel to an alert popped up by the before unload event handler.
     // The "before unload" event handler runs only for the main frame.
+    ASSERT(!m_isDispatchingBeforeUnloadEvent);
+    m_isDispatchingBeforeUnloadEvent = true;
     bool canContinue = shouldContinue && (!isLoadingMainFrame() || m_frame->shouldClose());
+    ASSERT(m_isDispatchingBeforeUnloadEvent);
+    m_isDispatchingBeforeUnloadEvent = false;
 
     if (!canContinue) {
         // If we were waiting for a quick redirect, but the policy delegate decided to ignore it, then we 
@@ -3627,10 +3634,12 @@ void FrameLoader::cachePageForHistoryItem(HistoryItem* item)
 
 void FrameLoader::pageHidden()
 {
-    m_unloadEventBeingDispatched = true;
+    ASSERT(!m_isDispatchingUnloadEvent);
+    m_isDispatchingUnloadEvent = true;
     if (m_frame->domWindow())
         m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, true), m_frame->document());
-    m_unloadEventBeingDispatched = false;
+    ASSERT(m_isDispatchingUnloadEvent);
+    m_isDispatchingUnloadEvent = false;
 
     // Send pagehide event for subframes as well
     for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
diff --git a/WebCore/loader/FrameLoader.h b/WebCore/loader/FrameLoader.h
index 7304bfd..b499cad 100644
--- a/WebCore/loader/FrameLoader.h
+++ b/WebCore/loader/FrameLoader.h
@@ -333,6 +333,8 @@ public:
     void continueLoadAfterWillSubmitForm();
     
     bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; }
+    
+    bool isDispatchingUnloadFamilyEvent() const { return m_isDispatchingBeforeUnloadEvent || m_isDispatchingUnloadEvent; }
 
     static ObjectContentType defaultObjectContentType(const KURL& url, const String& mimeType);
 
@@ -479,7 +481,8 @@ private:
 
     bool m_didCallImplicitClose;
     bool m_wasUnloadEventEmitted;
-    bool m_unloadEventBeingDispatched;
+    bool m_isDispatchingBeforeUnloadEvent;
+    bool m_isDispatchingUnloadEvent;
     bool m_isComplete;
     bool m_isLoadingMainResource;
 
diff --git a/WebCore/loader/Request.cpp b/WebCore/loader/Request.cpp
index 630a4bb..7cb8934 100644
--- a/WebCore/loader/Request.cpp
+++ b/WebCore/loader/Request.cpp
@@ -25,10 +25,12 @@
 #include "Request.h"
 
 #include "CachedResource.h"
+#include "DocLoader.h"
+#include "Frame.h"
 
 namespace WebCore {
 
-Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental, SecurityCheckPolicy shouldDoSecurityCheck, bool sendResourceLoadCallbacks)
+Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental, SecurityCheckPolicy shouldDoSecurityCheck, OutlivePagePolicy outlivePagePolicy, bool sendResourceLoadCallbacks)
     : m_object(object)
     , m_docLoader(docLoader)
     , m_incremental(incremental)
@@ -37,11 +39,18 @@ Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental,
     , m_sendResourceLoadCallbacks(sendResourceLoadCallbacks)
 {
     m_object->setRequest(this);
+    if (outlivePagePolicy == OutlivePage)
+        m_frameForRequestThatCanOutlivePage = docLoader->frame();
 }
 
 Request::~Request()
 {
     m_object->setRequest(0);
 }
+    
+Frame* Request::frame() const
+{
+    return m_frameForRequestThatCanOutlivePage ? m_frameForRequestThatCanOutlivePage.get() : m_docLoader->frame();
+}
 
 } //namespace WebCore
diff --git a/WebCore/loader/Request.h b/WebCore/loader/Request.h
index 468f8ff..20f358d 100644
--- a/WebCore/loader/Request.h
+++ b/WebCore/loader/Request.h
@@ -24,16 +24,23 @@
 #define Request_h
 
 #include "FrameLoaderTypes.h"
+#include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
     class CachedResource;
     class DocLoader;
+    class Frame;
+    
+    enum OutlivePagePolicy {
+        DoNotOutlivePage,
+        OutlivePage
+    };
 
     class Request : public Noncopyable {
     public:
-        Request(DocLoader*, CachedResource*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);
+        Request(DocLoader*, CachedResource*, bool incremental, SecurityCheckPolicy, OutlivePagePolicy, bool sendResourceLoadCallbacks);
         ~Request();
         
         Vector<char>& buffer() { return m_buffer; }
@@ -49,6 +56,9 @@ namespace WebCore {
         SecurityCheckPolicy shouldDoSecurityCheck() const { return m_shouldDoSecurityCheck; }
         bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
         
+        OutlivePagePolicy canOutlivePage() const { return m_frameForRequestThatCanOutlivePage ? OutlivePage : DoNotOutlivePage; }
+        Frame* frame() const;
+        
     private:
         Vector<char> m_buffer;
         CachedResource* m_object;
@@ -57,6 +67,7 @@ namespace WebCore {
         bool m_multipart;
         SecurityCheckPolicy m_shouldDoSecurityCheck;
         bool m_sendResourceLoadCallbacks;
+        RefPtr<Frame> m_frameForRequestThatCanOutlivePage;
     };
 
 } //namespace WebCore
diff --git a/WebCore/loader/SubresourceLoader.cpp b/WebCore/loader/SubresourceLoader.cpp
index f92a074..cc8e47d 100644
--- a/WebCore/loader/SubresourceLoader.cpp
+++ b/WebCore/loader/SubresourceLoader.cpp
@@ -61,18 +61,18 @@ SubresourceLoader::~SubresourceLoader()
 #endif
 }
 
-PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks, bool shouldContentSniff)
+PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, SecurityCheckPolicy securityCheckPolicy, OutlivePagePolicy outlivePagePolicy, bool sendResourceLoadCallbacks, bool shouldContentSniff)
 {
     if (!frame)
         return 0;
 
     FrameLoader* fl = frame->loader();
-    if (securityCheck == DoSecurityCheck && (fl->state() == FrameStateProvisional || fl->activeDocumentLoader()->isStopping()))
+    if (outlivePagePolicy == DoNotOutlivePage && (fl->state() == FrameStateProvisional || fl->activeDocumentLoader()->isStopping()))
         return 0;
 
     ResourceRequest newRequest = request;
 
-    if (securityCheck == DoSecurityCheck
+    if (securityCheckPolicy == DoSecurityCheck
             && SecurityOrigin::restrictAccessToLocal()
             && !SecurityOrigin::canLoad(request.url(), String(), frame->document())) {
         FrameLoader::reportLocalLoadFailed(frame, request.url().string());
diff --git a/WebCore/loader/SubresourceLoader.h b/WebCore/loader/SubresourceLoader.h
index 907d917..d75c1f7 100644
--- a/WebCore/loader/SubresourceLoader.h
+++ b/WebCore/loader/SubresourceLoader.h
@@ -30,6 +30,7 @@
 #define SubresourceLoader_h
 
 #include "FrameLoaderTypes.h"
+#include "Request.h"
 #include "ResourceLoader.h"
  
 namespace WebCore {
@@ -39,7 +40,7 @@ namespace WebCore {
     
     class SubresourceLoader : public ResourceLoader {
     public:
-        static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true);
+        static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, SecurityCheckPolicy = DoSecurityCheck, OutlivePagePolicy = DoNotOutlivePage, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true);
 
         void clearClient() { m_client = 0; }
 
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index a99bf87..7536f6a 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -120,7 +120,16 @@ Loader::Priority Loader::determinePriority(const CachedResource* resource) const
 void Loader::load(DocLoader* docLoader, CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
 {
     ASSERT(docLoader);
-    Request* request = new Request(docLoader, resource, incremental, securityCheck, sendResourceLoadCallbacks);
+    
+    // If we are loading an image during an unload event, we want to allow the request to outlive the page
+    // that we are leaving. Some sites (most commonly ad networks) rely on image requests in beforeunload
+    // or unload event handlers to track time spent on the page. This will allow them to do the tracking
+    // that they are going to do anyway, but asynchronously so that they don't slow down navigation.
+    OutlivePagePolicy outlivePagePolicy = resource->isImage() && docLoader && docLoader->frame() 
+        && docLoader->frame()->loader()->isDispatchingUnloadFamilyEvent()
+        ? OutlivePage : DoNotOutlivePage;
+    
+    Request* request = new Request(docLoader, resource, incremental, securityCheck, outlivePagePolicy, sendResourceLoadCallbacks);
 
     RefPtr<Host> host;
     KURL url(ParsedURLString, resource->url());
@@ -138,8 +147,10 @@ void Loader::load(DocLoader* docLoader, CachedResource* resource, bool increment
     Priority priority = determinePriority(resource);
     host->addRequest(request, priority);
     docLoader->incrementRequestCount();
-
-    if (priority > Low || !url.protocolInHTTPFamily() || !hadRequests) {
+    
+    // We want to guarantee that requests which outlive the page are run asynchronously, so only
+    // serve the request immediately if the request doesn't need to outlive the page.
+    if (request->canOutlivePage() == DoNotOutlivePage && (priority > Low || !url.protocolInHTTPFamily() || !hadRequests)) {
         // Try to request important resources immediately
         host->servePendingRequests(priority);
     } else {
@@ -248,8 +259,6 @@ void Loader::cancelRequests(DocLoader* docLoader)
     }
 
     scheduleServePendingRequests();
-    
-    ASSERT(docLoader->requestCount() == (docLoader->loadInProgress() ? 1 : 0));
 }
 
 Loader::Host::Host(const AtomicString& name, unsigned maxRequestsInFlight)
@@ -346,8 +355,8 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser
             }
         }
 
-        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
-            this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
+        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(request->frame(),
+            this, resourceRequest, request->shouldDoSecurityCheck(), request->canOutlivePage(), request->sendResourceLoadCallbacks());
         if (loader) {
             m_requestsLoading.add(loader.release(), request);
             request->cachedResource()->setRequestedFromNetworkingLayer();
@@ -550,7 +559,7 @@ void Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, DocLoade
     RequestQueue::iterator end = requestsPending.end();
     for (RequestQueue::iterator it = requestsPending.begin(); it != end; ++it) {
         Request* request = *it;
-        if (request->docLoader() == docLoader) {
+        if (request->canOutlivePage() == DoNotOutlivePage && request->docLoader() == docLoader) {
             cache()->remove(request->cachedResource());
             delete request;
             docLoader->decrementRequestCount();
@@ -570,7 +579,7 @@ void Loader::Host::cancelRequests(DocLoader* docLoader)
     RequestMap::iterator end = m_requestsLoading.end();
     for (RequestMap::iterator i = m_requestsLoading.begin(); i != end; ++i) {
         Request* r = i->second;
-        if (r->docLoader() == docLoader)
+        if (r->canOutlivePage() == DoNotOutlivePage && r->docLoader() == docLoader)
             loadersToCancel.append(i->first.get());
     }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list