summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/NavigationScheduler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader/NavigationScheduler.cpp')
-rw-r--r--Source/WebCore/loader/NavigationScheduler.cpp261
1 files changed, 167 insertions, 94 deletions
diff --git a/Source/WebCore/loader/NavigationScheduler.cpp b/Source/WebCore/loader/NavigationScheduler.cpp
index 7a6351639..0f0290c11 100644
--- a/Source/WebCore/loader/NavigationScheduler.cpp
+++ b/Source/WebCore/loader/NavigationScheduler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2009 Adam Barth. All rights reserved.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -46,6 +46,7 @@
#include "HTMLFrameOwnerElement.h"
#include "HistoryItem.h"
#include "InspectorInstrumentation.h"
+#include "Logging.h"
#include "Page.h"
#include "ScriptController.h"
#include "UserGestureIndicator.h"
@@ -54,18 +55,28 @@
namespace WebCore {
-unsigned NavigationDisablerForBeforeUnload::s_navigationDisableCount = 0;
+unsigned NavigationDisabler::s_navigationDisableCount = 0;
class ScheduledNavigation {
WTF_MAKE_NONCOPYABLE(ScheduledNavigation); WTF_MAKE_FAST_ALLOCATED;
public:
- ScheduledNavigation(double delay, bool lockHistory, bool lockBackForwardList, bool wasDuringLoad, bool isLocationChange)
+ ScheduledNavigation(double delay, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool wasDuringLoad, bool isLocationChange)
: m_delay(delay)
, m_lockHistory(lockHistory)
, m_lockBackForwardList(lockBackForwardList)
, m_wasDuringLoad(wasDuringLoad)
, m_isLocationChange(isLocationChange)
- , m_wasUserGesture(ScriptController::processingUserGesture())
+ , m_userGestureToForward(UserGestureIndicator::currentUserGesture())
+ {
+ }
+ ScheduledNavigation(double delay, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool wasDuringLoad, bool isLocationChange, ShouldOpenExternalURLsPolicy externalURLPolicy)
+ : m_delay(delay)
+ , m_lockHistory(lockHistory)
+ , m_lockBackForwardList(lockBackForwardList)
+ , m_wasDuringLoad(wasDuringLoad)
+ , m_isLocationChange(isLocationChange)
+ , m_userGestureToForward(UserGestureIndicator::currentUserGesture())
+ , m_shouldOpenExternalURLsPolicy(externalURLPolicy)
{
}
virtual ~ScheduledNavigation() { }
@@ -73,56 +84,61 @@ public:
virtual void fire(Frame&) = 0;
virtual bool shouldStartTimer(Frame&) { return true; }
- virtual void didStartTimer(Frame&, Timer<NavigationScheduler>&) { }
+ virtual void didStartTimer(Frame&, Timer&) { }
virtual void didStopTimer(Frame&, bool /* newLoadInProgress */) { }
double delay() const { return m_delay; }
- bool lockHistory() const { return m_lockHistory; }
- bool lockBackForwardList() const { return m_lockBackForwardList; }
+ LockHistory lockHistory() const { return m_lockHistory; }
+ LockBackForwardList lockBackForwardList() const { return m_lockBackForwardList; }
bool wasDuringLoad() const { return m_wasDuringLoad; }
bool isLocationChange() const { return m_isLocationChange; }
- bool wasUserGesture() const { return m_wasUserGesture; }
+ UserGestureToken* userGestureToForward() const { return m_userGestureToForward.get(); }
protected:
- void clearUserGesture() { m_wasUserGesture = false; }
+ void clearUserGesture() { m_userGestureToForward = nullptr; }
+ ShouldOpenExternalURLsPolicy shouldOpenExternalURLs() const { return m_shouldOpenExternalURLsPolicy; }
private:
double m_delay;
- bool m_lockHistory;
- bool m_lockBackForwardList;
+ LockHistory m_lockHistory;
+ LockBackForwardList m_lockBackForwardList;
bool m_wasDuringLoad;
bool m_isLocationChange;
- bool m_wasUserGesture;
+ RefPtr<UserGestureToken> m_userGestureToForward;
+ ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
};
class ScheduledURLNavigation : public ScheduledNavigation {
protected:
- ScheduledURLNavigation(double delay, SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool duringLoad, bool isLocationChange)
- : ScheduledNavigation(delay, lockHistory, lockBackForwardList, duringLoad, isLocationChange)
+ ScheduledURLNavigation(Document& initiatingDocument, double delay, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, bool isLocationChange)
+ : ScheduledNavigation(delay, lockHistory, lockBackForwardList, duringLoad, isLocationChange, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate())
, m_securityOrigin(securityOrigin)
, m_url(url)
, m_referrer(referrer)
- , m_haveToldClient(false)
{
}
- virtual void fire(Frame& frame) override
+ void fire(Frame& frame) override
{
- UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
- frame.loader().changeLocation(m_securityOrigin.get(), URL(ParsedURLString, m_url), m_referrer, lockHistory(), lockBackForwardList(), false);
+ UserGestureIndicator gestureIndicator(userGestureToForward());
+
+ ResourceRequest resourceRequest(m_url, m_referrer, UseProtocolCachePolicy);
+ FrameLoadRequest frameRequest(*m_securityOrigin, resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
+
+ frame.loader().changeLocation(frameRequest);
}
- virtual void didStartTimer(Frame& frame, Timer<NavigationScheduler>& timer) override
+ void didStartTimer(Frame& frame, Timer& timer) override
{
if (m_haveToldClient)
return;
m_haveToldClient = true;
- UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
- frame.loader().clientRedirected(URL(ParsedURLString, m_url), delay(), currentTime() + timer.nextFireInterval(), lockBackForwardList());
+ UserGestureIndicator gestureIndicator(userGestureToForward());
+ frame.loader().clientRedirected(m_url, delay(), currentTime() + timer.nextFireInterval(), lockBackForwardList());
}
- virtual void didStopTimer(Frame& frame, bool newLoadInProgress) override
+ void didStopTimer(Frame& frame, bool newLoadInProgress) override
{
if (!m_haveToldClient)
return;
@@ -137,73 +153,88 @@ protected:
}
SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
- String url() const { return m_url; }
+ const URL& url() const { return m_url; }
String referrer() const { return m_referrer; }
private:
RefPtr<SecurityOrigin> m_securityOrigin;
- String m_url;
+ URL m_url;
String m_referrer;
- bool m_haveToldClient;
+ bool m_haveToldClient { false };
};
class ScheduledRedirect : public ScheduledURLNavigation {
public:
- ScheduledRedirect(double delay, SecurityOrigin* securityOrigin, const String& url, bool lockHistory, bool lockBackForwardList)
- : ScheduledURLNavigation(delay, securityOrigin, url, String(), lockHistory, lockBackForwardList, false, false)
+ ScheduledRedirect(Document& initiatingDocument, double delay, SecurityOrigin* securityOrigin, const URL& url, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
+ : ScheduledURLNavigation(initiatingDocument, delay, securityOrigin, url, String(), lockHistory, lockBackForwardList, false, false)
{
clearUserGesture();
}
- virtual bool shouldStartTimer(Frame& frame) override
+ bool shouldStartTimer(Frame& frame) override
{
return frame.loader().allAncestorsAreComplete();
}
- virtual void fire(Frame& frame) override
+ void fire(Frame& frame) override
{
- UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
- bool refresh = equalIgnoringFragmentIdentifier(frame.document()->url(), URL(ParsedURLString, url()));
- frame.loader().changeLocation(securityOrigin(), URL(ParsedURLString, url()), referrer(), lockHistory(), lockBackForwardList(), refresh);
+ UserGestureIndicator gestureIndicator(userGestureToForward());
+ bool refresh = equalIgnoringFragmentIdentifier(frame.document()->url(), url());
+ ResourceRequest resourceRequest(url(), referrer(), refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy);
+ FrameLoadRequest frameRequest(*securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
+
+ frame.loader().changeLocation(frameRequest);
}
};
class ScheduledLocationChange : public ScheduledURLNavigation {
public:
- ScheduledLocationChange(SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool duringLoad)
- : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { }
+ ScheduledLocationChange(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad)
+ : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { }
+
+ void fire(Frame& frame) override
+ {
+ UserGestureIndicator gestureIndicator(userGestureToForward());
+
+ ResourceRequest resourceRequest(url(), referrer(), UseProtocolCachePolicy);
+ FrameLoadRequest frameRequest(*securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
+ frame.loader().changeLocation(frameRequest);
+ }
};
class ScheduledRefresh : public ScheduledURLNavigation {
public:
- ScheduledRefresh(SecurityOrigin* securityOrigin, const String& url, const String& referrer)
- : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, true, true, false, true)
+ ScheduledRefresh(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer)
+ : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, LockHistory::Yes, LockBackForwardList::Yes, false, true)
{
}
- virtual void fire(Frame& frame) override
+ void fire(Frame& frame) override
{
- UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
- frame.loader().changeLocation(securityOrigin(), URL(ParsedURLString, url()), referrer(), lockHistory(), lockBackForwardList(), true);
+ UserGestureIndicator gestureIndicator(userGestureToForward());
+
+ ResourceRequest resourceRequest(url(), referrer(), ReloadIgnoringCacheData);
+ FrameLoadRequest frameRequest(*securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
+ frame.loader().changeLocation(frameRequest);
}
};
class ScheduledHistoryNavigation : public ScheduledNavigation {
public:
explicit ScheduledHistoryNavigation(int historySteps)
- : ScheduledNavigation(0, false, false, false, true)
+ : ScheduledNavigation(0, LockHistory::No, LockBackForwardList::No, false, true)
, m_historySteps(historySteps)
{
}
- virtual void fire(Frame& frame) override
+ void fire(Frame& frame) override
{
- UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
+ UserGestureIndicator gestureIndicator(userGestureToForward());
if (!m_historySteps) {
// Special case for go(0) from a frame -> reload only the frame
// To follow Firefox and IE's behavior, history reload can only navigate the self frame.
- frame.loader().urlSelected(frame.document()->url(), "_self", 0, lockHistory(), lockBackForwardList(), MaybeSendReferrer);
+ frame.loader().urlSelected(frame.document()->url(), "_self", 0, lockHistory(), lockBackForwardList(), MaybeSendReferrer, shouldOpenExternalURLs());
return;
}
@@ -218,41 +249,39 @@ private:
class ScheduledFormSubmission : public ScheduledNavigation {
public:
- ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBackForwardList, bool duringLoad)
- : ScheduledNavigation(0, submission->lockHistory(), lockBackForwardList, duringLoad, true)
- , m_submission(submission)
- , m_haveToldClient(false)
+ ScheduledFormSubmission(Ref<FormSubmission>&& submission, LockBackForwardList lockBackForwardList, bool duringLoad)
+ : ScheduledNavigation(0, submission->lockHistory(), lockBackForwardList, duringLoad, true, submission->state().sourceDocument().shouldOpenExternalURLsPolicyToPropagate())
+ , m_submission(WTFMove(submission))
{
- ASSERT(m_submission->state());
}
- virtual void fire(Frame& frame) override
+ void fire(Frame& frame) override
{
- UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
+ UserGestureIndicator gestureIndicator(userGestureToForward());
// The submitForm function will find a target frame before using the redirection timer.
// Now that the timer has fired, we need to repeat the security check which normally is done when
// selecting a target, in case conditions have changed. Other code paths avoid this by targeting
// without leaving a time window. If we fail the check just silently drop the form submission.
- Document* requestingDocument = m_submission->state()->sourceDocument();
- if (!requestingDocument->canNavigate(&frame))
+ auto& requestingDocument = m_submission->state().sourceDocument();
+ if (!requestingDocument.canNavigate(&frame))
return;
- FrameLoadRequest frameRequest(requestingDocument->securityOrigin());
+ FrameLoadRequest frameRequest(requestingDocument.securityOrigin(), lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
m_submission->populateFrameLoadRequest(frameRequest);
- frame.loader().loadFrameRequest(frameRequest, lockHistory(), lockBackForwardList(), m_submission->event(), m_submission->state(), MaybeSendReferrer);
+ frame.loader().loadFrameRequest(frameRequest, m_submission->event(), &m_submission->state());
}
-
- virtual void didStartTimer(Frame& frame, Timer<NavigationScheduler>& timer) override
+
+ void didStartTimer(Frame& frame, Timer& timer) override
{
if (m_haveToldClient)
return;
m_haveToldClient = true;
- UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
+ UserGestureIndicator gestureIndicator(userGestureToForward());
frame.loader().clientRedirected(m_submission->requestURL(), delay(), currentTime() + timer.nextFireInterval(), lockBackForwardList());
}
- virtual void didStopTimer(Frame& frame, bool newLoadInProgress) override
+ void didStopTimer(Frame& frame, bool newLoadInProgress) override
{
if (!m_haveToldClient)
return;
@@ -267,13 +296,38 @@ public:
}
private:
- RefPtr<FormSubmission> m_submission;
- bool m_haveToldClient;
+ Ref<FormSubmission> m_submission;
+ bool m_haveToldClient { false };
+};
+
+class ScheduledPageBlock final : public ScheduledNavigation {
+public:
+ ScheduledPageBlock(Document& originDocument)
+ : ScheduledNavigation(0, LockHistory::Yes, LockBackForwardList::Yes, false, false)
+ , m_originDocument(originDocument)
+ {
+ }
+
+ void fire(Frame& frame) override
+ {
+ UserGestureIndicator gestureIndicator(userGestureToForward());
+
+ ResourceResponse replacementResponse(m_originDocument.url(), ASCIILiteral("text/plain"), 0, ASCIILiteral("UTF-8"));
+ SubstituteData replacementData(SharedBuffer::create(), m_originDocument.url(), replacementResponse, SubstituteData::SessionHistoryVisibility::Hidden);
+
+ ResourceRequest resourceRequest(m_originDocument.url(), emptyString(), ReloadIgnoringCacheData);
+ FrameLoadRequest frameRequest(m_originDocument.securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
+ frameRequest.setSubstituteData(replacementData);
+ frame.loader().load(frameRequest);
+ }
+
+private:
+ Document& m_originDocument;
};
NavigationScheduler::NavigationScheduler(Frame& frame)
: m_frame(frame)
- , m_timer(this, &NavigationScheduler::timerFired)
+ , m_timer(*this, &NavigationScheduler::timerFired)
{
}
@@ -304,12 +358,16 @@ inline bool NavigationScheduler::shouldScheduleNavigation() const
return m_frame.page();
}
-inline bool NavigationScheduler::shouldScheduleNavigation(const String& url) const
+inline bool NavigationScheduler::shouldScheduleNavigation(const URL& url) const
{
- return shouldScheduleNavigation() && (protocolIsJavaScript(url) || NavigationDisablerForBeforeUnload::isNavigationAllowed());
+ if (!shouldScheduleNavigation())
+ return false;
+ if (protocolIsJavaScript(url))
+ return true;
+ return NavigationDisabler::isNavigationAllowed();
}
-void NavigationScheduler::scheduleRedirect(double delay, const String& url)
+void NavigationScheduler::scheduleRedirect(Document& initiatingDocument, double delay, const URL& url)
{
if (!shouldScheduleNavigation(url))
return;
@@ -319,16 +377,18 @@ void NavigationScheduler::scheduleRedirect(double delay, const String& url)
return;
// We want a new back/forward list item if the refresh timeout is > 1 second.
- if (!m_redirect || delay <= m_redirect->delay())
- schedule(std::make_unique<ScheduledRedirect>(delay, m_frame.document()->securityOrigin(), url, true, delay <= 1));
+ if (!m_redirect || delay <= m_redirect->delay()) {
+ auto lockBackForwardList = delay <= 1 ? LockBackForwardList::Yes : LockBackForwardList::No;
+ schedule(std::make_unique<ScheduledRedirect>(initiatingDocument, delay, &m_frame.document()->securityOrigin(), url, LockHistory::Yes, lockBackForwardList));
+ }
}
-bool NavigationScheduler::mustLockBackForwardList(Frame& targetFrame)
+LockBackForwardList NavigationScheduler::mustLockBackForwardList(Frame& targetFrame)
{
// Non-user navigation before the page has finished firing onload should not create a new back/forward item.
// See https://webkit.org/b/42861 for the original motivation for this.
- if (!ScriptController::processingUserGesture() && targetFrame.loader().documentLoader() && !targetFrame.loader().documentLoader()->wasOnloadHandled())
- return true;
+ if (!UserGestureIndicator::processingUserGesture() && targetFrame.loader().documentLoader() && !targetFrame.loader().documentLoader()->wasOnloadDispatched())
+ return LockBackForwardList::Yes;
// Navigation of a subframe during loading of an ancestor frame does not create a new back/forward item.
// The definition of "during load" is any time before all handlers for the load event have been run.
@@ -336,38 +396,38 @@ bool NavigationScheduler::mustLockBackForwardList(Frame& targetFrame)
for (Frame* ancestor = targetFrame.tree().parent(); ancestor; ancestor = ancestor->tree().parent()) {
Document* document = ancestor->document();
if (!ancestor->loader().isComplete() || (document && document->processingLoadEvent()))
- return true;
+ return LockBackForwardList::Yes;
}
- return false;
+ return LockBackForwardList::No;
}
-void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList)
+void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, SecurityOrigin& securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
{
if (!shouldScheduleNavigation(url))
return;
- if (url.isEmpty())
- return;
- lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame);
+ if (lockBackForwardList == LockBackForwardList::No)
+ lockBackForwardList = mustLockBackForwardList(m_frame);
FrameLoader& loader = m_frame.loader();
// If the URL we're going to navigate to is the same as the current one, except for the
// fragment part, we don't need to schedule the location change.
- URL parsedURL(ParsedURLString, url);
- if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame.document()->url(), parsedURL)) {
- loader.changeLocation(securityOrigin, m_frame.document()->completeURL(url), referrer, lockHistory, lockBackForwardList);
+ if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame.document()->url(), url)) {
+ ResourceRequest resourceRequest(m_frame.document()->completeURL(url), referrer, UseProtocolCachePolicy);
+ FrameLoadRequest frameRequest(securityOrigin, resourceRequest, "_self", lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate());
+ loader.changeLocation(frameRequest);
return;
}
// Handle a location change of a page with no document as a special case.
// This may happen when a frame changes the location of another frame.
- bool duringLoad = !loader.stateMachine()->committedFirstRealDocumentLoad();
+ bool duringLoad = !loader.stateMachine().committedFirstRealDocumentLoad();
- schedule(std::make_unique<ScheduledLocationChange>(securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
+ schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, &securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
}
-void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission)
+void NavigationScheduler::scheduleFormSubmission(Ref<FormSubmission>&& submission)
{
ASSERT(m_frame.page());
@@ -376,19 +436,21 @@ void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> subm
// Handle a location change of a page with no document as a special case.
// This may happen when a frame changes the location of another frame.
- bool duringLoad = !m_frame.loader().stateMachine()->committedFirstRealDocumentLoad();
+ bool duringLoad = !m_frame.loader().stateMachine().committedFirstRealDocumentLoad();
// If this is a child frame and the form submission was triggered by a script, lock the back/forward list
// to match IE and Opera.
// See https://bugs.webkit.org/show_bug.cgi?id=32383 for the original motivation for this.
- bool lockBackForwardList = mustLockBackForwardList(m_frame)
- || (submission->state()->formSubmissionTrigger() == SubmittedByJavaScript
- && m_frame.tree().parent() && !ScriptController::processingUserGesture());
-
- schedule(std::make_unique<ScheduledFormSubmission>(submission, lockBackForwardList, duringLoad));
+ LockBackForwardList lockBackForwardList = mustLockBackForwardList(m_frame);
+ if (lockBackForwardList == LockBackForwardList::No
+ && (submission->state().formSubmissionTrigger() == SubmittedByJavaScript && m_frame.tree().parent() && !UserGestureIndicator::processingUserGesture())) {
+ lockBackForwardList = LockBackForwardList::Yes;
+ }
+
+ schedule(std::make_unique<ScheduledFormSubmission>(WTFMove(submission), lockBackForwardList, duringLoad));
}
-void NavigationScheduler::scheduleRefresh()
+void NavigationScheduler::scheduleRefresh(Document& initiatingDocument)
{
if (!shouldScheduleNavigation())
return;
@@ -396,11 +458,12 @@ void NavigationScheduler::scheduleRefresh()
if (url.isEmpty())
return;
- schedule(std::make_unique<ScheduledRefresh>(m_frame.document()->securityOrigin(), url.string(), m_frame.loader().outgoingReferrer()));
+ schedule(std::make_unique<ScheduledRefresh>(initiatingDocument, &m_frame.document()->securityOrigin(), url, m_frame.loader().outgoingReferrer()));
}
void NavigationScheduler::scheduleHistoryNavigation(int steps)
{
+ LOG(History, "NavigationScheduler %p scheduleHistoryNavigation(%d) - shouldSchedule %d", this, steps, shouldScheduleNavigation());
if (!shouldScheduleNavigation())
return;
@@ -416,7 +479,13 @@ void NavigationScheduler::scheduleHistoryNavigation(int steps)
schedule(std::make_unique<ScheduledHistoryNavigation>(steps));
}
-void NavigationScheduler::timerFired(Timer<NavigationScheduler>&)
+void NavigationScheduler::schedulePageBlock(Document& originDocument)
+{
+ if (shouldScheduleNavigation())
+ schedule(std::make_unique<ScheduledPageBlock>(originDocument));
+}
+
+void NavigationScheduler::timerFired()
{
if (!m_frame.page())
return;
@@ -427,7 +496,9 @@ void NavigationScheduler::timerFired(Timer<NavigationScheduler>&)
Ref<Frame> protect(m_frame);
- std::unique_ptr<ScheduledNavigation> redirect = std::move(m_redirect);
+ std::unique_ptr<ScheduledNavigation> redirect = WTFMove(m_redirect);
+ LOG(History, "NavigationScheduler %p timerFired - firing redirect %p", this, redirect.get());
+
redirect->fire(m_frame);
InspectorInstrumentation::frameClearedScheduledNavigation(m_frame);
}
@@ -448,7 +519,7 @@ void NavigationScheduler::schedule(std::unique_ptr<ScheduledNavigation> redirect
}
cancel();
- m_redirect = std::move(redirect);
+ m_redirect = WTFMove(redirect);
if (!m_frame.loader().isComplete() && m_redirect->isLocationChange())
m_frame.loader().completed();
@@ -478,11 +549,13 @@ void NavigationScheduler::startTimer()
void NavigationScheduler::cancel(bool newLoadInProgress)
{
+ LOG(History, "NavigationScheduler %p cancel(newLoadInProgress=%d)", this, newLoadInProgress);
+
if (m_timer.isActive())
InspectorInstrumentation::frameClearedScheduledNavigation(m_frame);
m_timer.stop();
- if (std::unique_ptr<ScheduledNavigation> redirect = std::move(m_redirect))
+ if (std::unique_ptr<ScheduledNavigation> redirect = WTFMove(m_redirect))
redirect->didStopTimer(m_frame, newLoadInProgress);
}