Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / loader / FrameLoader.cpp
index 7f63f13..2f1bb96 100644 (file)
@@ -71,7 +71,6 @@
 #include "core/loader/ProgressTracker.h"
 #include "core/loader/UniqueIdentifier.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/page/BackForwardClient.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/CreateWindow.h"
@@ -102,7 +101,7 @@ using namespace HTMLNames;
 
 bool isBackForwardLoadType(FrameLoadType type)
 {
-    return type == FrameLoadTypeBackForward;
+    return type == FrameLoadTypeBackForward || type == FrameLoadTypeInitialHistoryLoad;
 }
 
 static bool needsHistoryItemRestore(FrameLoadType type)
@@ -137,6 +136,9 @@ void FrameLoader::trace(Visitor* visitor)
     visitor->trace(m_mixedContentChecker);
     visitor->trace(m_progressTracker);
     visitor->trace(m_fetchContext);
+    visitor->trace(m_currentItem);
+    visitor->trace(m_provisionalItem);
+    visitor->trace(m_deferredHistoryLoad);
 }
 
 void FrameLoader::init()
@@ -166,7 +168,8 @@ void FrameLoader::setDefersLoading(bool defers)
 
     if (!defers) {
         if (m_deferredHistoryLoad.isValid()) {
-            loadHistoryItem(m_deferredHistoryLoad.m_item.get(), m_deferredHistoryLoad.m_type, m_deferredHistoryLoad.m_cachePolicy);
+            loadHistoryItem(m_deferredHistoryLoad.m_item.get(), FrameLoadTypeBackForward,
+                m_deferredHistoryLoad.m_type, m_deferredHistoryLoad.m_cachePolicy);
             m_deferredHistoryLoad = DeferredHistoryLoad();
         }
         m_frame->navigationScheduler().startTimer();
@@ -239,8 +242,10 @@ bool FrameLoader::closeURL()
 void FrameLoader::didExplicitOpen()
 {
     // Calling document.open counts as committing the first real document load.
-    if (!m_stateMachine.committedFirstRealDocumentLoad())
+    if (!m_stateMachine.committedFirstRealDocumentLoad()) {
         m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
+        m_progressTracker->progressStarted();
+    }
 
     // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
     // from a subsequent window.document.open / window.document.write call.
@@ -251,8 +256,9 @@ void FrameLoader::didExplicitOpen()
 
 void FrameLoader::clear()
 {
-    // clear() is called during (Local)Frame finalization and when creating
-    // a new Document within it (DocumentLoader::createWriterFor().)
+    // clear() is called during (Local)Frame detachment or when
+    // reusing a FrameLoader by putting a new Document within it
+    // (DocumentLoader::ensureWriter().)
     if (m_stateMachine.creatingInitialEmptyDocument())
         return;
 
@@ -283,7 +289,7 @@ void FrameLoader::replaceDocumentWhileExecutingJavaScriptURL(const String& sourc
     if (!m_frame->document()->loader())
         return;
 
-    // DocumentWriter::replaceDocumentWhileExecutingJavaScriptURL can cause the DocumentLoader to get deref'ed and possible destroyed,
+    // DocumentLoader::replaceDocumentWhileExecutingJavaScriptURL can cause the DocumentLoader to get deref'ed and possible destroyed,
     // so protect it with a RefPtr.
     RefPtr<DocumentLoader> documentLoader(m_frame->document()->loader());
 
@@ -333,6 +339,7 @@ static HistoryCommitType loadTypeToCommitType(FrameLoadType type)
     case FrameLoadTypeStandard:
         return StandardCommit;
     case FrameLoadTypeInitialInChildFrame:
+    case FrameLoadTypeInitialHistoryLoad:
         return InitialCommitInChildFrame;
     case FrameLoadTypeBackForward:
         return BackForwardCommit;
@@ -368,9 +375,6 @@ void FrameLoader::didBeginDocument(bool dispatch)
 {
     m_frame->document()->setReadyState(Document::Loading);
 
-    if (m_provisionalItem && m_loadType == FrameLoadTypeBackForward)
-        m_frame->domWindow()->statePopped(m_provisionalItem->stateObject());
-
     if (dispatch)
         dispatchDidClearDocumentOfWindowObject();
 
@@ -397,7 +401,7 @@ void FrameLoader::didBeginDocument(bool dispatch)
         }
     }
 
-    if (m_provisionalItem && m_loadType == FrameLoadTypeBackForward)
+    if (m_provisionalItem && (m_loadType == FrameLoadTypeBackForward || m_loadType == FrameLoadTypeInitialHistoryLoad))
         m_frame->document()->setStateForNewFormElements(m_provisionalItem->documentState());
 }
 
@@ -617,21 +621,22 @@ void FrameLoader::completed()
 
 void FrameLoader::setReferrerForFrameRequest(ResourceRequest& request, ShouldSendReferrer shouldSendReferrer, Document* originDocument)
 {
-    if (shouldSendReferrer == NeverSendReferrer) {
-        request.clearHTTPReferrer();
+    if (!originDocument)
+        return;
+    // FIXME: This should be an assertion, but there's some plugin code in the chromium repo
+    // that both determines its own referrer and expects to be associated with an originDocument.
+    if (!request.httpReferrer().isEmpty())
+        return;
+    if (shouldSendReferrer == NeverSendReferrer)
         return;
-    }
 
     // Always use the initiating document to generate the referrer.
-    // We need to generateReferrerHeader(), because we might not have enforced ReferrerPolicy or https->http
+    // We need to generateReferrer(), because we haven't enforced ReferrerPolicy or https->http
     // referrer suppression yet.
-    String argsReferrer(request.httpReferrer());
-    if (argsReferrer.isEmpty())
-        argsReferrer = originDocument->outgoingReferrer();
-    String referrer = SecurityPolicy::generateReferrerHeader(originDocument->referrerPolicy(), request.url(), argsReferrer);
+    Referrer referrer = SecurityPolicy::generateReferrer(originDocument->referrerPolicy(), request.url(), originDocument->outgoingReferrer());
 
-    request.setHTTPReferrer(Referrer(referrer, originDocument->referrerPolicy()));
-    RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer);
+    request.setHTTPReferrer(referrer);
+    RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer.referrer);
     request.addHTTPOriginIfNeeded(referrerOrigin->toAtomicString());
 }
 
