Prevent new loads while in PageCache (or being added to PageCache)
https://bugs.webkit.org/show_bug.cgi?id=146299
<rdar://problem/21523788>
Reviewed by Darin Adler.
Generalize the change in r185337 to prevent new loads while in the
PageCache (or being added to the PageCache), instead of merely
preventing new loads in pagehide event handlers. We should never
have any pages that are still loading inside the PageCache.
The fix in r185337 was apparently insufficient to address the
problem so generalizing the check / policy will hopefully catch
more cases where content is able to start loads while being added
to the PageCache. This patch also removes some of the complexity
added in r185337 as it is no longer needed.
No new tests, already covered by:
http/tests/navigation/image-load-in-pagehide-handler.html
http/tests/navigation/subframe-pagehide-handler-starts-load.html
http/tests/navigation/subframe-pagehide-handler-starts-load2.html
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::stopLoading):
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::loadWithDocumentLoader):
(WebCore::FrameLoader::stopAllLoaders):
(WebCore::FrameLoader::handleBeforeUnloadEvent):
(WebCore::FrameLoader::FrameLoader): Deleted.
* loader/FrameLoader.h:
(WebCore::FrameLoader::pageDismissalEventBeingDispatched):
* loader/ImageLoader.cpp:
(WebCore::pageIsBeingDismissed):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::load):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::requestImage):
* page/Page.cpp:
(WebCore::Page::inPageCache):
* page/Page.h:
(WebCore::Page::group): Deleted.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@186005 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 2ef9500..1e49557 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -225,7 +225,6 @@
, m_isExecutingJavaScriptFormAction(false)
, m_didCallImplicitClose(true)
, m_wasUnloadEventEmitted(false)
- , m_pageDismissalEventBeingDispatched(frame)
, m_isComplete(false)
, m_needsClear(false)
, m_checkTimer(*this, &FrameLoader::checkTimerFired)
@@ -424,9 +423,9 @@
Element* currentFocusedElement = m_frame.document()->focusedElement();
if (currentFocusedElement && currentFocusedElement->toInputElement())
currentFocusedElement->toInputElement()->endEditing();
- if (m_pageDismissalEventBeingDispatched == Page::DismissalType::None) {
+ if (m_pageDismissalEventBeingDispatched == PageDismissalType::None) {
if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
- m_pageDismissalEventBeingDispatched = Page::DismissalType::PageHide;
+ m_pageDismissalEventBeingDispatched = PageDismissalType::PageHide;
m_frame.document()->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame.document()->inPageCache()), m_frame.document());
}
@@ -439,7 +438,7 @@
// while dispatching the event, so protect it to prevent writing the end
// time into freed memory.
RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader;
- m_pageDismissalEventBeingDispatched = Page::DismissalType::Unload;
+ m_pageDismissalEventBeingDispatched = PageDismissalType::Unload;
if (documentLoader && !documentLoader->timing().unloadEventStart() && !documentLoader->timing().unloadEventEnd()) {
DocumentLoadTiming& timing = documentLoader->timing();
ASSERT(timing.navigationStart());
@@ -450,7 +449,7 @@
m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
}
}
- m_pageDismissalEventBeingDispatched = Page::DismissalType::None;
+ m_pageDismissalEventBeingDispatched = PageDismissalType::None;
if (m_frame.document())
m_frame.document()->updateStyleIfNeeded();
m_wasUnloadEventEmitted = true;
@@ -1226,7 +1225,7 @@
return;
}
- if (m_pageDismissalEventBeingDispatched != Page::DismissalType::None)
+ if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
return;
NavigationAction action(request, newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy());
@@ -1417,7 +1416,7 @@
ASSERT(m_frame.view());
- if (m_pageDismissalEventBeingDispatched != Page::DismissalType::None)
+ if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
return;
if (m_frame.document())
@@ -1591,7 +1590,7 @@
void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy)
{
ASSERT(!m_frame.document() || !m_frame.document()->inPageCache());
- if (m_pageDismissalEventBeingDispatched != Page::DismissalType::None)
+ if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
return;
// If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
@@ -2847,7 +2846,7 @@
return true;
RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
- m_pageDismissalEventBeingDispatched = Page::DismissalType::BeforeUnload;
+ m_pageDismissalEventBeingDispatched = PageDismissalType::BeforeUnload;
// We store the frame's page in a local variable because the frame might get detached inside dispatchEvent.
Page* page = m_frame.page();
@@ -2855,7 +2854,7 @@
domWindow->dispatchEvent(beforeUnloadEvent.get(), domWindow->document());
page->decrementFrameHandlingBeforeUnloadEventCount();
- m_pageDismissalEventBeingDispatched = Page::DismissalType::None;
+ m_pageDismissalEventBeingDispatched = PageDismissalType::None;
if (!beforeUnloadEvent->defaultPrevented())
document->defaultEventHandler(beforeUnloadEvent.get());
@@ -3553,14 +3552,4 @@
return WTF::move(frame);
}
-auto FrameLoader::PageDismissalEventType::operator=(Page::DismissalType dismissalType) -> PageDismissalEventType&
-{
- m_dismissalEventBeingDispatched = dismissalType;
-
- if (auto* page = m_frame.page())
- page->setDismissalEventBeingDispatched(dismissalType);
-
- return *this;
-}
-
} // namespace WebCore