diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/NavigationScheduler.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/loader/NavigationScheduler.cpp')
-rw-r--r-- | Source/WebCore/loader/NavigationScheduler.cpp | 261 |
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); } |