@@ -649,7 +654,7 @@ FrameLoadType FrameLoader::determineFrameLoadType(const FrameLoadRequest& reques
 {
     if (m_frame->tree().parent() && !m_stateMachine.committedFirstRealDocumentLoad())
         return FrameLoadTypeInitialInChildFrame;
-    if (!m_frame->tree().parent() && !m_frame->page()->backForward().backForwardListCount())
+    if (!m_frame->tree().parent() && !client()->backForwardLength())
         return FrameLoadTypeStandard;
     if (m_provisionalDocumentLoader && request.substituteData().failingURL() == m_provisionalDocumentLoader->url() && m_loadType == FrameLoadTypeBackForward)
         return FrameLoadTypeBackForward;
@@ -685,8 +690,6 @@ bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request)
 
     if (!request.formState() && request.frameName().isEmpty())
         request.setFrameName(m_frame->document()->baseTarget());
-
-    setReferrerForFrameRequest(request.resourceRequest(), request.shouldSendReferrer(), request.originDocument());
     return true;
 }
 
@@ -742,6 +745,8 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
         return;
     }
 
+    setReferrerForFrameRequest(request.resourceRequest(), request.shouldSendReferrer(), request.originDocument());
+
     FrameLoadType newLoadType = determineFrameLoadType(request);
     NavigationAction action(request.resourceRequest(), newLoadType, request.formState(), request.triggeringEvent());
     if (action.resourceRequest().requestContext() == WebURLRequest::RequestContextUnspecified)
@@ -794,7 +799,8 @@ void FrameLoader::reportLocalLoadFailed(LocalFrame* frame, const String& url)
 ResourceRequest FrameLoader::requestFromHistoryItem(HistoryItem* item, ResourceRequestCachePolicy cachePolicy)
 {
     RefPtr<FormData> formData = item->formData();
-    ResourceRequest request(item->url(), item->referrer());
+    ResourceRequest request(item->url());
+    request.setHTTPReferrer(item->referrer());
     request.setCachePolicy(cachePolicy);
     if (formData) {
         request.setHTTPMethod("POST");
@@ -806,7 +812,7 @@ ResourceRequest FrameLoader::requestFromHistoryItem(HistoryItem* item, ResourceR
     return request;
 }
 
-void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, const AtomicString& overrideEncoding, ClientRedirectPolicy clientRedirectPolicy)
+void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, ClientRedirectPolicy clientRedirectPolicy)
 {
     if (!m_currentItem)
         return;
@@ -832,7 +838,7 @@ void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, con
     request.setSkipServiceWorker(reloadPolicy == EndToEndReload);
 
     FrameLoadType type = reloadPolicy == EndToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload;
-    loadWithNavigationAction(NavigationAction(request, type), type, nullptr, SubstituteData(), CheckContentSecurityPolicy, clientRedirectPolicy, overrideEncoding);
+    loadWithNavigationAction(NavigationAction(request, type), type, nullptr, SubstituteData(), CheckContentSecurityPolicy, clientRedirectPolicy);
 }
 
 void FrameLoader::stopAllLoaders()
