Text input is largely broken when there are subframes loading
[WebKit-https.git] / Source / WebCore / loader / FrameLoader.h
index 890f7bc..1ca0696 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "CachePolicy.h"
 #include "FrameLoaderStateMachine.h"
 #include "FrameLoaderTypes.h"
-#include "HistoryController.h"
-#include "IconDatabaseBase.h"
-#include "PolicyChecker.h"
+#include "IconURL.h"
+#include "LayoutMilestones.h"
+#include "MixedContentChecker.h"
+#include "ResourceHandleTypes.h"
 #include "ResourceLoadNotifier.h"
-#include "ScriptValue.h"
+#include "SecurityContext.h"
 #include "SubframeLoader.h"
-#include "ThreadableLoader.h"
 #include "Timer.h"
 #include <wtf/Forward.h>
 #include <wtf/HashSet.h>
 namespace WebCore {
 
 class Archive;
-class AuthenticationChallenge;
 class CachedFrameBase;
 class CachedPage;
 class CachedResource;
 class Chrome;
 class DOMWrapperWorld;
-class Document;
 class DocumentLoader;
 class Event;
-class FormData;
 class FormState;
 class FormSubmission;
-class Frame;
 class FrameLoaderClient;
 class FrameNetworkingContext;
+class HistoryController;
 class HistoryItem;
-class HTMLFormElement;
-class IconLoader;
+class IconController;
 class NavigationAction;
 class NetworkingContext;
 class Page;
-class ProtectionSpace;
+class PolicyChecker;
 class ResourceError;
-class ResourceLoader;
 class ResourceRequest;
 class ResourceResponse;
-class ScriptSourceCode;
-class ScriptValue;
 class SecurityOrigin;
 class SerializedScriptValue;
-class SharedBuffer;
 class StringWithDirection;
 class SubstituteData;
-class TextResourceDecoder;
 
 struct FrameLoadRequest;
 struct WindowFeatures;
@@ -98,47 +90,56 @@ public:
 
     Frame* frame() const { return m_frame; }
 
-    PolicyChecker* policyChecker() const { return &m_policyChecker; }
-    HistoryController* history() const { return &m_history; }
+    PolicyChecker* policyChecker() const { return m_policyChecker.get(); }
+    HistoryController* history() const { return m_history.get(); }
     ResourceLoadNotifier* notifier() const { return &m_notifer; }
     SubframeLoader* subframeLoader() const { return &m_subframeLoader; }
+    IconController* icon() const { return m_icon.get(); }
+    MixedContentChecker* mixedContentChecker() const { return &m_mixedContentChecker; }
 
-    // FIXME: This is not cool, people. There are too many different functions that all start loads.
-    // We should aim to consolidate these into a smaller set of functions, and try to reuse more of
-    // the logic by extracting common code paths.
-
-    void prepareForLoadStart();
+    void prepareForHistoryNavigation();
     void setupForReplace();
-    void setupForReplaceByMIMEType(const String& newMIMEType);
 
+    // FIXME: These are all functions which start loads. We have too many.
     void loadURLIntoChildFrame(const KURL&, const String& referer, Frame*);
-
     void loadFrameRequest(const FrameLoadRequest&, bool lockHistory, bool lockBackForwardList,  // Called by submitForm, calls loadPostRequest and loadURL.
-        PassRefPtr<Event>, PassRefPtr<FormState>, ReferrerPolicy);
+        PassRefPtr<Event>, PassRefPtr<FormState>, ShouldSendReferrer);
 
-    void load(const ResourceRequest&, bool lockHistory);                                        // Called by WebFrame, calls load(ResourceRequest, SubstituteData).
-    void load(const ResourceRequest&, const SubstituteData&, bool lockHistory);                 // Called both by WebFrame and internally, calls load(DocumentLoader*).
-    void load(const ResourceRequest&, const String& frameName, bool lockHistory);               // Called by WebPluginController.
+    void load(const FrameLoadRequest&);
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     void loadArchive(PassRefPtr<Archive>);
 #endif
+    unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ClientCredentialPolicy, ResourceError&, ResourceResponse&, Vector<char>& data);
 
-    static void reportLocalLoadFailed(Frame*, const String& url);
+    void changeLocation(SecurityOrigin*, const KURL&, const String& referrer, bool lockHistory = true, bool lockBackForwardList = true, bool refresh = false);
+    void urlSelected(const KURL&, const String& target, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ShouldSendReferrer);
+    void submitForm(PassRefPtr<FormSubmission>);
+
+    void reload(bool endToEndReload = false);
+    void reloadWithOverrideEncoding(const String& overrideEncoding);
+    void reloadWithOverrideURL(const KURL& overrideUrl, bool endToEndReload = false);
 
