diff options
author | Jocelyn Turcotte <jocelyn.turcotte@nokia.com> | 2009-10-22 17:50:52 (GMT) |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@nokia.com> | 2009-10-22 18:34:20 (GMT) |
commit | 57f1983c164bc8553c6b6aa7ac320f00e5405548 (patch) | |
tree | 6cfbec33f6e385ceb5cbfa0168f4a9f27f0c8e57 /src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp | |
parent | 5baebfc68dd67def412bcbaa7c61b43d05e6ee42 (diff) | |
download | Qt-57f1983c164bc8553c6b6aa7ac320f00e5405548.zip Qt-57f1983c164bc8553c6b6aa7ac320f00e5405548.tar.gz Qt-57f1983c164bc8553c6b6aa7ac320f00e5405548.tar.bz2 |
Updated WebKit from /home/jturcott/dev/webkit/ to qtwebkit-4.6-snapshot-22102009 ( 0639bb8e812c8923287cd5523248ca64fa5f7a50 )
Changes in WebKit/qt since the last update:
Jocelyn: fatal error from script, sha1 in src/3rdparty/webkit/VERSION is bad
Diffstat (limited to 'src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp | 1735 |
1 files changed, 168 insertions, 1567 deletions
diff --git a/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp b/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp index 93a1f10..df46397 100644 --- a/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp +++ b/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp @@ -55,6 +55,7 @@ #include "FrameLoaderClient.h" #include "FrameTree.h" #include "FrameView.h" +#include "HTMLAnchorElement.h" #include "HTMLAppletElement.h" #include "HTMLFormElement.h" #include "HTMLFrameElement.h" @@ -123,96 +124,12 @@ using namespace SVGNames; #endif using namespace HTMLNames; -struct ScheduledRedirection { - enum Type { redirection, locationChange, historyNavigation, formSubmission }; - - const Type type; - const double delay; - const String url; - const String referrer; - const FrameLoadRequest frameRequest; - const RefPtr<Event> event; - const RefPtr<FormState> formState; - const int historySteps; - const bool lockHistory; - const bool lockBackForwardList; - const bool wasUserGesture; - const bool wasRefresh; - const bool wasDuringLoad; - bool toldClient; - - ScheduledRedirection(double delay, const String& url, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool refresh) - : type(redirection) - , delay(delay) - , url(url) - , historySteps(0) - , lockHistory(lockHistory) - , lockBackForwardList(lockBackForwardList) - , wasUserGesture(wasUserGesture) - , wasRefresh(refresh) - , wasDuringLoad(false) - , toldClient(false) - { - ASSERT(!url.isEmpty()); - } - - ScheduledRedirection(const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool refresh, bool duringLoad) - : type(locationChange) - , delay(0) - , url(url) - , referrer(referrer) - , historySteps(0) - , lockHistory(lockHistory) - , lockBackForwardList(lockBackForwardList) - , wasUserGesture(wasUserGesture) - , wasRefresh(refresh) - , wasDuringLoad(duringLoad) - , toldClient(false) - { - ASSERT(!url.isEmpty()); - } - - explicit ScheduledRedirection(int historyNavigationSteps) - : type(historyNavigation) - , delay(0) - , historySteps(historyNavigationSteps) - , lockHistory(false) - , lockBackForwardList(false) - , wasUserGesture(false) - , wasRefresh(false) - , wasDuringLoad(false) - , toldClient(false) - { - } - - ScheduledRedirection(const FrameLoadRequest& frameRequest, - bool lockHistory, bool lockBackForwardList, PassRefPtr<Event> event, PassRefPtr<FormState> formState, - bool duringLoad) - : type(formSubmission) - , delay(0) - , frameRequest(frameRequest) - , event(event) - , formState(formState) - , historySteps(0) - , lockHistory(lockHistory) - , lockBackForwardList(lockBackForwardList) - , wasUserGesture(false) - , wasRefresh(false) - , wasDuringLoad(duringLoad) - , toldClient(false) - { - ASSERT(!frameRequest.isEmpty()); - ASSERT(this->formState); - } -}; - #if ENABLE(XHTMLMP) static const char defaultAcceptHeader[] = "application/xml,application/vnd.wap.xhtml+xml,application/xhtml+xml;profile='http://www.wapforum.org/xhtml',text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; #else static const char defaultAcceptHeader[] = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; #endif static double storedTimeOfLastCompletedLoad; -static FrameLoader::LocalLoadPolicy localLoadPolicy = FrameLoader::AllowLocalLoadsForLocalOnly; bool isBackForwardLoadType(FrameLoadType type) { @@ -250,39 +167,36 @@ static inline bool canReferToParentFrameEncoding(const Frame* frame, const Frame FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) : m_frame(frame) , m_client(client) + , m_policyChecker(frame) + , m_history(frame) + , m_notifer(frame) , m_state(FrameStateCommittedPage) , m_loadType(FrameLoadTypeStandard) - , m_policyLoadType(FrameLoadTypeStandard) , m_delegateIsHandlingProvisionalLoadError(false) - , m_delegateIsDecidingNavigationPolicy(false) - , m_delegateIsHandlingUnimplementablePolicy(false) , m_firstLayoutDone(false) , m_quickRedirectComing(false) , m_sentRedirectNotification(false) , m_inStopAllLoaders(false) , m_isExecutingJavaScriptFormAction(false) - , m_isRunningScript(false) , m_didCallImplicitClose(false) , m_wasUnloadEventEmitted(false) , m_unloadEventBeingDispatched(false) , m_isComplete(false) , m_isLoadingMainResource(false) - , m_cancellingWithLoadInProgress(false) , m_needsClear(false) , m_receivedData(false) , m_encodingWasChosenByUser(false) , m_containsPlugIns(false) - , m_redirectionTimer(this, &FrameLoader::redirectionTimerFired) , m_checkTimer(this, &FrameLoader::checkTimerFired) , m_shouldCallCheckCompleted(false) , m_shouldCallCheckLoadComplete(false) , m_opener(0) - , m_openedByDOM(false) , m_creatingInitialEmptyDocument(false) , m_isDisplayingInitialEmptyDocument(false) , m_committedFirstRealDocumentLoad(false) , m_didPerformFirstNavigation(false) , m_loadingFromCachedPage(false) + , m_suppressOpenerInNewFrame(false) #ifndef NDEBUG , m_didDispatchDidCommitLoad(false) #endif @@ -327,7 +241,7 @@ void FrameLoader::setDefersLoading(bool defers) m_policyDocumentLoader->setDefersLoading(defers); if (!defers) { - startRedirectionTimer(); + m_frame->redirectScheduler()->startTimer(); startCheckCompleteTimer(); } } @@ -340,7 +254,7 @@ Frame* FrameLoader::createWindow(FrameLoader* frameLoaderForFrameLookup, const F Frame* frame = frameLoaderForFrameLookup->frame()->tree()->find(request.frameName()); if (frame && shouldAllowNavigation(frame)) { if (!request.resourceRequest().url().isEmpty()) - frame->loader()->loadFrameRequest(request, false, false, 0, 0); + frame->loader()->loadFrameRequest(request, false, false, 0, 0, SendReferrer); if (Page* page = frame->page()) page->chrome()->focus(); created = false; @@ -404,15 +318,17 @@ void FrameLoader::changeLocation(const KURL& url, const String& referrer, bool l ResourceRequest request(url, referrer, refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy); - if (executeIfJavaScriptURL(request.url(), userGesture)) + if (m_frame->script()->executeIfJavaScriptURL(request.url(), userGesture)) return; - urlSelected(request, "_self", 0, lockHistory, lockBackForwardList, userGesture); + urlSelected(request, "_self", 0, lockHistory, lockBackForwardList, userGesture, SendReferrer); } -void FrameLoader::urlSelected(const ResourceRequest& request, const String& passedTarget, PassRefPtr<Event> triggeringEvent, bool lockHistory, bool lockBackForwardList, bool userGesture) +void FrameLoader::urlSelected(const ResourceRequest& request, const String& passedTarget, PassRefPtr<Event> triggeringEvent, bool lockHistory, bool lockBackForwardList, bool userGesture, ReferrerPolicy referrerPolicy) { - if (executeIfJavaScriptURL(request.url(), userGesture, false)) + ASSERT(!m_suppressOpenerInNewFrame); + + if (m_frame->script()->executeIfJavaScriptURL(request.url(), userGesture, false)) return; String target = passedTarget; @@ -421,11 +337,16 @@ void FrameLoader::urlSelected(const ResourceRequest& request, const String& pass FrameLoadRequest frameRequest(request, target); - if (frameRequest.resourceRequest().httpReferrer().isEmpty()) + if (referrerPolicy == NoReferrer) { + m_suppressOpenerInNewFrame = true; + setOpener(0); + } else if (frameRequest.resourceRequest().httpReferrer().isEmpty()) frameRequest.resourceRequest().setHTTPReferrer(m_outgoingReferrer); addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin()); - loadFrameRequest(frameRequest, lockHistory, lockBackForwardList, triggeringEvent, 0); + loadFrameRequest(frameRequest, lockHistory, lockBackForwardList, triggeringEvent, 0, referrerPolicy); + + m_suppressOpenerInNewFrame = false; } bool FrameLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String& urlString, const AtomicString& frameName) @@ -441,7 +362,7 @@ bool FrameLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String Frame* frame = ownerElement->contentFrame(); if (frame) - frame->loader()->scheduleLocationChange(url.string(), m_outgoingReferrer, true, true, isProcessingUserGesture()); + frame->redirectScheduler()->scheduleLocationChange(url.string(), m_outgoingReferrer, true, true, isProcessingUserGesture()); else frame = loadSubframe(ownerElement, url, frameName, m_outgoingReferrer); @@ -449,7 +370,7 @@ bool FrameLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String return false; if (!scriptURL.isEmpty()) - frame->loader()->executeIfJavaScriptURL(scriptURL); + frame->script()->executeIfJavaScriptURL(scriptURL); return true; } @@ -466,12 +387,12 @@ Frame* FrameLoader::loadSubframe(HTMLFrameOwnerElement* ownerElement, const KURL marginHeight = o->getMarginHeight(); } - if (!canLoad(url, referrer)) { + if (!SecurityOrigin::canLoad(url, referrer, 0)) { FrameLoader::reportLocalLoadFailed(m_frame, url.string()); return 0; } - bool hideReferrer = shouldHideReferrer(url, referrer); + bool hideReferrer = SecurityOrigin::shouldHideReferrer(url, referrer); RefPtr<Frame> frame = m_client->createFrame(url, name, ownerElement, hideReferrer ? String() : referrer, allowsScrolling, marginWidth, marginHeight); if (!frame) { @@ -521,7 +442,7 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F if (protocolIsJavaScript(u)) { m_isExecutingJavaScriptFormAction = true; - executeIfJavaScriptURL(u, false, false); + m_frame->script()->executeIfJavaScriptURL(u, false, false); m_isExecutingJavaScriptFormAction = false; return; } @@ -576,7 +497,7 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F frameRequest.resourceRequest().setURL(u); addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin()); - targetFrame->loader()->scheduleFormSubmission(frameRequest, lockHistory, event, formState); + targetFrame->redirectScheduler()->scheduleFormSubmission(frameRequest, lockHistory, event, formState); } void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolicy databasePolicy) @@ -605,8 +526,14 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic } // Dispatching the unload event could have made m_frame->document() null. - if (m_frame->document() && !m_frame->document()->inPageCache()) - m_frame->document()->removeAllEventListeners(); + if (m_frame->document() && !m_frame->document()->inPageCache()) { + // Don't remove event listeners from a transitional empty document (see bug 28716 for more information). + bool keepEventListeners = m_isDisplayingInitialEmptyDocument && m_provisionalDocumentLoader + && m_frame->document()->securityOrigin()->isSecureTransitionTo(m_provisionalDocumentLoader->url()); + + if (!keepEventListeners) + m_frame->document()->removeAllEventListeners(); + } } m_isComplete = true; // to avoid calling completed() in finishedParsing() @@ -634,7 +561,7 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) child->loader()->stopLoading(unloadEventPolicy); - cancelRedirection(); + m_frame->redirectScheduler()->cancel(); } void FrameLoader::stop() @@ -653,7 +580,7 @@ void FrameLoader::stop() bool FrameLoader::closeURL() { - saveDocumentState(); + history()->saveDocumentState(); // Should only send the pagehide event here if the current document exists and has not been placed in the page cache. Document* currentDocument = m_frame->document(); @@ -663,13 +590,6 @@ bool FrameLoader::closeURL() return true; } -void FrameLoader::cancelRedirection(bool cancelWithLoadInProgress) -{ - m_cancellingWithLoadInProgress = cancelWithLoadInProgress; - - stopRedirectionTimer(); -} - KURL FrameLoader::iconURL() { // If this isn't a top level frame, return nothing @@ -695,15 +615,14 @@ KURL FrameLoader::iconURL() bool FrameLoader::didOpenURL(const KURL& url) { - if (m_scheduledRedirection && m_scheduledRedirection->wasDuringLoad) { + if (m_frame->redirectScheduler()->redirectScheduledDuringLoad()) { // A redirect was scheduled before the document was created. // This can happen when one frame changes another frame's location. return false; } - cancelRedirection(); + m_frame->redirectScheduler()->cancel(); m_frame->editor()->clearLastEditCommand(); - closeURL(); m_isComplete = false; m_isLoadingMainResource = true; @@ -738,71 +657,15 @@ void FrameLoader::didExplicitOpen() // from a subsequent window.document.open / window.document.write call. // Cancelling redirection here works for all cases because document.open // implicitly precedes document.write. - cancelRedirection(); + m_frame->redirectScheduler()->cancel(); if (m_frame->document()->url() != blankURL()) m_URL = m_frame->document()->url(); } -bool FrameLoader::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool replaceDocument) -{ - if (!protocolIsJavaScript(url)) - return false; - - if (m_frame->page() && !m_frame->page()->javaScriptURLsAreAllowed()) - return true; - - const int javascriptSchemeLength = sizeof("javascript:") - 1; - - String script = url.string().substring(javascriptSchemeLength); - ScriptValue result; - if (m_frame->script()->xssAuditor()->canEvaluateJavaScriptURL(script)) - result = executeScript(decodeURLEscapeSequences(script), userGesture); - - String scriptResult; - if (!result.getString(scriptResult)) - return true; - - SecurityOrigin* currentSecurityOrigin = m_frame->document()->securityOrigin(); - - // FIXME: We should always replace the document, but doing so - // synchronously can cause crashes: - // http://bugs.webkit.org/show_bug.cgi?id=16782 - if (replaceDocument) { - stopAllLoaders(); - begin(m_URL, true, currentSecurityOrigin); - write(scriptResult); - end(); - } - - return true; -} - -ScriptValue FrameLoader::executeScript(const String& script, bool forceUserGesture) -{ - return executeScript(ScriptSourceCode(script, forceUserGesture ? KURL() : m_URL)); -} - -ScriptValue FrameLoader::executeScript(const ScriptSourceCode& sourceCode) -{ - if (!m_frame->script()->isEnabled() || m_frame->script()->isPaused()) - return ScriptValue(); - - bool wasRunningScript = m_isRunningScript; - m_isRunningScript = true; - - ScriptValue result = m_frame->script()->evaluate(sourceCode); - - if (!wasRunningScript) { - m_isRunningScript = false; - Document::updateStyleForAllDocuments(); - } - - return result; -} void FrameLoader::cancelAndClear() { - cancelRedirection(); + m_frame->redirectScheduler()->cancel(); if (!m_isComplete) closeURL(); @@ -811,6 +674,14 @@ void FrameLoader::cancelAndClear() m_frame->script()->updatePlatformScriptObjects(); } +void FrameLoader::replaceDocument(const String& html) +{ + stopAllLoaders(); + begin(m_URL, true, m_frame->document()->securityOrigin()); + write(html); + end(); +} + void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, bool clearFrameView) { m_frame->editor()->clear(); @@ -853,8 +724,7 @@ void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, boo if (clearScriptObjects) m_frame->script()->clearScriptObjects(); - m_redirectionTimer.stop(); - m_scheduledRedirection.clear(); + m_frame->redirectScheduler()->clear(); m_checkTimer.stop(); m_shouldCallCheckCompleted = false; @@ -895,7 +765,7 @@ void FrameLoader::receivedFirstData() else url = m_frame->document()->completeURL(url).string(); - scheduleHTTPRedirection(delay, url); + m_frame->redirectScheduler()->scheduleRedirect(delay, url); } const String& FrameLoader::responseMIMEType() const @@ -972,7 +842,7 @@ void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin) document->parseDNSPrefetchControlHeader(dnsPrefetchControl); } - restoreDocumentState(); + history()->restoreDocumentState(); document->implicitOpen(); @@ -1151,21 +1021,6 @@ void FrameLoader::startIconLoader() m_iconLoader->startLoading(); } -void FrameLoader::setLocalLoadPolicy(LocalLoadPolicy policy) -{ - localLoadPolicy = policy; -} - -bool FrameLoader::restrictAccessToLocal() -{ - return localLoadPolicy != FrameLoader::AllowLocalLoadsForAll; -} - -bool FrameLoader::allowSubstituteDataAccessToLocal() -{ - return localLoadPolicy != FrameLoader::AllowLocalLoadsForLocalOnly; -} - void FrameLoader::commitIconURLToIconDatabase(const KURL& icon) { ASSERT(iconDatabase()); @@ -1174,52 +1029,6 @@ void FrameLoader::commitIconURLToIconDatabase(const KURL& icon) iconDatabase()->setIconURLForPageURL(icon.string(), originalRequestURL().string()); } -void FrameLoader::restoreDocumentState() -{ - Document* doc = m_frame->document(); - - HistoryItem* itemToRestore = 0; - - switch (loadType()) { - case FrameLoadTypeReload: - case FrameLoadTypeReloadFromOrigin: - case FrameLoadTypeSame: - case FrameLoadTypeReplace: - break; - case FrameLoadTypeBack: - case FrameLoadTypeBackWMLDeckNotAccessible: - case FrameLoadTypeForward: - case FrameLoadTypeIndexedBackForward: - case FrameLoadTypeRedirectWithLockedBackForwardList: - case FrameLoadTypeStandard: - itemToRestore = m_currentHistoryItem.get(); - } - - if (!itemToRestore) - return; - - LOG(Loading, "WebCoreLoading %s: restoring form state from %p", m_frame->tree()->name().string().utf8().data(), itemToRestore); - doc->setStateForNewFormElements(itemToRestore->documentState()); -} - -void FrameLoader::gotoAnchor() -{ - // If our URL has no ref, then we have no place we need to jump to. - // OTOH If CSS target was set previously, we want to set it to 0, recalc - // and possibly repaint because :target pseudo class may have been - // set (see bug 11321). - if (!m_URL.hasFragmentIdentifier() && !m_frame->document()->cssTarget()) - return; - - String fragmentIdentifier = m_URL.fragmentIdentifier(); - if (gotoAnchor(fragmentIdentifier)) - return; - - // Try again after decoding the ref, based on the document's encoding. - if (m_decoder) - gotoAnchor(decodeURLEscapeSequences(fragmentIdentifier, m_decoder->encoding())); -} - void FrameLoader::finishedParsing() { if (m_creatingInitialEmptyDocument) @@ -1242,8 +1051,7 @@ void FrameLoader::finishedParsing() // Check if the scrollbars are really needed for the content. // If not, remove them, relayout, and repaint. m_frame->view()->restoreScrollbar(); - - gotoAnchor(); + m_frame->view()->scrollToFragment(m_URL); } void FrameLoader::loadDone() @@ -1298,7 +1106,7 @@ void FrameLoader::checkCompleted() RefPtr<Frame> protect(m_frame); checkCallImplicitClose(); // if we didn't do it before - startRedirectionTimer(); + m_frame->redirectScheduler()->startTimer(); completed(); if (m_frame->page()) @@ -1363,186 +1171,11 @@ KURL FrameLoader::completeURL(const String& url) return m_frame->document()->completeURL(url); } -void FrameLoader::scheduleHTTPRedirection(double delay, const String& url) -{ - if (delay < 0 || delay > INT_MAX / 1000) - return; - - if (!m_frame->page()) - return; - - if (url.isEmpty()) - return; - - // We want a new history item if the refresh timeout is > 1 second. - if (!m_scheduledRedirection || delay <= m_scheduledRedirection->delay) - scheduleRedirection(new ScheduledRedirection(delay, url, true, delay <= 1, false, false)); -} - -static bool mustLockBackForwardList(Frame* targetFrame) -{ - // 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. - // See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation for this. - - 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 false; -} - -void FrameLoader::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); - - // 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(m_URL, parsedURL)) { - changeLocation(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 = !m_committedFirstRealDocumentLoad; - - scheduleRedirection(new ScheduledRedirection(url, referrer, lockHistory, lockBackForwardList, wasUserGesture, false, duringLoad)); -} - -void FrameLoader::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_committedFirstRealDocumentLoad; - - scheduleRedirection(new ScheduledRedirection(frameRequest, lockHistory, mustLockBackForwardList(m_frame), event, formState, duringLoad)); -} - -void FrameLoader::scheduleRefresh(bool wasUserGesture) -{ - if (!m_frame->page()) - return; - - if (m_URL.isEmpty()) - return; - - scheduleRedirection(new ScheduledRedirection(m_URL.string(), m_outgoingReferrer, true, true, wasUserGesture, true, false)); -} - -bool FrameLoader::isLocationChange(const ScheduledRedirection& redirection) -{ - switch (redirection.type) { - case ScheduledRedirection::redirection: - return false; - case ScheduledRedirection::historyNavigation: - case ScheduledRedirection::locationChange: - case ScheduledRedirection::formSubmission: - return true; - } - ASSERT_NOT_REACHED(); - return false; -} - -void FrameLoader::scheduleHistoryNavigation(int steps) -{ - if (!m_frame->page()) - return; - - scheduleRedirection(new ScheduledRedirection(steps)); -} - -void FrameLoader::goBackOrForward(int distance) -{ - if (distance == 0) - return; - - Page* page = m_frame->page(); - if (!page) - return; - BackForwardList* list = page->backForwardList(); - if (!list) - return; - - HistoryItem* item = list->itemAtIndex(distance); - if (!item) { - if (distance > 0) { - int forwardListCount = list->forwardListCount(); - if (forwardListCount > 0) - item = list->itemAtIndex(forwardListCount); - } else { - int backListCount = list->backListCount(); - if (backListCount > 0) - item = list->itemAtIndex(-backListCount); - } - } - - ASSERT(item); // we should not reach this line with an empty back/forward list - if (item) - page->goToItem(item, FrameLoadTypeIndexedBackForward); -} - -void FrameLoader::redirectionTimerFired(Timer<FrameLoader>*) -{ - ASSERT(m_frame->page()); - - if (m_frame->page()->defersLoading()) - return; - - OwnPtr<ScheduledRedirection> redirection(m_scheduledRedirection.release()); - - switch (redirection->type) { - case ScheduledRedirection::redirection: - case ScheduledRedirection::locationChange: - 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 - urlSelected(m_URL, "", 0, redirection->lockHistory, redirection->lockBackForwardList, redirection->wasUserGesture); - 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. - if (canGoBackOrForward(redirection->historySteps)) - 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; - loadFrameRequest(redirection->frameRequest, redirection->lockHistory, redirection->lockBackForwardList, - redirection->event, redirection->formState); - return; - } - - ASSERT_NOT_REACHED(); -} - void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, Frame* childFrame) { ASSERT(childFrame); - HistoryItem* parentItem = currentHistoryItem(); + HistoryItem* parentItem = history()->currentItem(); FrameLoadType loadType = this->loadType(); FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedBackForwardList; @@ -1558,7 +1191,7 @@ void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, // this is needed is Radar 3213556. workingURL = KURL(ParsedURLString, childItem->originalURLString()); childLoadType = loadType; - childFrame->loader()->m_provisionalHistoryItem = childItem; + childFrame->loader()->history()->setProvisionalItem(childItem); } } @@ -1601,54 +1234,6 @@ String FrameLoader::encoding() const return settings ? settings->defaultTextEncodingName() : String(); } -bool FrameLoader::gotoAnchor(const String& name) -{ - ASSERT(m_frame->document()); - - if (!m_frame->document()->haveStylesheetsLoaded()) { - m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true); - return false; - } - - m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false); - - Element* anchorNode = m_frame->document()->findAnchor(name); - -#if ENABLE(SVG) - if (m_frame->document()->isSVGDocument()) { - if (name.startsWith("xpointer(")) { - // We need to parse the xpointer reference here - } else if (name.startsWith("svgView(")) { - RefPtr<SVGSVGElement> svg = static_cast<SVGDocument*>(m_frame->document())->rootElement(); - if (!svg->currentView()->parseViewSpec(name)) - return false; - svg->setUseCurrentView(true); - } else { - if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) { - RefPtr<SVGViewElement> viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0; - if (viewElement.get()) { - RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(SVGLocatable::nearestViewportElement(viewElement.get())); - svg->inheritViewAttributes(viewElement.get()); - } - } - } - // FIXME: need to decide which <svg> to focus on, and zoom to that one - // FIXME: need to actually "highlight" the viewTarget(s) - } -#endif - - m_frame->document()->setCSSTarget(anchorNode); // Setting to null will clear the current target. - - // Implement the rule that "" and "top" both mean top of page as in other browsers. - if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top"))) - return false; - - if (FrameView* view = m_frame->view()) - view->maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document()); - - return true; -} - bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const AtomicString& frameName, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues) { @@ -1728,11 +1313,13 @@ bool FrameLoader::loadPlugin(RenderPart* renderer, const KURL& url, const String if (renderer && !useFallback) { HTMLPlugInElement* element = toPlugInElement(renderer->node()); - if (!canLoad(url, String(), frame()->document())) { + if (!SecurityOrigin::canLoad(url, String(), frame()->document())) { FrameLoader::reportLocalLoadFailed(m_frame, url.string()); return false; } + checkIfRunInsecureContent(m_frame->document()->securityOrigin(), url); + widget = m_client->createPlugin(IntSize(renderer->contentWidth(), renderer->contentHeight()), element, url, paramNames, paramValues, mimeType, m_frame->document()->isPluginDocument() && !m_containsPlugIns); @@ -1771,6 +1358,10 @@ void FrameLoader::checkIfDisplayInsecureContent(SecurityOrigin* context, const K if (!isMixedContent(context, url)) return; + String message = String::format("The page at %s displayed insecure content from %s.\n", + m_URL.string().utf8().data(), url.string().utf8().data()); + m_frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, message, 1, String()); + m_client->didDisplayInsecureContent(); } @@ -1779,6 +1370,10 @@ void FrameLoader::checkIfRunInsecureContent(SecurityOrigin* context, const KURL& if (!isMixedContent(context, url)) return; + String message = String::format("The page at %s ran insecure content from %s.\n", + m_URL.string().utf8().data(), url.string().utf8().data()); + m_frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, message, 1, String()); + m_client->didRunInsecureContent(context); } @@ -1801,16 +1396,6 @@ void FrameLoader::setOpener(Frame* opener) } } -bool FrameLoader::openedByDOM() const -{ - return m_openedByDOM; -} - -void FrameLoader::setOpenedByDOM() -{ - m_openedByDOM = true; -} - void FrameLoader::handleFallbackContent() { HTMLFrameOwnerElement* owner = m_frame->ownerElement(); @@ -1822,7 +1407,7 @@ void FrameLoader::handleFallbackContent() void FrameLoader::provisionalLoadStarted() { m_firstLayoutDone = false; - cancelRedirection(true); + m_frame->redirectScheduler()->cancel(true); m_client->provisionalLoadStarted(); } @@ -1892,7 +1477,7 @@ bool FrameLoader::canCachePageContainingThisFrame() && !SharedWorkerRepository::hasSharedWorkers(m_frame->document()) #endif && !m_frame->document()->usingGeolocation() - && m_currentHistoryItem + && history()->currentItem() && !m_quickRedirectComing && !m_documentLoader->isLoadingInAPISense() && !m_documentLoader->isStopping() @@ -2043,7 +1628,7 @@ bool FrameLoader::logCanCacheFrameDecision(int indentLevel) #endif if (m_frame->document()->usingGeolocation()) { PCLOG(" -Frame uses Geolocation"); cannotCache = true; } - if (!m_currentHistoryItem) + if (!history()->currentItem()) { PCLOG(" -No current history item"); cannotCache = true; } if (m_quickRedirectComing) { PCLOG(" -Quick redirect is coming"); cannotCache = true; } @@ -2109,7 +1694,7 @@ private: RefPtr<Document> m_document; }; - + // This does the same kind of work that didOpenURL does, except it relies on the fact // that a higher level already checked that the URLs match and the scrolling is the right thing to do. void FrameLoader::scrollToAnchor(const KURL& url) @@ -2121,12 +1706,13 @@ void FrameLoader::scrollToAnchor(const KURL& url) } m_URL = url; - updateHistoryForAnchorScroll(); + history()->updateForAnchorScroll(); // If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor m_frame->eventHandler()->stopAutoscrollTimer(); started(); - gotoAnchor(); + if (FrameView* view = m_frame->view()) + view->scrollToFragment(m_URL); // It's important to model this as a load that starts and immediately finishes. // Otherwise, the parent frame may think we never finished loading. @@ -2139,78 +1725,11 @@ bool FrameLoader::isComplete() const return m_isComplete; } -void FrameLoader::scheduleRedirection(PassOwnPtr<ScheduledRedirection> redirection) -{ - ASSERT(m_frame->page()); - - // If a redirect was scheduled during a load, then stop the current load. - // Otherwise when the current load transitions from a provisional to a - // committed state, pending redirects may be cancelled. - if (redirection->wasDuringLoad) { - if (m_provisionalDocumentLoader) - m_provisionalDocumentLoader->stopLoading(); - stopLoading(UnloadEventPolicyUnloadAndPageHide); - } - - stopRedirectionTimer(); - m_scheduledRedirection = redirection; - if (!m_isComplete && m_scheduledRedirection->type != ScheduledRedirection::redirection) - completed(); - startRedirectionTimer(); -} - -void FrameLoader::startRedirectionTimer() -{ - if (!m_scheduledRedirection) - return; - - ASSERT(m_frame->page()); - - if (m_redirectionTimer.isActive()) - return; - - if (m_scheduledRedirection->type == ScheduledRedirection::redirection && !allAncestorsAreComplete()) - return; - - m_redirectionTimer.startOneShot(m_scheduledRedirection->delay); - - switch (m_scheduledRedirection->type) { - case ScheduledRedirection::locationChange: - case ScheduledRedirection::redirection: - if (m_scheduledRedirection->toldClient) - return; - m_scheduledRedirection->toldClient = true; - clientRedirected(KURL(ParsedURLString, m_scheduledRedirection->url), - m_scheduledRedirection->delay, - currentTime() + m_redirectionTimer.nextFireInterval(), - m_scheduledRedirection->lockBackForwardList); - return; - case ScheduledRedirection::formSubmission: - // FIXME: It would make sense to report form submissions as client redirects too. - // But we didn't do that in the past when form submission used a separate delay - // mechanism, so doing it will be a behavior change. - return; - case ScheduledRedirection::historyNavigation: - // Don't report history navigations. - return; - } - ASSERT_NOT_REACHED(); -} - -void FrameLoader::stopRedirectionTimer() -{ - m_redirectionTimer.stop(); - - OwnPtr<ScheduledRedirection> redirection(m_scheduledRedirection.release()); - if (redirection && redirection->toldClient) - clientRedirectCancelledOrFinished(m_cancellingWithLoadInProgress); -} - void FrameLoader::completed() { RefPtr<Frame> protect(m_frame); for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - child->loader()->startRedirectionTimer(); + child->redirectScheduler()->startTimer(); if (Frame* parent = m_frame->tree()->parent()) parent->loader()->checkCompleted(); if (m_frame->view()) @@ -2264,7 +1783,7 @@ static bool isFeedWithNestedProtocolInHTTPFamily(const KURL& url) } void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHistory, bool lockBackForwardList, - PassRefPtr<Event> event, PassRefPtr<FormState> formState) + PassRefPtr<Event> event, PassRefPtr<FormState> formState, ReferrerPolicy referrerPolicy) { KURL url = request.resourceRequest().url(); @@ -2277,13 +1796,13 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHis ASSERT(frame()->document()); if (SecurityOrigin::shouldTreatURLAsLocal(url.string()) && !isFeedWithNestedProtocolInHTTPFamily(url)) { - if (!canLoad(url, String(), frame()->document()) && !canLoad(url, referrer)) { + if (!SecurityOrigin::canLoad(url, String(), frame()->document()) && !SecurityOrigin::canLoad(url, referrer, 0)) { FrameLoader::reportLocalLoadFailed(m_frame, url.string()); return; } } - if (shouldHideReferrer(url, referrer)) + if (SecurityOrigin::shouldHideReferrer(url, referrer) || referrerPolicy == NoReferrer) referrer = String(); FrameLoadType loadType; @@ -2340,7 +1859,8 @@ void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const Stri NavigationAction action(newURL, newLoadType, isFormSubmission, event); if (!targetFrame && !frameName.isEmpty()) { - checkNewWindowPolicy(action, request, formState.release(), frameName); + policyChecker()->checkNewWindowPolicy(action, FrameLoader::callContinueLoadAfterNewWindowPolicy, + request, formState.release(), frameName, this); return; } @@ -2353,9 +1873,9 @@ void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const Stri // work properly. if (shouldScrollToAnchor(isFormSubmission, newLoadType, newURL)) { oldDocumentLoader->setTriggeringAction(action); - stopPolicyCheck(); - m_policyLoadType = newLoadType; - checkNavigationPolicy(request, oldDocumentLoader.get(), formState.release(), + policyChecker()->stopCheck(); + policyChecker()->setLoadType(newLoadType); + policyChecker()->checkNavigationPolicy(request, oldDocumentLoader.get(), formState.release(), callContinueFragmentScrollAfterNavigationPolicy, this); } else { // must grab this now, since this load may stop the previous load and clear this flag @@ -2404,7 +1924,7 @@ void FrameLoader::load(const ResourceRequest& request, const String& frameName, return; } - checkNewWindowPolicy(NavigationAction(request.url(), NavigationTypeOther), request, 0, frameName); + policyChecker()->checkNewWindowPolicy(NavigationAction(request.url(), NavigationTypeOther), FrameLoader::callContinueLoadAfterNewWindowPolicy, request, 0, frameName, this); } void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, bool lockHistory, FrameLoadType type, PassRefPtr<FormState> formState) @@ -2462,54 +1982,41 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t if (m_unloadEventBeingDispatched) return; - m_policyLoadType = type; + policyChecker()->setLoadType(type); RefPtr<FormState> formState = prpFormState; bool isFormSubmission = formState; const KURL& newURL = loader->request().url(); - if (shouldScrollToAnchor(isFormSubmission, m_policyLoadType, newURL)) { + if (shouldScrollToAnchor(isFormSubmission, policyChecker()->loadType(), newURL)) { RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader; - NavigationAction action(newURL, m_policyLoadType, isFormSubmission); + NavigationAction action(newURL, policyChecker()->loadType(), isFormSubmission); oldDocumentLoader->setTriggeringAction(action); - stopPolicyCheck(); - checkNavigationPolicy(loader->request(), oldDocumentLoader.get(), formState, + policyChecker()->stopCheck(); + policyChecker()->checkNavigationPolicy(loader->request(), oldDocumentLoader.get(), formState, callContinueFragmentScrollAfterNavigationPolicy, this); } else { if (Frame* parent = m_frame->tree()->parent()) loader->setOverrideEncoding(parent->loader()->documentLoader()->overrideEncoding()); - stopPolicyCheck(); + policyChecker()->stopCheck(); setPolicyDocumentLoader(loader); if (loader->triggeringAction().isEmpty()) - loader->setTriggeringAction(NavigationAction(newURL, m_policyLoadType, isFormSubmission)); + loader->setTriggeringAction(NavigationAction(newURL, policyChecker()->loadType(), isFormSubmission)); + + if (Element* ownerElement = m_frame->document()->ownerElement()) { + if (!ownerElement->dispatchBeforeLoadEvent(loader->request().url().string())) { + continueLoadAfterNavigationPolicy(loader->request(), formState, false); + return; + } + } - checkNavigationPolicy(loader->request(), loader, formState, + policyChecker()->checkNavigationPolicy(loader->request(), loader, formState, callContinueLoadAfterNavigationPolicy, this); } } -bool FrameLoader::canLoad(const KURL& url, const String& referrer, const Document* doc) -{ - return canLoad(url, referrer, doc ? doc->securityOrigin() : 0); -} - -bool FrameLoader::canLoad(const KURL& url, const String& referrer, const SecurityOrigin* securityOrigin) -{ - // We can always load any URL that isn't considered local (e.g. http URLs). - if (!SecurityOrigin::shouldTreatURLAsLocal(url.string())) - return true; - - // If we were provided a document, we let its local file policy dictate the result, - // otherwise we allow local loads only if the supplied referrer is also local. - if (securityOrigin) - return securityOrigin->canLoadLocalResources(); - if (!referrer.isEmpty()) - return SecurityOrigin::shouldTreatURLAsLocal(referrer); - return false; -} - void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url) { ASSERT(!url.isEmpty()); @@ -2519,22 +2026,6 @@ void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url) frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Not allowed to load local resource: " + url, 0, String()); } -bool FrameLoader::shouldHideReferrer(const KURL& url, const String& referrer) -{ - bool referrerIsSecureURL = protocolIs(referrer, "https"); - bool referrerIsWebURL = referrerIsSecureURL || protocolIs(referrer, "http"); - - if (!referrerIsWebURL) - return true; - - if (!referrerIsSecureURL) - return false; - - bool URLIsSecureURL = url.protocolIs("https"); - - return !URLIsSecureURL; -} - const ResourceRequest& FrameLoader::initialRequest() const { return activeDocumentLoader()->originalRequest(); @@ -2545,50 +2036,23 @@ void FrameLoader::receivedData(const char* data, int length) activeDocumentLoader()->receivedData(data, length); } -void FrameLoader::handleUnimplementablePolicy(const ResourceError& error) +bool FrameLoader::willLoadMediaElementURL(KURL& url) { - m_delegateIsHandlingUnimplementablePolicy = true; - m_client->dispatchUnableToImplementPolicy(error); - m_delegateIsHandlingUnimplementablePolicy = false; -} + ResourceRequest request(url); -void FrameLoader::cannotShowMIMEType(const ResourceResponse& response) -{ - handleUnimplementablePolicy(m_client->cannotShowMIMETypeError(response)); -} + unsigned long identifier; + ResourceError error; + requestFromDelegate(request, identifier, error); + notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, ResourceResponse(url, String(), -1, String(), String()), -1, error); -ResourceError FrameLoader::interruptionForPolicyChangeError(const ResourceRequest& request) -{ - return m_client->interruptForPolicyChangeError(request); -} + url = request.url(); -void FrameLoader::checkNavigationPolicy(const ResourceRequest& newRequest, NavigationPolicyDecisionFunction function, void* argument) -{ - checkNavigationPolicy(newRequest, activeDocumentLoader(), 0, function, argument); + return error.isNull(); } -void FrameLoader::checkContentPolicy(const String& MIMEType, ContentPolicyDecisionFunction function, void* argument) +ResourceError FrameLoader::interruptionForPolicyChangeError(const ResourceRequest& request) { - ASSERT(activeDocumentLoader()); - - // Always show content with valid substitute data. - if (activeDocumentLoader()->substituteData().isValid()) { - function(argument, PolicyUse); - return; - } - -#if ENABLE(FTPDIR) - // Respect the hidden FTP Directory Listing pref so it can be tested even if the policy delegate might otherwise disallow it - Settings* settings = m_frame->settings(); - if (settings && settings->forceFTPDirectoryListings() && MIMEType == "application/x-ftp-directory") { - function(argument, PolicyUse); - return; - } -#endif - - m_policyCheck.set(function, argument); - m_client->dispatchDecidePolicyForMIMEType(&FrameLoader::continueAfterContentPolicy, - MIMEType, activeDocumentLoader()->request()); + return m_client->interruptForPolicyChangeError(request); } bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader* docLoader) @@ -2598,7 +2062,7 @@ bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader* docLoader) if (unreachableURL.isEmpty()) return false; - if (!isBackForwardLoadType(m_policyLoadType)) + if (!isBackForwardLoadType(policyChecker()->loadType())) return false; // We only treat unreachableURLs specially during the delegate callbacks @@ -2607,7 +2071,7 @@ bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader* docLoader) // case handles malformed URLs and unknown schemes. Loading alternate content // at other times behaves like a standard load. DocumentLoader* compareDocumentLoader = 0; - if (m_delegateIsDecidingNavigationPolicy || m_delegateIsHandlingUnimplementablePolicy) + if (policyChecker()->delegateIsDecidingNavigationPolicy() || policyChecker()->delegateIsHandlingUnimplementablePolicy()) compareDocumentLoader = m_policyDocumentLoader.get(); else if (m_delegateIsHandlingProvisionalLoadError) compareDocumentLoader = m_provisionalDocumentLoader.get(); @@ -2762,7 +2226,7 @@ void FrameLoader::stopAllLoaders(DatabasePolicy databasePolicy) m_inStopAllLoaders = true; - stopPolicyCheck(); + policyChecker()->stopCheck(); stopLoadingSubframes(); if (m_provisionalDocumentLoader) @@ -2893,7 +2357,7 @@ void FrameLoader::commitProvisionalLoad(PassRefPtr<CachedPage> prpCachedPage) // Check to see if we need to cache the page we are navigating away from into the back/forward cache. // We are doing this here because we know for sure that a new page is about to be loaded. - cachePageForHistoryItem(m_currentHistoryItem.get()); + cachePageForHistoryItem(history()->currentItem()); if (m_loadType != FrameLoadTypeReplace) closeOldDataSources(); @@ -2927,7 +2391,7 @@ void FrameLoader::commitProvisionalLoad(PassRefPtr<CachedPage> prpCachedPage) LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame->tree()->name().string().utf8().data(), m_URL.string().utf8().data()); if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isClientRedirect()) - updateHistoryForClientRedirect(); + history()->updateForClientRedirect(); if (m_loadingFromCachedPage) { m_frame->document()->documentDidBecomeActive(); @@ -2947,10 +2411,10 @@ void FrameLoader::commitProvisionalLoad(PassRefPtr<CachedPage> prpCachedPage) // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing. // However, with today's computers and networking speeds, this won't happen in practice. // Could be an issue with a giant local file. - sendRemainingDelegateMessages(identifier, response, static_cast<int>(response.expectedContentLength()), error); + notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, response, static_cast<int>(response.expectedContentLength()), error); } - pageCache()->remove(m_currentHistoryItem.get()); + pageCache()->remove(history()->currentItem()); m_documentLoader->setPrimaryLoadComplete(true); @@ -2968,7 +2432,7 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage) return; m_client->setCopiesOnScroll(); - updateHistoryForCommit(); + history()->updateForCommit(); // The call to closeURL() invokes the unload event handler, which can execute arbitrary // JavaScript. If the script initiates a new load, we need to abandon the current load, @@ -3000,7 +2464,7 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage) case FrameLoadTypeIndexedBackForward: if (Page* page = m_frame->page()) if (page->backForwardList()) { - updateHistoryForBackForwardNavigation(); + history()->updateForBackForwardNavigation(); // Create a document view for this document, or used the cached view. if (cachedPage) { @@ -3018,12 +2482,12 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage) case FrameLoadTypeReloadFromOrigin: case FrameLoadTypeSame: case FrameLoadTypeReplace: - updateHistoryForReload(); + history()->updateForReload(); m_client->transitionToCommittedForNewPage(); break; case FrameLoadTypeStandard: - updateHistoryForStandardLoad(); + history()->updateForStandardLoad(); #ifndef BUILDING_ON_TIGER // This code was originally added for a Leopard performance imporvement. We decided to // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>. @@ -3034,7 +2498,7 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage) break; case FrameLoadTypeRedirectWithLockedBackForwardList: - updateHistoryForRedirectWithLockedBackForwardList(); + history()->updateForRedirectWithLockedBackForwardList(); m_client->transitionToCommittedForNewPage(); break; @@ -3130,7 +2594,7 @@ void FrameLoader::open(CachedPage& cachedPage) ASSERT(m_frame->page()); ASSERT(m_frame->page()->mainFrame() == m_frame); - cancelRedirection(); + m_frame->redirectScheduler()->cancel(); // We still have to close the previous part page. closeURL(); @@ -3242,12 +2706,6 @@ String FrameLoader::generatedMIMETypeForURLScheme(const String& URLScheme) return m_client->generatedMIMETypeForURLScheme(URLScheme); } -void FrameLoader::cancelContentPolicyCheck() -{ - m_client->cancelPolicyCheck(); - m_policyCheck.clear(); -} - void FrameLoader::didReceiveServerRedirectForProvisionalLoadForFrame() { m_client->dispatchDidReceiveServerRedirectForProvisionalLoad(); @@ -3288,6 +2746,8 @@ void FrameLoader::finishedLoadingDocument(DocumentLoader* loader) loader->setParsedArchiveData(mainResource->data()); m_responseMIMEType = mainResource->mimeType(); + + closeURL(); didOpenURL(mainResource->url()); String userChosenEncoding = documentLoader()->overrideEncoding(); @@ -3367,14 +2827,6 @@ CachePolicy FrameLoader::subresourceCachePolicy() const return CachePolicyVerify; } -void FrameLoader::stopPolicyCheck() -{ - m_client->cancelPolicyCheck(); - PolicyCheck check = m_policyCheck; - m_policyCheck.clear(); - check.cancel(); -} - void FrameLoader::checkLoadCompleteForThisFrame() { ASSERT(m_client->hasWebView()); @@ -3397,7 +2849,7 @@ void FrameLoader::checkLoadCompleteForThisFrame() RefPtr<HistoryItem> item; if (Page* page = m_frame->page()) if (isBackForwardLoadType(loadType()) && m_frame == page->mainFrame()) - item = m_currentHistoryItem; + item = history()->currentItem(); bool shouldReset = true; if (!(pdl->isLoadingInAPISense() && !pdl->isStopping())) { @@ -3446,7 +2898,7 @@ void FrameLoader::checkLoadCompleteForThisFrame() // If the user had a scroll point, scroll to it, overriding the anchor point if any. if (Page* page = m_frame->page()) if ((isBackForwardLoadType(m_loadType) || m_loadType == FrameLoadTypeReload || m_loadType == FrameLoadTypeReloadFromOrigin) && page->backForwardList()) - restoreScrollPositionAndViewState(); + history()->restoreScrollPositionAndViewState(); if (m_creatingInitialEmptyDocument || !m_committedFirstRealDocumentLoad) return; @@ -3473,14 +2925,7 @@ void FrameLoader::checkLoadCompleteForThisFrame() ASSERT_NOT_REACHED(); } -void FrameLoader::continueAfterContentPolicy(PolicyAction policy) -{ - PolicyCheck check = m_policyCheck; - m_policyCheck.clear(); - check.call(policy); -} - -void FrameLoader::continueLoadAfterWillSubmitForm(PolicyAction) +void FrameLoader::continueLoadAfterWillSubmitForm() { if (!m_provisionalDocumentLoader) return; @@ -3503,7 +2948,7 @@ void FrameLoader::continueLoadAfterWillSubmitForm(PolicyAction) if (Page* page = m_frame->page()) { identifier = page->progress()->createUniqueIdentifier(); - dispatchAssignIdentifierToInitialRequest(identifier, m_provisionalDocumentLoader.get(), m_provisionalDocumentLoader->originalRequest()); + notifier()->assignIdentifierToInitialRequest(identifier, m_provisionalDocumentLoader.get(), m_provisionalDocumentLoader->originalRequest()); } if (!m_provisionalDocumentLoader->startLoadingMainResource(identifier)) @@ -3514,7 +2959,7 @@ void FrameLoader::didFirstLayout() { if (Page* page = m_frame->page()) if (isBackForwardLoadType(m_loadType) && page->backForwardList()) - restoreScrollPositionAndViewState(); + history()->restoreScrollPositionAndViewState(); m_firstLayoutDone = true; m_client->dispatchDidFirstLayout(); @@ -3531,9 +2976,7 @@ void FrameLoader::frameLoadCompleted() m_client->frameLoadCompleted(); - // Even if already complete, we might have set a previous item on a frame that - // didn't do any data loading on the past transaction. Make sure to clear these out. - m_previousHistoryItem = 0; + history()->updateForFrameLoadCompleted(); // After a canceled provisional load, firstLayoutDone is false. // Reset it to true if we're displaying a page. @@ -3634,7 +3077,7 @@ void FrameLoader::detachFromParent() closeURL(); stopAllLoaders(); - saveScrollPositionAndViewStateToItem(currentHistoryItem()); + history()->saveScrollPositionAndViewStateToItem(history()->currentItem()); detachChildren(); #if ENABLE(INSPECTOR) @@ -3777,7 +3220,7 @@ void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String if (Frame* targetFrame = formState ? 0 : findFrameForNavigation(frameName)) targetFrame->loader()->loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release()); else - checkNewWindowPolicy(action, workingResourceRequest, formState.release(), frameName); + policyChecker()->checkNewWindowPolicy(action, FrameLoader::callContinueLoadAfterNewWindowPolicy, workingResourceRequest, formState.release(), frameName, this); } else loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release()); } @@ -3785,7 +3228,7 @@ void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data) { String referrer = m_outgoingReferrer; - if (shouldHideReferrer(request.url(), referrer)) + if (SecurityOrigin::shouldHideReferrer(request.url(), referrer)) referrer = String(); ResourceRequest initialRequest = request; @@ -3820,49 +3263,9 @@ unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& requ } #endif } - - sendRemainingDelegateMessages(identifier, response, data.size(), error); - return identifier; -} - -void FrameLoader::assignIdentifierToInitialRequest(unsigned long identifier, const ResourceRequest& clientRequest) -{ - return dispatchAssignIdentifierToInitialRequest(identifier, activeDocumentLoader(), clientRequest); -} - -void FrameLoader::willSendRequest(ResourceLoader* loader, ResourceRequest& clientRequest, const ResourceResponse& redirectResponse) -{ - applyUserAgent(clientRequest); - dispatchWillSendRequest(loader->documentLoader(), loader->identifier(), clientRequest, redirectResponse); -} - -void FrameLoader::didReceiveResponse(ResourceLoader* loader, const ResourceResponse& r) -{ - activeDocumentLoader()->addResponse(r); - - if (Page* page = m_frame->page()) - page->progress()->incrementProgress(loader->identifier(), r); - dispatchDidReceiveResponse(loader->documentLoader(), loader->identifier(), r); -} -void FrameLoader::didReceiveData(ResourceLoader* loader, const char* data, int length, int lengthReceived) -{ - if (Page* page = m_frame->page()) - page->progress()->incrementProgress(loader->identifier(), data, length); - dispatchDidReceiveContentLength(loader->documentLoader(), loader->identifier(), lengthReceived); -} - -void FrameLoader::didFailToLoad(ResourceLoader* loader, const ResourceError& error) -{ - if (Page* page = m_frame->page()) - page->progress()->completeProgress(loader->identifier()); - if (!error.isNull()) - m_client->dispatchDidFailLoading(loader->documentLoader(), loader->identifier(), error); -} - -void FrameLoader::didLoadResourceByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString) -{ - m_client->dispatchDidLoadResourceByXMLHttpRequest(identifier, sourceString); + notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, response, data.size(), error); + return identifier; } const ResourceRequest& FrameLoader::originalRequest() const @@ -3876,7 +3279,7 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error, bool isC RefPtr<Frame> protect(m_frame); RefPtr<DocumentLoader> loader = activeDocumentLoader(); - + if (isComplete) { // FIXME: Don't want to do this if an entirely new load is going, so should check // that both data sources on the frame are either this or nil. @@ -3884,7 +3287,7 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error, bool isC if (m_client->shouldFallBack(error)) handleFallbackContent(); } - + if (m_state == FrameStateProvisional && m_provisionalDocumentLoader) { if (m_submittedFormURL == m_provisionalDocumentLoader->originalRequestCopy().url()) m_submittedFormURL = KURL(); @@ -3892,7 +3295,7 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error, bool isC // We might have made a page cache item, but now we're bailing out due to an error before we ever // transitioned to the new page (before WebFrameState == commit). The goal here is to restore any state // so that the existing view (that wenever got far enough to replace) can continue being used. - invalidateCurrentItemCachedPage(); + history()->invalidateCurrentItemCachedPage(); // Call clientRedirectCancelledOrFinished here so that the frame load delegate is notified that the redirect's // status has changed, if there was a redirect. The frame load delegate may have saved some state about @@ -3902,8 +3305,7 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error, bool isC if (m_sentRedirectNotification) clientRedirectCancelledOrFinished(false); } - - + loader->mainReceivedError(error, isComplete); } @@ -3916,7 +3318,7 @@ void FrameLoader::callContinueFragmentScrollAfterNavigationPolicy(void* argument void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue) { - bool isRedirect = m_quickRedirectComing || m_policyLoadType == FrameLoadTypeRedirectWithLockedBackForwardList; + bool isRedirect = m_quickRedirectComing || policyChecker()->loadType() == FrameLoadTypeRedirectWithLockedBackForwardList; m_quickRedirectComing = false; if (!shouldContinue) @@ -3937,7 +3339,7 @@ void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequ // we have already saved away the scroll and doc state for the long slow load, // but it's not an obvious case. - addHistoryItemForFragmentScroll(); + history()->updateBackForwardListForFragmentScroll(); } scrollToAnchor(url); @@ -3972,101 +3374,6 @@ bool FrameLoader::shouldScrollToAnchor(bool isFormSubmission, FrameLoadType load && !m_frame->document()->isFrameSet(); } -void FrameLoader::checkNewWindowPolicy(const NavigationAction& action, const ResourceRequest& request, - PassRefPtr<FormState> formState, const String& frameName) -{ - m_policyCheck.set(request, formState, frameName, - callContinueLoadAfterNewWindowPolicy, this); - m_client->dispatchDecidePolicyForNewWindowAction(&FrameLoader::continueAfterNewWindowPolicy, - action, request, formState, frameName); -} - -void FrameLoader::continueAfterNewWindowPolicy(PolicyAction policy) -{ - PolicyCheck check = m_policyCheck; - m_policyCheck.clear(); - - switch (policy) { - case PolicyIgnore: - check.clearRequest(); - break; - case PolicyDownload: - m_client->startDownload(check.request()); - check.clearRequest(); - break; - case PolicyUse: - break; - } - - check.call(policy == PolicyUse); -} - -void FrameLoader::checkNavigationPolicy(const ResourceRequest& request, DocumentLoader* loader, - PassRefPtr<FormState> formState, NavigationPolicyDecisionFunction function, void* argument) -{ - NavigationAction action = loader->triggeringAction(); - if (action.isEmpty()) { - action = NavigationAction(request.url(), NavigationTypeOther); - loader->setTriggeringAction(action); - } - - // Don't ask more than once for the same request or if we are loading an empty URL. - // This avoids confusion on the part of the client. - if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) { - function(argument, request, 0, true); - loader->setLastCheckedRequest(request); - return; - } - - // We are always willing to show alternate content for unreachable URLs; - // treat it like a reload so it maintains the right state for b/f list. - if (loader->substituteData().isValid() && !loader->substituteData().failingURL().isEmpty()) { - if (isBackForwardLoadType(m_policyLoadType)) - m_policyLoadType = FrameLoadTypeReload; - function(argument, request, 0, true); - return; - } - - loader->setLastCheckedRequest(request); - - m_policyCheck.set(request, formState.get(), function, argument); - - m_delegateIsDecidingNavigationPolicy = true; - m_client->dispatchDecidePolicyForNavigationAction(&FrameLoader::continueAfterNavigationPolicy, - action, request, formState); - m_delegateIsDecidingNavigationPolicy = false; -} - -void FrameLoader::continueAfterNavigationPolicy(PolicyAction policy) -{ - PolicyCheck check = m_policyCheck; - m_policyCheck.clear(); - - bool shouldContinue = policy == PolicyUse; - - switch (policy) { - case PolicyIgnore: - check.clearRequest(); - break; - case PolicyDownload: - m_client->startDownload(check.request()); - check.clearRequest(); - break; - case PolicyUse: { - ResourceRequest request(check.request()); - - if (!m_client->canHandleRequest(request)) { - handleUnimplementablePolicy(m_client->cannotShowURLError(check.request())); - check.clearRequest(); - shouldContinue = false; - } - break; - } - } - - check.call(shouldContinue); -} - void FrameLoader::callContinueLoadAfterNavigationPolicy(void* argument, const ResourceRequest& request, PassRefPtr<FormState> formState, bool shouldContinue) { @@ -4081,7 +3388,7 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, Pass // through this method already, nested; otherwise, policyDataSource should still be set. ASSERT(m_policyDocumentLoader || !m_provisionalDocumentLoader->unreachableURL().isEmpty()); - bool isTargetItem = m_provisionalHistoryItem ? m_provisionalHistoryItem->isTargetItem() : false; + bool isTargetItem = history()->provisionalItem() ? history()->provisionalItem()->isTargetItem() : false; // Two reasons we can't continue: // 1) Navigation policy delegate said we can't so request is nil. A primary case of this @@ -4101,10 +3408,10 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, Pass // If the navigation request came from the back/forward menu, and we punt on it, we have the // problem that we have optimistically moved the b/f cursor already, so move it back. For sanity, // we only do this when punting a navigation for the target frame or top-level frame. - if ((isTargetItem || isLoadingMainFrame()) && isBackForwardLoadType(m_policyLoadType)) + if ((isTargetItem || isLoadingMainFrame()) && isBackForwardLoadType(policyChecker()->loadType())) if (Page* page = m_frame->page()) { Frame* mainFrame = page->mainFrame(); - if (HistoryItem* resetItem = mainFrame->loader()->m_currentHistoryItem.get()) { + if (HistoryItem* resetItem = mainFrame->loader()->history()->currentItem()) { page->backForwardList()->goToItem(resetItem); Settings* settings = m_frame->settings(); page->setGlobalHistoryItem((!settings || settings->privateBrowsingEnabled()) ? 0 : resetItem); @@ -4113,7 +3420,7 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, Pass return; } - FrameLoadType type = m_policyLoadType; + FrameLoadType type = policyChecker()->loadType(); stopAllLoaders(); // <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders() @@ -4138,12 +3445,11 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, Pass return; if (formState) - m_client->dispatchWillSubmitForm(&FrameLoader::continueLoadAfterWillSubmitForm, formState); + m_client->dispatchWillSubmitForm(&PolicyChecker::continueLoadAfterWillSubmitForm, formState); else continueLoadAfterWillSubmitForm(); } - void FrameLoader::callContinueLoadAfterNewWindowPolicy(void* argument, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, bool shouldContinue) { @@ -4165,26 +3471,13 @@ void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& reques if (frameName != "_blank") mainFrame->tree()->setName(frameName); - mainFrame->loader()->setOpenedByDOM(); + mainFrame->page()->setOpenedByDOM(); mainFrame->loader()->m_client->dispatchShow(); - mainFrame->loader()->setOpener(frame.get()); + if (!m_suppressOpenerInNewFrame) + mainFrame->loader()->setOpener(frame.get()); mainFrame->loader()->loadWithNavigationAction(request, NavigationAction(), false, FrameLoadTypeStandard, formState); } -void FrameLoader::sendRemainingDelegateMessages(unsigned long identifier, const ResourceResponse& response, int length, const ResourceError& error) -{ - if (!response.isNull()) - dispatchDidReceiveResponse(m_documentLoader.get(), identifier, response); - - if (length > 0) - dispatchDidReceiveContentLength(m_documentLoader.get(), identifier, length); - - if (error.isNull()) - dispatchDidFinishLoading(m_documentLoader.get(), identifier); - else - m_client->dispatchDidFailLoading(m_documentLoader.get(), identifier, error); -} - void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& identifier, ResourceError& error) { ASSERT(!request.isNull()); @@ -4192,11 +3485,11 @@ void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& i identifier = 0; if (Page* page = m_frame->page()) { identifier = page->progress()->createUniqueIdentifier(); - dispatchAssignIdentifierToInitialRequest(identifier, m_documentLoader.get(), request); + notifier()->assignIdentifierToInitialRequest(identifier, m_documentLoader.get(), request); } ResourceRequest newRequest(request); - dispatchWillSendRequest(m_documentLoader.get(), identifier, newRequest, ResourceResponse()); + notifier()->dispatchWillSendRequest(m_documentLoader.get(), identifier, newRequest, ResourceResponse()); if (newRequest.isNull()) error = cancelledError(request); @@ -4234,7 +3527,7 @@ void FrameLoader::loadedResourceFromMemoryCache(const CachedResource* resource) unsigned long identifier; ResourceError error; requestFromDelegate(request, identifier, error); - sendRemainingDelegateMessages(identifier, resource->response(), resource->encodedSize(), error); + notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, resource->response(), resource->encodedSize(), error); } void FrameLoader::applyUserAgent(ResourceRequest& request) @@ -4262,34 +3555,9 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con return false; } -bool FrameLoader::canGoBackOrForward(int distance) const -{ - if (Page* page = m_frame->page()) { - if (distance == 0) - return true; - if (distance > 0 && distance <= page->backForwardList()->forwardListCount()) - return true; - if (distance < 0 && -distance <= page->backForwardList()->backListCount()) - return true; - } - return false; -} - -int FrameLoader::getHistoryLength() -{ - if (Page* page = m_frame->page()) - return page->backForwardList()->backListCount() + 1; - return 0; -} - -void FrameLoader::addHistoryItemForFragmentScroll() -{ - addBackForwardItemClippedAtTarget(false); -} - bool FrameLoader::loadProvisionalItemFromCachedPage() { - RefPtr<CachedPage> cachedPage = pageCache()->get(m_provisionalHistoryItem.get()); + RefPtr<CachedPage> cachedPage = pageCache()->get(history()->provisionalItem()); if (!cachedPage || !cachedPage->document()) return false; @@ -4333,119 +3601,21 @@ void FrameLoader::pageHidden() bool FrameLoader::shouldTreatURLAsSameAsCurrent(const KURL& url) const { - if (!m_currentHistoryItem) + if (!history()->currentItem()) return false; - return url == m_currentHistoryItem->url() || url == m_currentHistoryItem->originalURL(); -} - -PassRefPtr<HistoryItem> FrameLoader::createHistoryItem(bool useOriginal) -{ - DocumentLoader* docLoader = documentLoader(); - - KURL unreachableURL = docLoader ? docLoader->unreachableURL() : KURL(); - - KURL url; - KURL originalURL; - - if (!unreachableURL.isEmpty()) { - url = unreachableURL; - originalURL = unreachableURL; - } else { - originalURL = docLoader ? docLoader->originalURL() : KURL(); - if (useOriginal) - url = originalURL; - else if (docLoader) - url = docLoader->requestURL(); - } - - LOG(History, "WebCoreHistory: Creating item for %s", url.string().ascii().data()); - - // Frames that have never successfully loaded any content - // may have no URL at all. Currently our history code can't - // deal with such things, so we nip that in the bud here. - // Later we may want to learn to live with nil for URL. - // See bug 3368236 and related bugs for more information. - if (url.isEmpty()) - url = blankURL(); - if (originalURL.isEmpty()) - originalURL = blankURL(); - - Frame* parentFrame = m_frame->tree()->parent(); - String parent = parentFrame ? parentFrame->tree()->name() : ""; - String title = docLoader ? docLoader->title() : ""; - - RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->name(), parent, title); - item->setOriginalURLString(originalURL.string()); - - if (!unreachableURL.isEmpty() || !docLoader || docLoader->response().httpStatusCode() >= 400) - item->setLastVisitWasFailure(true); - - // Save form state if this is a POST - if (docLoader) { - if (useOriginal) - item->setFormInfoFromRequest(docLoader->originalRequest()); - else - item->setFormInfoFromRequest(docLoader->request()); - } - - // Set the item for which we will save document state - m_previousHistoryItem = m_currentHistoryItem; - m_currentHistoryItem = item; - - return item.release(); + return url == history()->currentItem()->url() || url == history()->currentItem()->originalURL(); } -void FrameLoader::addBackForwardItemClippedAtTarget(bool doClip) +void FrameLoader::checkDidPerformFirstNavigation() { - // In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree. - // The item that was the target of the user's navigation is designated as the "targetItem". - // When this function is called with doClip=true we're able to create the whole tree except for the target's children, - // which will be loaded in the future. That part of the tree will be filled out as the child loads are committed. - Page* page = m_frame->page(); if (!page) return; - if (documentLoader()->urlForHistory().isEmpty()) - return; - - Frame* mainFrame = page->mainFrame(); - ASSERT(mainFrame); - FrameLoader* frameLoader = mainFrame->loader(); - - if (!frameLoader->m_didPerformFirstNavigation && page->backForwardList()->entries().size() == 1) { - frameLoader->m_didPerformFirstNavigation = true; + if (!m_didPerformFirstNavigation && page->backForwardList()->entries().size() == 1) { + m_didPerformFirstNavigation = true; m_client->didPerformFirstNavigation(); } - - RefPtr<HistoryItem> item = frameLoader->createHistoryItemTree(m_frame, doClip); - LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame %s", item.get(), documentLoader()->url().string().ascii().data()); - page->backForwardList()->addItem(item); -} - -PassRefPtr<HistoryItem> FrameLoader::createHistoryItemTree(Frame* targetFrame, bool clipAtTarget) -{ - RefPtr<HistoryItem> bfItem = createHistoryItem(m_frame->tree()->parent() ? true : false); - if (m_previousHistoryItem) - saveScrollPositionAndViewStateToItem(m_previousHistoryItem.get()); - if (!(clipAtTarget && m_frame == targetFrame)) { - // save frame state for items that aren't loading (khtml doesn't save those) - saveDocumentState(); - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { - FrameLoader* childLoader = child->loader(); - bool hasChildLoaded = childLoader->frameHasLoaded(); - - // If the child is a frame corresponding to an <object> element that never loaded, - // we don't want to create a history item, because that causes fallback content - // to be ignored on reload. - - if (!(!hasChildLoaded && childLoader->isHostedByObjectElement())) - bfItem->addChildItem(childLoader->createHistoryItemTree(targetFrame, clipAtTarget)); - } - } - if (m_frame == targetFrame) - bfItem->setIsTargetItem(true); - return bfItem; } Frame* FrameLoader::findFrameForNavigation(const AtomicString& name) @@ -4456,100 +3626,10 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name) return frame; } -void FrameLoader::saveScrollPositionAndViewStateToItem(HistoryItem* item) -{ - if (!item || !m_frame->view()) - return; - - item->setScrollPoint(m_frame->view()->scrollPosition()); - // FIXME: It would be great to work out a way to put this code in WebCore instead of calling through to the client. - m_client->saveViewStateToItem(item); -} - -/* - There is a race condition between the layout and load completion that affects restoring the scroll position. - We try to restore the scroll position at both the first layout and upon load completion. - - 1) If first layout happens before the load completes, we want to restore the scroll position then so that the - first time we draw the page is already scrolled to the right place, instead of starting at the top and later - jumping down. It is possible that the old scroll position is past the part of the doc laid out so far, in - which case the restore silent fails and we will fix it in when we try to restore on doc completion. - 2) If the layout happens after the load completes, the attempt to restore at load completion time silently - fails. We then successfully restore it when the layout happens. -*/ -void FrameLoader::restoreScrollPositionAndViewState() -{ - if (!m_committedFirstRealDocumentLoad) - return; - - ASSERT(m_currentHistoryItem); - - // FIXME: As the ASSERT attests, it seems we should always have a currentItem here. - // One counterexample is <rdar://problem/4917290> - // For now, to cover this issue in release builds, there is no technical harm to returning - // early and from a user standpoint - as in the above radar - the previous page load failed - // so there *is* no scroll or view state to restore! - if (!m_currentHistoryItem) - return; - - // FIXME: It would be great to work out a way to put this code in WebCore instead of calling - // through to the client. It's currently used only for the PDF view on Mac. - m_client->restoreViewState(); - - if (FrameView* view = m_frame->view()) - if (!view->wasScrolledByUser()) - view->setScrollPosition(m_currentHistoryItem->scrollPoint()); -} - -void FrameLoader::invalidateCurrentItemCachedPage() -{ - // When we are pre-commit, the currentItem is where the pageCache data resides - CachedPage* cachedPage = pageCache()->get(m_currentHistoryItem.get()); - - // FIXME: This is a grotesque hack to fix <rdar://problem/4059059> Crash in RenderFlow::detach - // Somehow the PageState object is not properly updated, and is holding onto a stale document. - // Both Xcode and FileMaker see this crash, Safari does not. - - ASSERT(!cachedPage || cachedPage->document() == m_frame->document()); - if (cachedPage && cachedPage->document() == m_frame->document()) { - cachedPage->document()->setInPageCache(false); - cachedPage->clear(); - } - - if (cachedPage) - pageCache()->remove(m_currentHistoryItem.get()); -} - -void FrameLoader::saveDocumentState() -{ - if (m_creatingInitialEmptyDocument) - return; - - // For a standard page load, we will have a previous item set, which will be used to - // store the form state. However, in some cases we will have no previous item, and - // the current item is the right place to save the state. One example is when we - // detach a bunch of frames because we are navigating from a site with frames to - // another site. Another is when saving the frame state of a frame that is not the - // target of the current navigation (if we even decide to save with that granularity). - - // Because of previousItem's "masking" of currentItem for this purpose, it's important - // that previousItem be cleared at the end of a page transition. We leverage the - // checkLoadComplete recursion to achieve this goal. - - HistoryItem* item = m_previousHistoryItem ? m_previousHistoryItem.get() : m_currentHistoryItem.get(); - if (!item) - return; - - Document* document = m_frame->document(); - ASSERT(document); - - if (item->isCurrentDocument(document)) { - LOG(Loading, "WebCoreLoading %s: saving form state to %p", m_frame->tree()->name().string().utf8().data(), item); - item->setDocumentState(document->formElementsState()); - } -} - // Loads content into this frame, as specified by history item +// FIXME: This function should really be split into a couple pieces, some of +// which should be methods of HistoryController and some of which should be +// methods of FrameLoader. void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) { if (!m_frame->page()) @@ -4568,7 +3648,7 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) // check for all that as an additional optimization. // We also do not do anchor-style navigation if we're posting a form or navigating from // a page that was resulted from a form post. - bool shouldScroll = !formData && !(m_currentHistoryItem && m_currentHistoryItem->formData()) && urlsMatchItem(item); + bool shouldScroll = !formData && !(history()->currentItem() && history()->currentItem()->formData()) && history()->urlsMatchItem(item); #if ENABLE(WML) // All WML decks should go through the real load mechanism, not the scroll-to-anchor code @@ -4578,12 +3658,12 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) if (shouldScroll) { // Must do this maintenance here, since we don't go through a real page reload - saveScrollPositionAndViewStateToItem(m_currentHistoryItem.get()); + history()->saveScrollPositionAndViewStateToItem(history()->currentItem()); if (FrameView* view = m_frame->view()) view->setWasScrolledByUser(false); - m_currentHistoryItem = item; + history()->setCurrentItem(item); // FIXME: Form state might need to be saved here too. @@ -4592,7 +3672,7 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) scrollToAnchor(item->url()); // must do this maintenance here, since we don't go through a real page reload - restoreScrollPositionAndViewState(); + history()->restoreScrollPositionAndViewState(); // Fake the URL change by updating the data source's request. This will no longer // be necessary if we do the better fix described above. @@ -4604,7 +3684,7 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) m_client->didFinishLoad(); } else { // Remember this item so we can traverse any child items as child frames load - m_provisionalHistoryItem = item; + history()->setProvisionalItem(item); bool inPageCache = false; @@ -4621,7 +3701,7 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) loadWithDocumentLoader(cachedPage->documentLoader(), loadType, 0); inPageCache = true; } else { - LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", m_provisionalHistoryItem->url().string().ascii().data()); + LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", history()->provisionalItem()->url().string().ascii().data()); pageCache()->remove(item); } } @@ -4696,322 +3776,6 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) } } -// Walk the frame tree and ensure that the URLs match the URLs in the item. -bool FrameLoader::urlsMatchItem(HistoryItem* item) const -{ - const KURL& currentURL = documentLoader()->url(); - if (!equalIgnoringFragmentIdentifier(currentURL, item->url())) - return false; - - const HistoryItemVector& childItems = item->children(); - - unsigned size = childItems.size(); - for (unsigned i = 0; i < size; ++i) { - Frame* childFrame = m_frame->tree()->child(childItems[i]->target()); - if (childFrame && !childFrame->loader()->urlsMatchItem(childItems[i].get())) - return false; - } - - return true; -} - -// Main funnel for navigating to a previous location (back/forward, non-search snap-back) -// This includes recursion to handle loading into framesets properly -void FrameLoader::goToItem(HistoryItem* targetItem, FrameLoadType type) -{ - ASSERT(!m_frame->tree()->parent()); - - // shouldGoToHistoryItem is a private delegate method. This is needed to fix: - // <rdar://problem/3951283> can view pages from the back/forward cache that should be disallowed by Parental Controls - // Ultimately, history item navigations should go through the policy delegate. That's covered in: - // <rdar://problem/3979539> back/forward cache navigations should consult policy delegate - Page* page = m_frame->page(); - if (!page) - return; - if (!m_client->shouldGoToHistoryItem(targetItem)) - return; - - // Set the BF cursor before commit, which lets the user quickly click back/forward again. - // - plus, it only makes sense for the top level of the operation through the frametree, - // as opposed to happening for some/one of the page commits that might happen soon - BackForwardList* bfList = page->backForwardList(); - HistoryItem* currentItem = bfList->currentItem(); - bfList->goToItem(targetItem); - Settings* settings = m_frame->settings(); - page->setGlobalHistoryItem((!settings || settings->privateBrowsingEnabled()) ? 0 : targetItem); - recursiveGoToItem(targetItem, currentItem, type); -} - -// The general idea here is to traverse the frame tree and the item tree in parallel, -// tracking whether each frame already has the content the item requests. If there is -// a match (by URL), we just restore scroll position and recurse. Otherwise we must -// reload that frame, and all its kids. -void FrameLoader::recursiveGoToItem(HistoryItem* item, HistoryItem* fromItem, FrameLoadType type) -{ - ASSERT(item); - ASSERT(fromItem); - - KURL itemURL = item->url(); - KURL currentURL; - if (documentLoader()) - currentURL = documentLoader()->url(); - - // Always reload the target frame of the item we're going to. This ensures that we will - // do -some- load for the transition, which means a proper notification will be posted - // to the app. - // The exact URL has to match, including fragment. We want to go through the _load - // method, even if to do a within-page navigation. - // The current frame tree and the frame tree snapshot in the item have to match. - if (!item->isTargetItem() && - itemURL == currentURL && - ((m_frame->tree()->name().isEmpty() && item->target().isEmpty()) || m_frame->tree()->name() == item->target()) && - childFramesMatchItem(item)) - { - // This content is good, so leave it alone and look for children that need reloading - // Save form state (works from currentItem, since prevItem is nil) - ASSERT(!m_previousHistoryItem); - saveDocumentState(); - saveScrollPositionAndViewStateToItem(m_currentHistoryItem.get()); - - if (FrameView* view = m_frame->view()) - view->setWasScrolledByUser(false); - - m_currentHistoryItem = item; - - // Restore form state (works from currentItem) - restoreDocumentState(); - - // Restore the scroll position (we choose to do this rather than going back to the anchor point) - restoreScrollPositionAndViewState(); - - const HistoryItemVector& childItems = item->children(); - - int size = childItems.size(); - for (int i = 0; i < size; ++i) { - String childFrameName = childItems[i]->target(); - HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName); - ASSERT(fromChildItem || fromItem->isTargetItem()); - Frame* childFrame = m_frame->tree()->child(childFrameName); - ASSERT(childFrame); - childFrame->loader()->recursiveGoToItem(childItems[i].get(), fromChildItem, type); - } - } else { - loadItem(item, type); - } -} - -// helper method that determines whether the subframes described by the item's subitems -// match our own current frameset -bool FrameLoader::childFramesMatchItem(HistoryItem* item) const -{ - const HistoryItemVector& childItems = item->children(); - if (childItems.size() != m_frame->tree()->childCount()) - return false; - - unsigned size = childItems.size(); - for (unsigned i = 0; i < size; ++i) { - if (!m_frame->tree()->child(childItems[i]->target())) - return false; - } - - // Found matches for all item targets - return true; -} - -// There are 3 things you might think of as "history", all of which are handled by these functions. -// -// 1) Back/forward: The m_currentHistoryItem is part of this mechanism. -// 2) Global history: Handled by the client. -// 3) Visited links: Handled by the PageGroup. - -void FrameLoader::updateHistoryForStandardLoad() -{ - LOG(History, "WebCoreHistory: Updating History for Standard Load in frame %s", documentLoader()->url().string().ascii().data()); - - Settings* settings = m_frame->settings(); - bool needPrivacy = !settings || settings->privateBrowsingEnabled(); - const KURL& historyURL = documentLoader()->urlForHistory(); - - if (!documentLoader()->isClientRedirect()) { - if (!historyURL.isEmpty()) { - addBackForwardItemClippedAtTarget(true); - if (!needPrivacy) { - m_client->updateGlobalHistory(); - m_documentLoader->setDidCreateGlobalHistoryEntry(true); - if (m_documentLoader->unreachableURL().isEmpty()) - m_client->updateGlobalHistoryRedirectLinks(); - } - if (Page* page = m_frame->page()) - page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwardList()->currentItem()); - } - } else if (documentLoader()->unreachableURL().isEmpty() && m_currentHistoryItem) { - m_currentHistoryItem->setURL(documentLoader()->url()); - m_currentHistoryItem->setFormInfoFromRequest(documentLoader()->request()); - } - - if (!historyURL.isEmpty() && !needPrivacy) { - if (Page* page = m_frame->page()) - page->group().addVisitedLink(historyURL); - - if (!m_documentLoader->didCreateGlobalHistoryEntry() && documentLoader()->unreachableURL().isEmpty() && !url().isEmpty()) - m_client->updateGlobalHistoryRedirectLinks(); - } -} - -void FrameLoader::updateHistoryForClientRedirect() -{ -#if !LOG_DISABLED - if (documentLoader()) - LOG(History, "WebCoreHistory: Updating History for client redirect in frame %s", documentLoader()->title().utf8().data()); -#endif - - // Clear out form data so we don't try to restore it into the incoming page. Must happen after - // webcore has closed the URL and saved away the form state. - if (m_currentHistoryItem) { - m_currentHistoryItem->clearDocumentState(); - m_currentHistoryItem->clearScrollPoint(); - } - - Settings* settings = m_frame->settings(); - bool needPrivacy = !settings || settings->privateBrowsingEnabled(); - const KURL& historyURL = documentLoader()->urlForHistory(); - - if (!historyURL.isEmpty() && !needPrivacy) { - if (Page* page = m_frame->page()) - page->group().addVisitedLink(historyURL); - } -} - -void FrameLoader::updateHistoryForBackForwardNavigation() -{ -#if !LOG_DISABLED - if (documentLoader()) - LOG(History, "WebCoreHistory: Updating History for back/forward navigation in frame %s", documentLoader()->title().utf8().data()); -#endif - - // Must grab the current scroll position before disturbing it - saveScrollPositionAndViewStateToItem(m_previousHistoryItem.get()); -} - -void FrameLoader::updateHistoryForReload() -{ -#if !LOG_DISABLED - if (documentLoader()) - LOG(History, "WebCoreHistory: Updating History for reload in frame %s", documentLoader()->title().utf8().data()); -#endif - - if (m_currentHistoryItem) { - pageCache()->remove(m_currentHistoryItem.get()); - - if (loadType() == FrameLoadTypeReload || loadType() == FrameLoadTypeReloadFromOrigin) - saveScrollPositionAndViewStateToItem(m_currentHistoryItem.get()); - - // Sometimes loading a page again leads to a different result because of cookies. Bugzilla 4072 - if (documentLoader()->unreachableURL().isEmpty()) - m_currentHistoryItem->setURL(documentLoader()->requestURL()); - } -} - -void FrameLoader::updateHistoryForRedirectWithLockedBackForwardList() -{ -#if !LOG_DISABLED - if (documentLoader()) - LOG(History, "WebCoreHistory: Updating History for redirect load in frame %s", documentLoader()->title().utf8().data()); -#endif - - Settings* settings = m_frame->settings(); - bool needPrivacy = !settings || settings->privateBrowsingEnabled(); - const KURL& historyURL = documentLoader()->urlForHistory(); - - if (documentLoader()->isClientRedirect()) { - if (!m_currentHistoryItem && !m_frame->tree()->parent()) { - if (!historyURL.isEmpty()) { - addBackForwardItemClippedAtTarget(true); - if (!needPrivacy) { - m_client->updateGlobalHistory(); - m_documentLoader->setDidCreateGlobalHistoryEntry(true); - if (m_documentLoader->unreachableURL().isEmpty()) - m_client->updateGlobalHistoryRedirectLinks(); - } - if (Page* page = m_frame->page()) - page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwardList()->currentItem()); - } - } - if (m_currentHistoryItem) { - m_currentHistoryItem->setURL(documentLoader()->url()); - m_currentHistoryItem->setFormInfoFromRequest(documentLoader()->request()); - } - } else { - Frame* parentFrame = m_frame->tree()->parent(); - if (parentFrame && parentFrame->loader()->m_currentHistoryItem) - parentFrame->loader()->m_currentHistoryItem->setChildItem(createHistoryItem(true)); - } - - if (!historyURL.isEmpty() && !needPrivacy) { - if (Page* page = m_frame->page()) - page->group().addVisitedLink(historyURL); - - if (!m_documentLoader->didCreateGlobalHistoryEntry() && documentLoader()->unreachableURL().isEmpty() && !url().isEmpty()) - m_client->updateGlobalHistoryRedirectLinks(); - } -} - -void FrameLoader::updateHistoryForCommit() -{ -#if !LOG_DISABLED - if (documentLoader()) - LOG(History, "WebCoreHistory: Updating History for commit in frame %s", documentLoader()->title().utf8().data()); -#endif - FrameLoadType type = loadType(); - if (isBackForwardLoadType(type) || - ((type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigin) && !provisionalDocumentLoader()->unreachableURL().isEmpty())) { - // Once committed, we want to use current item for saving DocState, and - // the provisional item for restoring state. - // Note previousItem must be set before we close the URL, which will - // happen when the data source is made non-provisional below - m_previousHistoryItem = m_currentHistoryItem; - ASSERT(m_provisionalHistoryItem); - m_currentHistoryItem = m_provisionalHistoryItem; - m_provisionalHistoryItem = 0; - } -} - -void FrameLoader::updateHistoryForAnchorScroll() -{ - if (m_URL.isEmpty()) - return; - - Settings* settings = m_frame->settings(); - if (!settings || settings->privateBrowsingEnabled()) - return; - - Page* page = m_frame->page(); - if (!page) - return; - - page->group().addVisitedLink(m_URL); -} - -// Walk the frame tree, telling all frames to save their form state into their current -// history item. -void FrameLoader::saveDocumentAndScrollState() -{ - for (Frame* frame = m_frame; frame; frame = frame->tree()->traverseNext(m_frame)) { - frame->loader()->saveDocumentState(); - frame->loader()->saveScrollPositionAndViewStateToItem(frame->loader()->currentHistoryItem()); - } -} - -HistoryItem* FrameLoader::currentHistoryItem() -{ - return m_currentHistoryItem.get(); -} - -void FrameLoader::setCurrentHistoryItem(PassRefPtr<HistoryItem> item) -{ - m_currentHistoryItem = item; -} - void FrameLoader::setMainDocumentError(DocumentLoader* loader, const ResourceError& error) { m_client->setMainDocumentError(loader, error); @@ -5053,116 +3817,11 @@ ResourceError FrameLoader::fileDoesNotExistError(const ResourceResponse& respons return m_client->fileDoesNotExistError(response); } -void FrameLoader::didFinishLoad(ResourceLoader* loader) -{ - if (Page* page = m_frame->page()) - page->progress()->completeProgress(loader->identifier()); - dispatchDidFinishLoading(loader->documentLoader(), loader->identifier()); -} - bool FrameLoader::shouldUseCredentialStorage(ResourceLoader* loader) { return m_client->shouldUseCredentialStorage(loader->documentLoader(), loader->identifier()); } -void FrameLoader::didReceiveAuthenticationChallenge(ResourceLoader* loader, const AuthenticationChallenge& currentWebChallenge) -{ - m_client->dispatchDidReceiveAuthenticationChallenge(loader->documentLoader(), loader->identifier(), currentWebChallenge); -} - -void FrameLoader::didCancelAuthenticationChallenge(ResourceLoader* loader, const AuthenticationChallenge& currentWebChallenge) -{ - m_client->dispatchDidCancelAuthenticationChallenge(loader->documentLoader(), loader->identifier(), currentWebChallenge); -} - -PolicyCheck::PolicyCheck() - : m_navigationFunction(0) - , m_newWindowFunction(0) - , m_contentFunction(0) -{ -} - -void PolicyCheck::clear() -{ - clearRequest(); - m_navigationFunction = 0; - m_newWindowFunction = 0; - m_contentFunction = 0; -} - -void PolicyCheck::set(const ResourceRequest& request, PassRefPtr<FormState> formState, - NavigationPolicyDecisionFunction function, void* argument) -{ - m_request = request; - m_formState = formState; - m_frameName = String(); - - m_navigationFunction = function; - m_newWindowFunction = 0; - m_contentFunction = 0; - m_argument = argument; -} - -void PolicyCheck::set(const ResourceRequest& request, PassRefPtr<FormState> formState, - const String& frameName, NewWindowPolicyDecisionFunction function, void* argument) -{ - m_request = request; - m_formState = formState; - m_frameName = frameName; - - m_navigationFunction = 0; - m_newWindowFunction = function; - m_contentFunction = 0; - m_argument = argument; -} - -void PolicyCheck::set(ContentPolicyDecisionFunction function, void* argument) -{ - m_request = ResourceRequest(); - m_formState = 0; - m_frameName = String(); - - m_navigationFunction = 0; - m_newWindowFunction = 0; - m_contentFunction = function; - m_argument = argument; -} - -void PolicyCheck::call(bool shouldContinue) -{ - if (m_navigationFunction) - m_navigationFunction(m_argument, m_request, m_formState.get(), shouldContinue); - if (m_newWindowFunction) - m_newWindowFunction(m_argument, m_request, m_formState.get(), m_frameName, shouldContinue); - ASSERT(!m_contentFunction); -} - -void PolicyCheck::call(PolicyAction action) -{ - ASSERT(!m_navigationFunction); - ASSERT(!m_newWindowFunction); - ASSERT(m_contentFunction); - m_contentFunction(m_argument, action); -} - -void PolicyCheck::clearRequest() -{ - m_request = ResourceRequest(); - m_formState = 0; - m_frameName = String(); -} - -void PolicyCheck::cancel() -{ - clearRequest(); - if (m_navigationFunction) - m_navigationFunction(m_argument, m_request, m_formState.get(), false); - if (m_newWindowFunction) - m_newWindowFunction(m_argument, m_request, m_formState.get(), m_frameName, false); - if (m_contentFunction) - m_contentFunction(m_argument, PolicyIgnore); -} - void FrameLoader::setTitle(const String& title) { documentLoader()->setTitle(title); @@ -5219,7 +3878,7 @@ PassRefPtr<Widget> FrameLoader::createJavaAppletWidget(const IntSize& size, HTML if (!codeBaseURLString.isEmpty()) { KURL codeBaseURL = completeURL(codeBaseURLString); - if (!canLoad(codeBaseURL, String(), element->document())) { + if (!SecurityOrigin::canLoad(codeBaseURL, String(), element->document())) { FrameLoader::reportLocalLoadFailed(m_frame, codeBaseURL.string()); return 0; } @@ -5243,8 +3902,7 @@ void FrameLoader::didChangeTitle(DocumentLoader* loader) if (loader == m_documentLoader) { // Must update the entries in the back-forward list too. - if (m_currentHistoryItem) - m_currentHistoryItem->setTitle(loader->title()); + history()->setCurrentItemTitle(loader->title()); // This must go through the WebFrame because it has the right notion of the current b/f item. m_client->setTitle(loader->title(), loader->urlForHistory()); m_client->setMainFrameDocumentReady(true); // update observers with new DOMDocument @@ -5269,63 +3927,6 @@ void FrameLoader::dispatchDidCommitLoad() #endif } -void FrameLoader::dispatchAssignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) -{ - m_client->assignIdentifierToInitialRequest(identifier, loader, request); - -#if ENABLE(INSPECTOR) - if (Page* page = m_frame->page()) - page->inspectorController()->identifierForInitialRequest(identifier, loader, request); -#endif -} - -void FrameLoader::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) -{ - StringImpl* oldRequestURL = request.url().string().impl(); - m_documentLoader->didTellClientAboutLoad(request.url()); - - m_client->dispatchWillSendRequest(loader, identifier, request, redirectResponse); - - // If the URL changed, then we want to put that new URL in the "did tell client" set too. - if (!request.isNull() && oldRequestURL != request.url().string().impl()) - m_documentLoader->didTellClientAboutLoad(request.url()); - -#if ENABLE(INSPECTOR) - if (Page* page = m_frame->page()) - page->inspectorController()->willSendRequest(loader, identifier, request, redirectResponse); -#endif -} - -void FrameLoader::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) -{ - m_client->dispatchDidReceiveResponse(loader, identifier, r); - -#if ENABLE(INSPECTOR) - if (Page* page = m_frame->page()) - page->inspectorController()->didReceiveResponse(loader, identifier, r); -#endif -} - -void FrameLoader::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length) -{ - m_client->dispatchDidReceiveContentLength(loader, identifier, length); - -#if ENABLE(INSPECTOR) - if (Page* page = m_frame->page()) - page->inspectorController()->didReceiveContentLength(loader, identifier, length); -#endif -} - -void FrameLoader::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier) -{ - m_client->dispatchDidFinishLoading(loader, identifier); - -#if ENABLE(INSPECTOR) - if (Page* page = m_frame->page()) - page->inspectorController()->didFinishLoading(loader, identifier); -#endif -} - void FrameLoader::tellClientAboutPastMemoryCacheLoads() { ASSERT(m_frame->page()); |