@@ -953,6 +959,7 @@ FrameLoadType FrameLoader::loadType() const
     return m_loadType;
 }
 
+#if defined(ENABLE_LOAD_COMPLETION_HACKS)
 // This function is an incomprehensible mess and is only used in checkLoadCompleteForThisFrame.
 // If you're thinking of using it elsewhere, stop right now and reconsider your life.
 static bool isDocumentDoneLoading(Document* document)
@@ -961,10 +968,8 @@ static bool isDocumentDoneLoading(Document* document)
         return true;
     if (document->loader()->isLoadingMainResource())
         return false;
-    if (!document->loadEventFinished()) {
-        if (document->loader()->isLoading() || document->isDelayingLoadEvent())
-            return false;
-    }
+    if (!document->loadEventFinished())
+        return false;
     if (document->fetcher()->requestCount())
         return false;
     if (document->processingLoadEvent())
@@ -973,6 +978,7 @@ static bool isDocumentDoneLoading(Document* document)
         return false;
     return true;
 }
+#endif
 
 bool FrameLoader::checkLoadCompleteForThisFrame()
 {
@@ -1008,8 +1014,16 @@ bool FrameLoader::checkLoadCompleteForThisFrame()
         return true;
     if (m_provisionalDocumentLoader || !m_documentLoader)
         return false;
+
+#if defined(ENABLE_LOAD_COMPLETION_HACKS)
     if (!isDocumentDoneLoading(m_frame->document()) && !m_inStopAllLoaders)
         return false;
+#else
+    if (m_inStopAllLoaders)
+        m_frame->document()->suppressLoadEvent();
+    if (!m_frame->document()->loadEventFinished())
+        return false;
+#endif
 
     m_state = FrameStateComplete;
 
@@ -1105,61 +1119,22 @@ String FrameLoader::userAgent(const KURL& url) const
     return userAgent;
 }
 
-void FrameLoader::detachFromParent()
+void FrameLoader::detach()
 {
 #if !ENABLE(OILPAN)
     // The caller must protect a reference to m_frame.
     ASSERT(m_frame->refCount() > 1);
 #endif
-
-    InspectorInstrumentation::frameDetachedFromParent(m_frame);
-
     if (m_documentLoader)
         m_documentLoader->detachFromFrame();
     m_documentLoader = nullptr;
 
-    if (!client())
-        return;
-
-    // FIXME: All this code belongs up in Page.
     Frame* parent = m_frame->tree().parent();
-    if (parent && parent->isLocalFrame()) {
-        m_frame->setView(nullptr);
-        // FIXME: Shouldn't need to check if page() is null here.
-        if (m_frame->owner() && m_frame->page())
-            m_frame->page()->decrementSubframeCount();
-        m_frame->willDetachFrameHost();
-        detachClient();
+    if (parent && parent->isLocalFrame())
         toLocalFrame(parent)->loader().scheduleCheckCompleted();
-    } else {
-        m_frame->setView(nullptr);
-        m_frame->willDetachFrameHost();
-        detachClient();
-    }
-    m_frame->detachFromFrameHost();
-}
-
-void FrameLoader::detachClient()
-{
-    ASSERT(client());
-
-    // Finish all cleanup work that might require talking to the embedder.
     m_progressTracker->dispose();
     m_progressTracker.clear();
     setOpener(0);
-    // Notify ScriptController that the frame is closing, since its cleanup ends up calling
-    // back to FrameLoaderClient via WindowProxy.
-    m_frame->script().clearForClose();
-
-    // client() should never be null because that means we somehow re-entered
-    // the frame detach code... but it is sometimes.
-    // FIXME: Understand why this is happening so we can document this insanity.
-    if (client()) {
-        // After this, we must no longer talk to the client since this clears
-        // its owning reference back to our owning LocalFrame.
-        client()->detachedFromParent();
-        m_frame->clearClient();
-    }
 }
 
 void FrameLoader::receivedMainResourceError(const ResourceError& error)
@@ -1254,8 +1229,8 @@ bool FrameLoader::shouldClose()
 
 bool FrameLoader::validateTransitionNavigationMode()
 {
-    if (frame()->document()->inQuirksMode()) {
-        frame()->document()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, "Ignoring transition elements due to quirks mode."));
+    if (m_frame->document()->inQuirksMode()) {
+        m_frame->document()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, "Ignoring transition elements due to quirks mode."));
         return false;
     }
 