-    unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data);
+    void open(CachedFrameBase&);
+    void loadItem(HistoryItem*, FrameLoadType);
+    HistoryItem* requestedHistoryItem() const { return m_requestedHistoryItem.get(); }
 
-    bool canHandleRequest(const ResourceRequest&);
+    void retryAfterFailedCacheOnlyMainResourceLoad();
+
+    static void reportLocalLoadFailed(Frame*, const String& url);
 
-    // Also not cool.
+    // FIXME: These are all functions which stop loads. We have too many.
     void stopAllLoaders(ClearProvisionalItemPolicy = ShouldClearProvisionalItem);
     void stopForUserCancel(bool deferCheckLoadComplete = false);
+    void stop();
+    void stopLoading(UnloadEventPolicy);
+    bool closeURL();
+    void cancelAndClear();
+    // FIXME: clear() is trying to do too many things. We should break it down into smaller functions (ideally with fewer raw Boolean parameters).
+    void clear(Document* newDocument, bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
 
-    bool isLoadingMainResource() const { return m_isLoadingMainResource; }
     bool isLoading() const;
     bool frameHasLoaded() const;
-    void transferLoadingResourcesFromPage(Page*);
-    void dispatchTransferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*);
 
     int numPendingOrLoadingRequests(bool recurse) const;
     String referrer() const;
@@ -152,57 +153,36 @@ public:
     FrameState state() const { return m_state; }
     static double timeOfLastCompletedLoad();
 
-    bool shouldUseCredentialStorage(ResourceLoader*);
-#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
-    bool canAuthenticateAgainstProtectionSpace(ResourceLoader* loader, const ProtectionSpace& protectionSpace);
-#endif
     const ResourceRequest& originalRequest() const;
     const ResourceRequest& initialRequest() const;
-    void receivedMainResourceError(const ResourceError&, bool isComplete);
+    void receivedMainResourceError(const ResourceError&);
 
     bool willLoadMediaElementURL(KURL&);
 
     void handleFallbackContent();
-    bool isStopping() const;
-
-    void finishedLoading();
 
     ResourceError cancelledError(const ResourceRequest&) const;
-    ResourceError fileDoesNotExistError(const ResourceResponse&) const;
-    ResourceError blockedError(const ResourceRequest&) const;
-    ResourceError cannotShowURLError(const ResourceRequest&) const;
-    ResourceError interruptionForPolicyChangeError(const ResourceRequest&) const;
 
     bool isHostedByObjectElement() const;
     bool isLoadingMainFrame() const;
-    bool canShowMIMEType(const String& MIMEType) const;
-    bool representationExistsForURLScheme(const String& URLScheme);
-    String generatedMIMETypeForURLScheme(const String& URLScheme);
-
-    void reload(bool endToEndReload = false);
-    void reloadWithOverrideEncoding(const String& overrideEncoding);
 
-    void didReceiveServerRedirectForProvisionalLoadForFrame();
-    void finishedLoadingDocument(DocumentLoader*);
     bool isReplacing() const;
     void setReplacing();
-    void revertToProvisional(DocumentLoader*);
-    void setMainDocumentError(DocumentLoader*, const ResourceError&);
-    void mainReceivedCompleteError(DocumentLoader*, const ResourceError&);
     bool subframeIsLoading() const;
     void willChangeTitle(DocumentLoader*);
     void didChangeTitle(DocumentLoader*);
-    void didChangeIcons(DocumentLoader*);
+    void didChangeIcons(IconType);
+
+    bool shouldTreatURLAsSrcdocDocument(const KURL&) const;
 
     FrameLoadType loadType() const;
 
     CachePolicy subresourceCachePolicy() const;
 
+    void didLayout(LayoutMilestones);
     void didFirstLayout();
 
-    void didFirstVisuallyNonEmptyLayout();
-
-    void loadedResourceFromMemoryCache(const CachedResource*);
+    void loadedResourceFromMemoryCache(CachedResource*, ResourceRequest& newRequest);
     void tellClientAboutPastMemoryCacheLoads();
 
     void checkLoadComplete();
@@ -212,32 +192,18 @@ public:
     void addExtraFieldsToSubresourceRequest(ResourceRequest&);
     void addExtraFieldsToMainResourceRequest(ResourceRequest&);
     
-    static void addHTTPOriginIfNeeded(ResourceRequest&, String origin);
+    static void addHTTPOriginIfNeeded(ResourceRequest&, const String& origin);
 
     FrameLoaderClient* client() const { return m_client; }
 
     void setDefersLoading(bool);
 
-    void changeLocation(PassRefPtr<SecurityOrigin>, const KURL&, const String& referrer, bool lockHistory = true, bool lockBackForwardList = true, bool refresh = false);
-    void urlSelected(const KURL&, const String& target, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ReferrerPolicy);
-
-    void submitForm(PassRefPtr<FormSubmission>);
-
-    void stop();
-    void stopLoading(UnloadEventPolicy);
-    bool closeURL();
-
     void didExplicitOpen();
 
     // Callbacks from DocumentWriter
     void didBeginDocument(bool dispatchWindowObjectAvailable);
