Changeset 52446 in webkit
- Timestamp:
- Dec 21, 2009 8:55:34 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r52445 r52446 1 2009-12-21 Nate Chapin <japhet@chromium.org> 2 3 Reviewed by Darin Adler. 4 5 Tests for https://bugs.webkit.org/show_bug.cgi?id=30457. 6 7 * http/tests/navigation/image-load-in-beforeunload-handler-expected.txt: Added. 8 * http/tests/navigation/image-load-in-beforeunload-handler.html: Added. 9 * http/tests/navigation/image-load-in-unload-handler-expected.txt: Added. 10 * http/tests/navigation/image-load-in-unload-handler.html: Added. 11 * http/tests/navigation/resources/wait-then-notify-done.html: Added. 12 1 13 2009-12-21 Philippe Normand <pnormand@igalia.com> 2 14 -
trunk/WebCore/ChangeLog
r52441 r52446 1 2009-12-21 Nate Chapin <japhet@chromium.org> 2 3 Reviewed by Darin Adler. 4 5 If an image load is started during an unload or beforeunload event, run it 6 asynchronously (and allow it to outlive its page) so navigation can continue 7 while the load completes. 8 9 https://bugs.webkit.org/show_bug.cgi?id=30457 10 11 Tests: http/tests/navigation/image-load-in-beforeunload-handler.html 12 http/tests/navigation/image-load-in-unload-handler.html 13 14 * loader/DocumentThreadableLoader.cpp: 15 (WebCore::DocumentThreadableLoader::loadRequest): 16 * loader/FrameLoader.cpp: Rename m_unloadEventBeingDispatched to m_isDispatchingUnloadEvent. 17 (WebCore::FrameLoader::FrameLoader): 18 (WebCore::FrameLoader::stopLoading): 19 (WebCore::FrameLoader::loadURL): 20 (WebCore::FrameLoader::loadWithDocumentLoader): 21 (WebCore::FrameLoader::stopAllLoaders): 22 (WebCore::FrameLoader::continueLoadAfterNavigationPolicy): Set m_isDispatchingBeforeUnloadEvent. 23 (WebCore::FrameLoader::pageHidden): 24 * loader/FrameLoader.h: 25 (WebCore::FrameLoader::isDispatchingUnloadFamilyEvent): Added. 26 * loader/Request.cpp: 27 (WebCore::Request::Request): Add OutlivePagePolicy to constructor parameters 28 * loader/Request.h: 29 (WebCore::): Add OutlivePagePolicy enum. 30 (WebCore::Request::shouldOutlivePage): Added. 31 (WebCore::Request::frame): Added. 32 * loader/SubresourceLoader.cpp: 33 (WebCore::SubresourceLoader::create): Change one of the security checks to an outlive page check. 34 * loader/SubresourceLoader.h: 35 * loader/loader.cpp: 36 (WebCore::Loader::load): Add OutlivePagePolicy to Request constructor call, 37 ensure requests that should outlive page are done asynchronously. 38 (WebCore::Loader::cancelRequests): Remove ending ASSERT since it will now be hard to predict how 39 many requests might possibly outlive a cancel in every case. 40 (WebCore::Loader::Host::servePendingRequests): Use the correct frame in the case of a request outliving its page. 41 (WebCore::Loader::Host::cancelPendingRequests): Ensure we don't cancel request that should outlive their page. 42 (WebCore::Loader::Host::cancelRequests): Ensure we don't cancel request that should outlive their page. 43 1 44 2009-12-18 Adam Roben <aroben@apple.com> 2 45 -
trunk/WebCore/loader/DocumentThreadableLoader.cpp
r52177 r52446 300 300 // Clear the loader so that any callbacks from SubresourceLoader::create will not have the old loader. 301 301 m_loader = 0; 302 m_loader = SubresourceLoader::create(m_document->frame(), this, request, securityCheck, sendLoadCallbacks, sniffContent);302 m_loader = SubresourceLoader::create(m_document->frame(), this, request, securityCheck, DoNotOutlivePage, sendLoadCallbacks, sniffContent); 303 303 return; 304 304 } -
trunk/WebCore/loader/FrameLoader.cpp
r52314 r52446 181 181 , m_didCallImplicitClose(false) 182 182 , m_wasUnloadEventEmitted(false) 183 , m_unloadEventBeingDispatched(false) 183 , m_isDispatchingBeforeUnloadEvent(false) 184 , m_isDispatchingUnloadEvent(false) 184 185 , m_isComplete(false) 185 186 , m_isLoadingMainResource(false) … … 518 519 if (currentFocusedNode) 519 520 currentFocusedNode->aboutToUnload(); 520 m_unloadEventBeingDispatched = true; 521 ASSERT(!m_isDispatchingUnloadEvent); 522 m_isDispatchingUnloadEvent = true; 521 523 if (m_frame->domWindow()) { 522 524 if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) … … 525 527 m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document()); 526 528 } 527 m_unloadEventBeingDispatched = false; 529 ASSERT(m_isDispatchingUnloadEvent); 530 m_isDispatchingUnloadEvent = false; 528 531 if (m_frame->document()) 529 532 m_frame->document()->updateStyleIfNeeded(); … … 1909 1912 } 1910 1913 1911 if (m_ unloadEventBeingDispatched)1914 if (m_isDispatchingUnloadEvent) 1912 1915 return; 1913 1916 … … 2035 2038 ASSERT(m_frame->view()); 2036 2039 2037 if (m_ unloadEventBeingDispatched)2040 if (m_isDispatchingUnloadEvent) 2038 2041 return; 2039 2042 … … 2277 2280 { 2278 2281 ASSERT(!m_frame->document() || !m_frame->document()->inPageCache()); 2279 if (m_ unloadEventBeingDispatched)2282 if (m_isDispatchingUnloadEvent) 2280 2283 return; 2281 2284 … … 3434 3437 // 2) User responded Cancel to an alert popped up by the before unload event handler. 3435 3438 // The "before unload" event handler runs only for the main frame. 3439 ASSERT(!m_isDispatchingBeforeUnloadEvent); 3440 m_isDispatchingBeforeUnloadEvent = true; 3436 3441 bool canContinue = shouldContinue && (!isLoadingMainFrame() || m_frame->shouldClose()); 3442 ASSERT(m_isDispatchingBeforeUnloadEvent); 3443 m_isDispatchingBeforeUnloadEvent = false; 3437 3444 3438 3445 if (!canContinue) { … … 3628 3635 void FrameLoader::pageHidden() 3629 3636 { 3630 m_unloadEventBeingDispatched = true; 3637 ASSERT(!m_isDispatchingUnloadEvent); 3638 m_isDispatchingUnloadEvent = true; 3631 3639 if (m_frame->domWindow()) 3632 3640 m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, true), m_frame->document()); 3633 m_unloadEventBeingDispatched = false; 3641 ASSERT(m_isDispatchingUnloadEvent); 3642 m_isDispatchingUnloadEvent = false; 3634 3643 3635 3644 // Send pagehide event for subframes as well -
trunk/WebCore/loader/FrameLoader.h
r51644 r52446 334 334 335 335 bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; } 336 337 bool isDispatchingUnloadFamilyEvent() const { return m_isDispatchingBeforeUnloadEvent || m_isDispatchingUnloadEvent; } 336 338 337 339 static ObjectContentType defaultObjectContentType(const KURL& url, const String& mimeType); … … 480 482 bool m_didCallImplicitClose; 481 483 bool m_wasUnloadEventEmitted; 482 bool m_unloadEventBeingDispatched; 484 bool m_isDispatchingBeforeUnloadEvent; 485 bool m_isDispatchingUnloadEvent; 483 486 bool m_isComplete; 484 487 bool m_isLoadingMainResource; -
trunk/WebCore/loader/Request.cpp
r52177 r52446 26 26 27 27 #include "CachedResource.h" 28 #include "DocLoader.h" 29 #include "Frame.h" 28 30 29 31 namespace WebCore { 30 32 31 Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental, SecurityCheckPolicy shouldDoSecurityCheck, bool sendResourceLoadCallbacks)33 Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental, SecurityCheckPolicy shouldDoSecurityCheck, OutlivePagePolicy outlivePagePolicy, bool sendResourceLoadCallbacks) 32 34 : m_object(object) 33 35 , m_docLoader(docLoader) … … 38 40 { 39 41 m_object->setRequest(this); 42 if (outlivePagePolicy == OutlivePage) 43 m_frameForRequestThatCanOutlivePage = docLoader->frame(); 40 44 } 41 45 … … 44 48 m_object->setRequest(0); 45 49 } 50 51 Frame* Request::frame() const 52 { 53 return m_frameForRequestThatCanOutlivePage ? m_frameForRequestThatCanOutlivePage.get() : m_docLoader->frame(); 54 } 46 55 47 56 } //namespace WebCore -
trunk/WebCore/loader/Request.h
r52177 r52446 25 25 26 26 #include "FrameLoaderTypes.h" 27 #include <wtf/RefPtr.h> 27 28 #include <wtf/Vector.h> 28 29 … … 31 32 class CachedResource; 32 33 class DocLoader; 34 class Frame; 35 36 enum OutlivePagePolicy { 37 DoNotOutlivePage, 38 OutlivePage 39 }; 33 40 34 41 class Request : public Noncopyable { 35 42 public: 36 Request(DocLoader*, CachedResource*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);43 Request(DocLoader*, CachedResource*, bool incremental, SecurityCheckPolicy, OutlivePagePolicy, bool sendResourceLoadCallbacks); 37 44 ~Request(); 38 45 … … 50 57 bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; } 51 58 59 OutlivePagePolicy canOutlivePage() const { return m_frameForRequestThatCanOutlivePage ? OutlivePage : DoNotOutlivePage; } 60 Frame* frame() const; 61 52 62 private: 53 63 Vector<char> m_buffer; … … 58 68 SecurityCheckPolicy m_shouldDoSecurityCheck; 59 69 bool m_sendResourceLoadCallbacks; 70 RefPtr<Frame> m_frameForRequestThatCanOutlivePage; 60 71 }; 61 72 -
trunk/WebCore/loader/SubresourceLoader.cpp
r52177 r52446 62 62 } 63 63 64 PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, SecurityCheckPolicy securityCheck , bool sendResourceLoadCallbacks, bool shouldContentSniff)64 PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, SecurityCheckPolicy securityCheckPolicy, OutlivePagePolicy outlivePagePolicy, bool sendResourceLoadCallbacks, bool shouldContentSniff) 65 65 { 66 66 if (!frame) … … 68 68 69 69 FrameLoader* fl = frame->loader(); 70 if ( securityCheck == DoSecurityCheck&& (fl->state() == FrameStateProvisional || fl->activeDocumentLoader()->isStopping()))70 if (outlivePagePolicy == DoNotOutlivePage && (fl->state() == FrameStateProvisional || fl->activeDocumentLoader()->isStopping())) 71 71 return 0; 72 72 73 73 ResourceRequest newRequest = request; 74 74 75 if (securityCheck == DoSecurityCheck75 if (securityCheckPolicy == DoSecurityCheck 76 76 && SecurityOrigin::restrictAccessToLocal() 77 77 && !SecurityOrigin::canLoad(request.url(), String(), frame->document())) { -
trunk/WebCore/loader/SubresourceLoader.h
r52177 r52446 31 31 32 32 #include "FrameLoaderTypes.h" 33 #include "Request.h" 33 34 #include "ResourceLoader.h" 34 35 … … 40 41 class SubresourceLoader : public ResourceLoader { 41 42 public: 42 static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true);43 static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, SecurityCheckPolicy = DoSecurityCheck, OutlivePagePolicy = DoNotOutlivePage, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true); 43 44 44 45 void clearClient() { m_client = 0; } -
trunk/WebCore/loader/loader.cpp
r52177 r52446 121 121 { 122 122 ASSERT(docLoader); 123 Request* request = new Request(docLoader, resource, incremental, securityCheck, sendResourceLoadCallbacks); 123 124 // If we are loading an image during an unload event, we want to allow the request to outlive the page 125 // that we are leaving. Some sites (most commonly ad networks) rely on image requests in beforeunload 126 // or unload event handlers to track time spent on the page. This will allow them to do the tracking 127 // that they are going to do anyway, but asynchronously so that they don't slow down navigation. 128 OutlivePagePolicy outlivePagePolicy = resource->isImage() && docLoader && docLoader->frame() 129 && docLoader->frame()->loader()->isDispatchingUnloadFamilyEvent() 130 ? OutlivePage : DoNotOutlivePage; 131 132 Request* request = new Request(docLoader, resource, incremental, securityCheck, outlivePagePolicy, sendResourceLoadCallbacks); 124 133 125 134 RefPtr<Host> host; … … 139 148 host->addRequest(request, priority); 140 149 docLoader->incrementRequestCount(); 141 142 if (priority > Low || !url.protocolInHTTPFamily() || !hadRequests) { 150 151 // We want to guarantee that requests which outlive the page are run asynchronously, so only 152 // serve the request immediately if the request doesn't need to outlive the page. 153 if (request->canOutlivePage() == DoNotOutlivePage && (priority > Low || !url.protocolInHTTPFamily() || !hadRequests)) { 143 154 // Try to request important resources immediately 144 155 host->servePendingRequests(priority); … … 249 260 250 261 scheduleServePendingRequests(); 251 252 ASSERT(docLoader->requestCount() == (docLoader->loadInProgress() ? 1 : 0));253 262 } 254 263 … … 347 356 } 348 357 349 RefPtr<SubresourceLoader> loader = SubresourceLoader::create( docLoader->doc()->frame(),350 this, resourceRequest, request->shouldDoSecurityCheck(), request-> sendResourceLoadCallbacks());358 RefPtr<SubresourceLoader> loader = SubresourceLoader::create(request->frame(), 359 this, resourceRequest, request->shouldDoSecurityCheck(), request->canOutlivePage(), request->sendResourceLoadCallbacks()); 351 360 if (loader) { 352 361 m_requestsLoading.add(loader.release(), request); … … 551 560 for (RequestQueue::iterator it = requestsPending.begin(); it != end; ++it) { 552 561 Request* request = *it; 553 if (request-> docLoader() == docLoader) {562 if (request->canOutlivePage() == DoNotOutlivePage && request->docLoader() == docLoader) { 554 563 cache()->remove(request->cachedResource()); 555 564 delete request; … … 571 580 for (RequestMap::iterator i = m_requestsLoading.begin(); i != end; ++i) { 572 581 Request* r = i->second; 573 if (r-> docLoader() == docLoader)582 if (r->canOutlivePage() == DoNotOutlivePage && r->docLoader() == docLoader) 574 583 loadersToCancel.append(i->first.get()); 575 584 }
Note: See TracChangeset
for help on using the changeset viewer.