void RedirectScheduler::scheduleLocationChange(const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool wasUserGesture) { if (!m_frame->page()) return; if (url.isEmpty()) return; lockBackForwardList = 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. KURL parsedURL(ParsedURLString, url); if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(loader->url(), parsedURL)) { loader->changeLocation(loader->completeURL(url), referrer, lockHistory, lockBackForwardList, wasUserGesture); 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->committedFirstRealDocumentLoad(); schedule(new ScheduledLocationChange(url, referrer, lockHistory, lockBackForwardList, wasUserGesture, duringLoad)); }
void NavigationScheduler::scheduleLocationChange(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList) { if (!shouldScheduleNavigation(url)) return; 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. if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame.document()->url(), url)) { ResourceRequest resourceRequest(m_frame.document()->completeURL(url), referrer, UseProtocolCachePolicy); ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow; if (initiatingDocument) shouldOpenExternalURLsPolicy = initiatingDocument->shouldOpenExternalURLsPolicyToPropagate(); FrameLoadRequest frameRequest(securityOrigin, resourceRequest, "_self", lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy); 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(); schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad)); }
void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList) { if (!shouldScheduleNavigation(url)) return; if (url.isEmpty()) return; lockBackForwardList = 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); 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(); schedule(std::make_unique<ScheduledLocationChange>(securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad)); }
void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockBackForwardList) { if (!shouldScheduleNavigation(url)) return; if (url.isEmpty()) return; lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame); // 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. We'll skip this // optimization for cross-origin navigations to minimize the navigator's ability to // execute timing attacks. if (securityOrigin->canAccess(m_frame->document()->securityOrigin())) { KURL parsedURL(ParsedURLString, url); if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame->document()->url(), parsedURL)) { FrameLoadRequest request(securityOrigin, ResourceRequest(m_frame->document()->completeURL(url), referrer), "_self"); request.setLockBackForwardList(lockBackForwardList); request.setClientRedirect(ClientRedirect); m_frame->loader().load(request); return; } } schedule(adoptPtr(new ScheduledLocationChange(securityOrigin, url, referrer, lockBackForwardList))); }
void RedirectScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission) { ASSERT(m_frame->page()); // FIXME: Do we need special handling for form submissions where the URL is the same // as the current one except for the fragment part? See scheduleLocationChange above. // 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(); // 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, UserGestureIndicator::processingUserGesture()) || (submission->state()->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent()); schedule(adoptPtr(new ScheduledFormSubmission(submission, lockBackForwardList, duringLoad))); }
void RedirectScheduler::scheduleFormSubmission(const FrameLoadRequest& frameRequest, bool lockHistory, PassRefPtr<Event> event, PassRefPtr<FormState> formState) { ASSERT(m_frame->page()); ASSERT(!frameRequest.isEmpty()); // FIXME: Do we need special handling for form submissions where the URL is the same // as the current one except for the fragment part? See scheduleLocationChange above. // 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()->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) || (formState->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent()); schedule(new ScheduledFormSubmission(frameRequest, lockHistory, lockBackForwardList, event, formState, duringLoad)); }
void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission) { ASSERT(m_frame.page()); // FIXME: Do we need special handling for form submissions where the URL is the same // as the current one except for the fragment part? See scheduleLocationChange above. // 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(); // 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. LockBackForwardList lockBackForwardList = mustLockBackForwardList(m_frame); if (lockBackForwardList == LockBackForwardList::No && (submission->state()->formSubmissionTrigger() == SubmittedByJavaScript && m_frame.tree().parent() && !ScriptController::processingUserGesture())) { lockBackForwardList = LockBackForwardList::Yes; } schedule(std::make_unique<ScheduledFormSubmission>(submission, lockBackForwardList, duringLoad)); }
void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission) { ASSERT(m_frame->page()); schedule(adoptPtr(new ScheduledFormSubmission(submission, mustLockBackForwardList(m_frame)))); }