-    void didEndDocument();
-    void willSetEncoding();
 
-    KURL iconURL();
-    void commitIconURLToIconDatabase(const KURL&);
-
-    KURL baseURL() const;
+    void receivedFirstData();
 
     void handledOnloadEvents();
     String userAgent(const KURL&) const;
@@ -246,24 +212,16 @@ public:
     void dispatchDidClearWindowObjectsInAllWorlds();
     void dispatchDocumentElementAvailable();
 
-    void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); }
-
-    bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
-    SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
     // The following sandbox flags will be forced, regardless of changes to
     // the sandbox attribute of any parent frames.
-    void setForcedSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags = flags; m_sandboxFlags |= flags; }
+    void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; }
+    SandboxFlags effectiveSandboxFlags() const;
 
-    // Mixed content related functions.
-    static bool isMixedContent(SecurityOrigin* context, const KURL&);
-    bool checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&);
-    bool checkIfRunInsecureContent(SecurityOrigin* context, const KURL&);
+    bool checkIfFormActionAllowedByCSP(const KURL&) const;
 
     Frame* opener();
     void setOpener(Frame*);
 
-    bool isProcessingUserGesture();
-
     void resetMultipleFormSubmissionProtection();
 
     void checkCallImplicitClose();
@@ -280,101 +238,92 @@ public:
 
     bool isComplete() const;
 
-    KURL completeURL(const String& url);
-
-    void cancelAndClear();
-
     void setTitle(const StringWithDirection&);
-    void setIconURL(const String&);
 
     void commitProvisionalLoad();
-    bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; }
 
     FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
 
-    void startIconLoader();
-    void iconLoadDecisionReceived(IconLoadDecision);
-    void continueIconLoadWithDecision(IconLoadDecision);
-
-    bool shouldAllowNavigation(Frame* targetFrame) const;
-    Frame* findFrameForNavigation(const AtomicString& name);
-
-    void applyUserAgent(ResourceRequest& request);
-
-    bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&);
+    Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument = 0);
 
-    void open(CachedFrameBase&);
+    void applyUserAgent(ResourceRequest&);
 
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-    void hideMediaPlayerProxyPlugin(Widget*);
-    void showMediaPlayerProxyPlugin(Widget*);
-#endif
+    bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&, unsigned long requestIdentifier);
 
-    // FIXME: Should these really be public?
     void completed();
     bool allAncestorsAreComplete() const; // including this
-    bool allChildrenAreComplete() const; // immediate children, not all descendants
     void clientRedirected(const KURL&, double delay, double fireDate, bool lockBackForwardList);
     void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress);
-    void loadItem(HistoryItem*, FrameLoadType);
 
     // FIXME: This is public because this asynchronous callback from the FrameLoaderClient
     // uses the policy machinery (and therefore is called via the PolicyChecker).  Once we
     // introduce a proper callback type for this function, we should make it private again.
     void continueLoadAfterWillSubmitForm();
-    
+
+    void setOriginalURLForDownloadRequest(ResourceRequest&);
+
     bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; }
 
     static ObjectContentType defaultObjectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages);
 
-    void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
-
     bool quickRedirectComing() const { return m_quickRedirectComing; }
 
     bool shouldClose();
     
     void started();
 
-    bool pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
+    enum PageDismissalType {
+        NoDismissal = 0,
+        BeforeUnloadDismissal = 1,
+        PageHideDismissal = 2,
+        UnloadDismissal = 3
+    };
+    PageDismissalType pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
 
     NetworkingContext* networkingContext() const;
 
+    void loadProgressingStatusChanged();
+
+    const KURL& previousURL() const { return m_previousURL; }
+
 private:
+    enum FormSubmissionCacheLoadPolicy {
+        MayAttemptCacheOnlyLoadForFormSubmissionItem,
+        MayNotAttemptCacheOnlyLoadForFormSubmissionItem
+    };
+
+    bool allChildrenAreComplete() const; // immediate children, not all descendants
+
     void checkTimerFired(Timer<FrameLoader>*);
     
     void loadSameDocumentItem(HistoryItem*);
-    void loadDifferentDocumentItem(HistoryItem*, FrameLoadType);
+    void loadDifferentDocumentItem(HistoryItem*, FrameLoadType, FormSubmissionCacheLoadPolicy);
     
     void loadProvisionalItemFromCachedPage();
 
-    void receivedFirstData();
-
     void updateFirstPartyForCookies();
     void setFirstPartyForCookies(const KURL&);
     
-    void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType loadType, bool isMainResource, bool cookiePolicyURLFromRequest);
-
-    // Also not cool.
-    void stopLoadingSubframes(ClearProvisionalItemPolicy);
+    void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
 
     void clearProvisionalLoad();
