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 RedirectScheduler::timerFired(Timer<RedirectScheduler>*) { if (!m_frame->page()) return; if (m_frame->page()->defersLoading()) return; OwnPtr<ScheduledRedirection> redirection(m_scheduledRedirection.release()); FrameLoader* loader = m_frame->loader(); switch (redirection->type) { case ScheduledRedirection::redirection: case ScheduledRedirection::locationChange: loader->changeLocation(KURL(ParsedURLString, redirection->url), redirection->referrer, redirection->lockHistory, redirection->lockBackForwardList, redirection->wasUserGesture, redirection->wasRefresh); return; case ScheduledRedirection::historyNavigation: if (redirection->historySteps == 0) { // Special case for go(0) from a frame -> reload only the frame loader->urlSelected(loader->url(), "", 0, redirection->lockHistory, redirection->lockBackForwardList, redirection->wasUserGesture, SendReferrer); return; } // go(i!=0) from a frame navigates into the history of the frame only, // in both IE and NS (but not in Mozilla). We can't easily do that. m_frame->page()->goBackOrForward(redirection->historySteps); return; case ScheduledRedirection::formSubmission: // 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. if (!redirection->formState->sourceFrame()->loader()->shouldAllowNavigation(m_frame)) return; loader->loadFrameRequest(redirection->frameRequest, redirection->lockHistory, redirection->lockBackForwardList, redirection->event, redirection->formState, SendReferrer); return; } ASSERT_NOT_REACHED(); }