@@ -1266,7 +1241,7 @@ bool FrameLoader::validateTransitionNavigationMode()
 bool FrameLoader::dispatchNavigationTransitionData()
 {
     Vector<Document::TransitionElementData> elementData;
-    frame()->document()->getTransitionElementData(elementData);
+    m_frame->document()->getTransitionElementData(elementData);
     if (elementData.isEmpty() || !validateTransitionNavigationMode())
         return false;
 
@@ -1277,7 +1252,7 @@ bool FrameLoader::dispatchNavigationTransitionData()
     return true;
 }
 
-void FrameLoader::loadWithNavigationAction(const NavigationAction& action, FrameLoadType type, PassRefPtrWillBeRawPtr<FormState> formState, const SubstituteData& substituteData, ContentSecurityPolicyCheck shouldCheckMainWorldContentSecurityPolicy, ClientRedirectPolicy clientRedirect, const AtomicString& overrideEncoding)
+void FrameLoader::loadWithNavigationAction(const NavigationAction& action, FrameLoadType type, PassRefPtrWillBeRawPtr<FormState> formState, const SubstituteData& substituteData, ContentSecurityPolicyCheck shouldCheckMainWorldContentSecurityPolicy, ClientRedirectPolicy clientRedirect)
 {
     ASSERT(client()->hasWebView());
     if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
@@ -1298,15 +1273,6 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame
     m_policyDocumentLoader->setReplacesCurrentHistoryItem(replacesCurrentHistoryItem);
     m_policyDocumentLoader->setIsClientRedirect(clientRedirect == ClientRedirect);
 
-    Frame* parent = m_frame->tree().parent();
-    if (parent && parent->isLocalFrame())
-        m_policyDocumentLoader->setOverrideEncoding(toLocalFrame(parent)->loader().documentLoader()->overrideEncoding());
-    else if (!overrideEncoding.isEmpty())
-        m_policyDocumentLoader->setOverrideEncoding(overrideEncoding);
-    else if (m_documentLoader)
-        m_policyDocumentLoader->setOverrideEncoding(m_documentLoader->overrideEncoding());
-
-
     bool isTransitionNavigation = false;
     if (RuntimeEnabledFeatures::navigationTransitionsEnabled() && type != FrameLoadTypeReload && type != FrameLoadTypeReloadFromOrigin && type != FrameLoadTypeSame)
         isTransitionNavigation = dispatchNavigationTransitionData();
@@ -1316,6 +1282,8 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame
     if ((!m_policyDocumentLoader->shouldContinueForNavigationPolicy(request, shouldCheckMainWorldContentSecurityPolicy, isTransitionNavigation) || !shouldClose()) && m_policyDocumentLoader) {
         m_policyDocumentLoader->detachFromFrame();
         m_policyDocumentLoader = nullptr;
+        if (!m_stateMachine.committedFirstRealDocumentLoad())
+            m_state = FrameStateComplete;
         checkCompleted();
         return;
     }
@@ -1431,7 +1399,7 @@ LocalFrame* FrameLoader::findFrameForNavigation(const AtomicString& name, Docume
     return toLocalFrame(frame);
 }
 
-void FrameLoader::loadHistoryItem(HistoryItem* item, HistoryLoadType historyLoadType, ResourceRequestCachePolicy cachePolicy)
+void FrameLoader::loadHistoryItem(HistoryItem* item, FrameLoadType frameLoadType, HistoryLoadType historyLoadType, ResourceRequestCachePolicy cachePolicy)
 {
     RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get());
     if (m_frame->page()->defersLoading()) {
@@ -1441,7 +1409,7 @@ void FrameLoader::loadHistoryItem(HistoryItem* item, HistoryLoadType historyLoad
 
     m_provisionalItem = item;
     if (historyLoadType == HistorySameDocumentLoad) {
-        loadInSameDocument(item->url(), item->stateObject(), FrameLoadTypeBackForward, NotClientRedirect);
+        loadInSameDocument(item->url(), item->stateObject(), frameLoadType, NotClientRedirect);
         restoreScrollPositionAndViewState();
         return;
     }
@@ -1449,7 +1417,7 @@ void FrameLoader::loadHistoryItem(HistoryItem* item, HistoryLoadType historyLoad
     ResourceRequest request = requestFromHistoryItem(item, cachePolicy);
     request.setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested);
     request.setRequestContext(WebURLRequest::RequestContextInternal);
-    loadWithNavigationAction(NavigationAction(request, FrameLoadTypeBackForward), FrameLoadTypeBackForward, nullptr, SubstituteData(), CheckContentSecurityPolicy);
+    loadWithNavigationAction(NavigationAction(request, frameLoadType), frameLoadType, nullptr, SubstituteData(), CheckContentSecurityPolicy);
 }
 
 void FrameLoader::dispatchDocumentElementAvailable()