-    void markLoadComplete();
     void transitionToCommitted(PassRefPtr<CachedPage>);
     void frameLoadCompleted();
 
-    void mainReceivedError(const ResourceError&, bool isComplete);
+    SubstituteData defaultSubstituteDataForURL(const KURL&);
 
     static void callContinueLoadAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
     static void callContinueLoadAfterNewWindowPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
     static void callContinueFragmentScrollAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
     
-    bool fireBeforeUnloadEvent(Chrome*);
+    bool fireBeforeUnloadEvent(Chrome&);
 
     void continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
     void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
     void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
 
-    bool shouldScrollToAnchor(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
+    bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
+    void scrollToFragmentWithParentBoundary(const KURL&);
 
     void checkLoadCompleteForThisFrame();
 
@@ -391,7 +340,7 @@ private:
 
     void dispatchDidCommitLoad();
 
-    void urlSelected(const FrameLoadRequest&, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ReferrerPolicy, ShouldReplaceDocumentIfJavaScriptURL);
+    void urlSelected(const FrameLoadRequest&, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ShouldSendReferrer, ShouldReplaceDocumentIfJavaScriptURL);
 
     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>); // Calls continueLoadAfterNavigationPolicy
     void load(DocumentLoader*);                                                         // Calls loadWithDocumentLoader   
@@ -404,39 +353,47 @@ private:
     void loadURL(const KURL&, const String& referrer, const String& frameName,          // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate
         bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>);                                                         
 
+    void reloadWithRequest(const ResourceRequest&, bool endToEndReload);
+
     bool shouldReload(const KURL& currentURL, const KURL& destinationURL);
 
     void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
 
-    void recursiveCheckLoadComplete();
-
     void detachChildren();
     void closeAndRemoveChild(Frame*);
 
-    void loadInSameDocument(const KURL&, SerializedScriptValue* stateObject, bool isNewNavigation);
+    void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation);
 
+    void prepareForLoadStart();
     void provisionalLoadStarted();
 
-    bool didOpenURL(const KURL&);
+    void willTransitionToCommitted();
+    bool didOpenURL();
 
     void scheduleCheckCompleted();
     void scheduleCheckLoadComplete();
     void startCheckCompleteTimer();
 
-    KURL originalRequestURL() const;
-
     bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
 
-    void updateSandboxFlags();
+    void dispatchGlobalObjectAvailableInAllWorlds();
 
     Frame* m_frame;
     FrameLoaderClient* m_client;
 
-    mutable PolicyChecker m_policyChecker;
-    mutable HistoryController m_history;
+    // FIXME: These should be OwnPtr<T> to reduce build times and simplify
+    // header dependencies unless performance testing proves otherwise.
+    // Some of these could be lazily created for memory savings on devices.
+    OwnPtr<PolicyChecker> m_policyChecker;
+    OwnPtr<HistoryController> m_history;
     mutable ResourceLoadNotifier m_notifer;
     mutable SubframeLoader m_subframeLoader;
     mutable FrameLoaderStateMachine m_stateMachine;
+    OwnPtr<IconController> m_icon;
+    mutable MixedContentChecker m_mixedContentChecker;
+
+    class FrameProgressTracker;
+    OwnPtr<FrameProgressTracker> m_progressTracker;
 
     FrameState m_state;
     FrameLoadType m_loadType;
@@ -461,17 +418,11 @@ private:
 
     bool m_didCallImplicitClose;
     bool m_wasUnloadEventEmitted;
-    bool m_pageDismissalEventBeingDispatched;
+    PageDismissalType m_pageDismissalEventBeingDispatched;
     bool m_isComplete;
-    bool m_isLoadingMainResource;
 
     RefPtr<SerializedScriptValue> m_pendingStateObject;
 
-    KURL m_workingURL;
-
-    OwnPtr<IconLoader> m_iconLoader;
-    bool m_mayLoadIconLater;
-
     bool m_needsClear;
 
     KURL m_submittedFormURL;
@@ -487,12 +438,12 @@ private:
     bool m_loadingFromCachedPage;
     bool m_suppressOpenerInNewFrame;
 
-    SandboxFlags m_sandboxFlags;
     SandboxFlags m_forcedSandboxFlags;
 
     RefPtr<FrameNetworkingContext> m_networkingContext;
 
-    KURL m_previousUrl;
+    KURL m_previousURL;
+    RefPtr<HistoryItem> m_requestedHistoryItem;
 };
 
 // This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for
@@ -502,7 +453,7 @@ private:
 //
 // FIXME: Consider making this function part of an appropriate class (not FrameLoader)
 // and moving it to a more appropriate location.
-Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
+PassRefPtr<Frame> createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
 
 } // namespace WebCore