1/*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4 * Copyright (C) Research In Motion Limited 2009. All rights reserved.
5 * Copyright (C) 2011 Google Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1.  Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 * 2.  Redistributions in binary form must reproduce the above copyright
14 *     notice, this list of conditions and the following disclaimer in the
15 *     documentation and/or other materials provided with the distribution.
16 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
17 *     its contributors may be used to endorse or promote products derived
18 *     from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef FrameLoader_h
33#define FrameLoader_h
34
35#include "CachePolicy.h"
36#include "FrameLoaderStateMachine.h"
37#include "FrameLoaderTypes.h"
38#include "IconURL.h"
39#include "LayoutMilestones.h"
40#include "MixedContentChecker.h"
41#include "ResourceHandleTypes.h"
42#include "ResourceLoadNotifier.h"
43#include "SecurityContext.h"
44#include "SubframeLoader.h"
45#include "Timer.h"
46#include <wtf/Forward.h>
47#include <wtf/HashSet.h>
48
49namespace WebCore {
50
51class Archive;
52class CachedFrameBase;
53class CachedPage;
54class CachedResource;
55class Chrome;
56class DOMWrapperWorld;
57class DocumentLoader;
58class Event;
59class FormState;
60class FormSubmission;
61class FrameLoaderClient;
62class FrameNetworkingContext;
63class HistoryController;
64class HistoryItem;
65class IconController;
66class NavigationAction;
67class NetworkingContext;
68class Page;
69class PageActivityAssertionToken;
70class PolicyChecker;
71class ResourceError;
72class ResourceRequest;
73class ResourceResponse;
74class SecurityOrigin;
75class SerializedScriptValue;
76class StringWithDirection;
77class SubstituteData;
78
79struct FrameLoadRequest;
80struct WindowFeatures;
81
82bool isBackForwardLoadType(FrameLoadType);
83
84class FrameLoader {
85    WTF_MAKE_NONCOPYABLE(FrameLoader);
86public:
87    FrameLoader(Frame*, FrameLoaderClient*);
88    ~FrameLoader();
89
90    void init();
91
92    Frame* frame() const { return m_frame; }
93
94    PolicyChecker* policyChecker() const { return m_policyChecker.get(); }
95    HistoryController* history() const { return m_history.get(); }
96    ResourceLoadNotifier* notifier() const { return &m_notifer; }
97    SubframeLoader* subframeLoader() const { return &m_subframeLoader; }
98    IconController* icon() const { return m_icon.get(); }
99    MixedContentChecker* mixedContentChecker() const { return &m_mixedContentChecker; }
100
101    void prepareForHistoryNavigation();
102    void setupForReplace();
103
104    // FIXME: These are all functions which start loads. We have too many.
105    void loadURLIntoChildFrame(const KURL&, const String& referer, Frame*);
106    void loadFrameRequest(const FrameLoadRequest&, bool lockHistory, bool lockBackForwardList,  // Called by submitForm, calls loadPostRequest and loadURL.
107        PassRefPtr<Event>, PassRefPtr<FormState>, ShouldSendReferrer);
108
109    void load(const FrameLoadRequest&);
110
111#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
112    void loadArchive(PassRefPtr<Archive>);
113#endif
114    unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ClientCredentialPolicy, ResourceError&, ResourceResponse&, Vector<char>& data);
115
116    void changeLocation(SecurityOrigin*, const KURL&, const String& referrer, bool lockHistory = true, bool lockBackForwardList = true, bool refresh = false);
117    void urlSelected(const KURL&, const String& target, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ShouldSendReferrer);
118    void submitForm(PassRefPtr<FormSubmission>);
119
120    void reload(bool endToEndReload = false);
121    void reloadWithOverrideEncoding(const String& overrideEncoding);
122    void reloadWithOverrideURL(const KURL& overrideUrl, bool endToEndReload = false);
123
124    void open(CachedFrameBase&);
125    void loadItem(HistoryItem*, FrameLoadType);
126    HistoryItem* requestedHistoryItem() const { return m_requestedHistoryItem.get(); }
127
128    void retryAfterFailedCacheOnlyMainResourceLoad();
129
130    static void reportLocalLoadFailed(Frame*, const String& url);
131
132    // FIXME: These are all functions which stop loads. We have too many.
133    void stopAllLoaders(ClearProvisionalItemPolicy = ShouldClearProvisionalItem);
134    void stopForUserCancel(bool deferCheckLoadComplete = false);
135    void stop();
136    void stopLoading(UnloadEventPolicy);
137    bool closeURL();
138    void cancelAndClear();
139    // FIXME: clear() is trying to do too many things. We should break it down into smaller functions (ideally with fewer raw Boolean parameters).
140    void clear(Document* newDocument, bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
141
142    bool isLoading() const;
143    bool frameHasLoaded() const;
144
145    int numPendingOrLoadingRequests(bool recurse) const;
146    String referrer() const;
147    String outgoingReferrer() const;
148    String outgoingOrigin() const;
149
150    DocumentLoader* activeDocumentLoader() const;
151    DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
152    DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
153    DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
154    FrameState state() const { return m_state; }
155    static double timeOfLastCompletedLoad();
156
157    const ResourceRequest& originalRequest() const;
158    const ResourceRequest& initialRequest() const;
159    void receivedMainResourceError(const ResourceError&);
160
161    bool willLoadMediaElementURL(KURL&);
162
163    void handleFallbackContent();
164
165    ResourceError cancelledError(const ResourceRequest&) const;
166
167    bool isHostedByObjectElement() const;
168    bool isLoadingMainFrame() const;
169
170    bool isReplacing() const;
171    void setReplacing();
172    bool subframeIsLoading() const;
173    void willChangeTitle(DocumentLoader*);
174    void didChangeTitle(DocumentLoader*);
175    void didChangeIcons(IconType);
176
177    bool shouldTreatURLAsSrcdocDocument(const KURL&) const;
178
179    FrameLoadType loadType() const;
180
181    CachePolicy subresourceCachePolicy() const;
182
183    void didLayout(LayoutMilestones);
184    void didFirstLayout();
185
186    void loadedResourceFromMemoryCache(CachedResource*, ResourceRequest& newRequest);
187    void tellClientAboutPastMemoryCacheLoads();
188
189    void checkLoadComplete();
190    void detachFromParent();
191    void detachViewsAndDocumentLoader();
192
193    void addExtraFieldsToSubresourceRequest(ResourceRequest&);
194    void addExtraFieldsToMainResourceRequest(ResourceRequest&);
195
196    static void addHTTPOriginIfNeeded(ResourceRequest&, const String& origin);
197
198    FrameLoaderClient* client() const { return m_client; }
199
200    void setDefersLoading(bool);
201
202    void didExplicitOpen();
203
204    // Callbacks from DocumentWriter
205    void didBeginDocument(bool dispatchWindowObjectAvailable);
206
207    void receivedFirstData();
208
209    void handledOnloadEvents();
210    String userAgent(const KURL&) const;
211
212    void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*);
213    void dispatchDidClearWindowObjectsInAllWorlds();
214    void dispatchDocumentElementAvailable();
215
216    // The following sandbox flags will be forced, regardless of changes to
217    // the sandbox attribute of any parent frames.
218    void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; }
219    SandboxFlags effectiveSandboxFlags() const;
220
221    bool checkIfFormActionAllowedByCSP(const KURL&) const;
222
223    Frame* opener();
224    void setOpener(Frame*);
225
226    void resetMultipleFormSubmissionProtection();
227
228    void checkCallImplicitClose();
229
230    void frameDetached();
231
232    void setOutgoingReferrer(const KURL&);
233
234    void loadDone();
235    void finishedParsing();
236    void checkCompleted();
237
238    void checkDidPerformFirstNavigation();
239
240    bool isComplete() const;
241
242    void setTitle(const StringWithDirection&);
243
244    void commitProvisionalLoad();
245
246    FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
247
248    Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument = 0);
249
250    void applyUserAgent(ResourceRequest&);
251
252    bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&, unsigned long requestIdentifier);
253
254    void completed();
255    bool allAncestorsAreComplete() const; // including this
256    void clientRedirected(const KURL&, double delay, double fireDate, bool lockBackForwardList);
257    void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress);
258
259    // FIXME: This is public because this asynchronous callback from the FrameLoaderClient
260    // uses the policy machinery (and therefore is called via the PolicyChecker).  Once we
261    // introduce a proper callback type for this function, we should make it private again.
262    void continueLoadAfterWillSubmitForm();
263
264    void setOriginalURLForDownloadRequest(ResourceRequest&);
265
266    bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; }
267
268    static ObjectContentType defaultObjectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages);
269
270    bool quickRedirectComing() const { return m_quickRedirectComing; }
271
272    bool shouldClose();
273
274    void started();
275
276    enum PageDismissalType {
277        NoDismissal = 0,
278        BeforeUnloadDismissal = 1,
279        PageHideDismissal = 2,
280        UnloadDismissal = 3
281    };
282    PageDismissalType pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
283
284    NetworkingContext* networkingContext() const;
285
286    void loadProgressingStatusChanged();
287
288    const KURL& previousURL() const { return m_previousURL; }
289
290    void forcePageTransitionIfNeeded();
291
292private:
293    enum FormSubmissionCacheLoadPolicy {
294        MayAttemptCacheOnlyLoadForFormSubmissionItem,
295        MayNotAttemptCacheOnlyLoadForFormSubmissionItem
296    };
297
298    bool allChildrenAreComplete() const; // immediate children, not all descendants
299
300    void checkTimerFired(Timer<FrameLoader>*);
301
302    void loadSameDocumentItem(HistoryItem*);
303    void loadDifferentDocumentItem(HistoryItem*, FrameLoadType, FormSubmissionCacheLoadPolicy);
304
305    void loadProvisionalItemFromCachedPage();
306
307    void updateFirstPartyForCookies();
308    void setFirstPartyForCookies(const KURL&);
309
310    void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
311
312    void clearProvisionalLoad();
313    void transitionToCommitted(PassRefPtr<CachedPage>);
314    void frameLoadCompleted();
315
316    SubstituteData defaultSubstituteDataForURL(const KURL&);
317
318    static void callContinueLoadAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
319    static void callContinueLoadAfterNewWindowPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
320    static void callContinueFragmentScrollAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
321
322    bool handleBeforeUnloadEvent(Chrome&, FrameLoader* frameLoaderBeingNavigated);
323
324    void continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
325    void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
326    void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
327
328    bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
329    void scrollToFragmentWithParentBoundary(const KURL&);
330
331    void checkLoadCompleteForThisFrame();
332
333    void setDocumentLoader(DocumentLoader*);
334    void setPolicyDocumentLoader(DocumentLoader*);
335    void setProvisionalDocumentLoader(DocumentLoader*);
336
337    void setState(FrameState);
338
339    void closeOldDataSources();
340    void prepareForCachedPageRestore();
341
342    bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
343
344    void dispatchDidCommitLoad();
345
346    void urlSelected(const FrameLoadRequest&, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ShouldSendReferrer, ShouldReplaceDocumentIfJavaScriptURL);
347
348    void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>); // Calls continueLoadAfterNavigationPolicy
349    void load(DocumentLoader*);                                                         // Calls loadWithDocumentLoader
350
351    void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&,      // Calls loadWithDocumentLoader
352        bool lockHistory, FrameLoadType, PassRefPtr<FormState>);
353
354    void loadPostRequest(const ResourceRequest&, const String& referrer,                // Called by loadFrameRequest, calls loadWithNavigationAction
355        const String& frameName, bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>);
356    void loadURL(const KURL&, const String& referrer, const String& frameName,          // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate
357        bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>);
358
359    void reloadWithRequest(const ResourceRequest&, bool endToEndReload);
360
361    bool shouldReload(const KURL& currentURL, const KURL& destinationURL);
362
363    void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
364
365    void detachChildren();
366    void closeAndRemoveChild(Frame*);
367
368    void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation);
369
370    void prepareForLoadStart();
371    void provisionalLoadStarted();
372
373    void willTransitionToCommitted();
374    bool didOpenURL();
375
376    void scheduleCheckCompleted();
377    void scheduleCheckLoadComplete();
378    void startCheckCompleteTimer();
379
380    bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
381
382    void dispatchGlobalObjectAvailableInAllWorlds();
383
384    Frame* m_frame;
385    FrameLoaderClient* m_client;
386
387    // FIXME: These should be OwnPtr<T> to reduce build times and simplify
388    // header dependencies unless performance testing proves otherwise.
389    // Some of these could be lazily created for memory savings on devices.
390    OwnPtr<PolicyChecker> m_policyChecker;
391    OwnPtr<HistoryController> m_history;
392    mutable ResourceLoadNotifier m_notifer;
393    mutable SubframeLoader m_subframeLoader;
394    mutable FrameLoaderStateMachine m_stateMachine;
395    OwnPtr<IconController> m_icon;
396    mutable MixedContentChecker m_mixedContentChecker;
397
398    class FrameProgressTracker;
399    OwnPtr<FrameProgressTracker> m_progressTracker;
400
401    FrameState m_state;
402    FrameLoadType m_loadType;
403
404    // Document loaders for the three phases of frame loading. Note that while
405    // a new request is being loaded, the old document loader may still be referenced.
406    // E.g. while a new request is in the "policy" state, the old document loader may
407    // be consulted in particular as it makes sense to imply certain settings on the new loader.
408    RefPtr<DocumentLoader> m_documentLoader;
409    RefPtr<DocumentLoader> m_provisionalDocumentLoader;
410    RefPtr<DocumentLoader> m_policyDocumentLoader;
411
412    bool m_delegateIsHandlingProvisionalLoadError;
413
414    bool m_quickRedirectComing;
415    bool m_sentRedirectNotification;
416    bool m_inStopAllLoaders;
417
418    String m_outgoingReferrer;
419
420    bool m_isExecutingJavaScriptFormAction;
421
422    bool m_didCallImplicitClose;
423    bool m_wasUnloadEventEmitted;
424    PageDismissalType m_pageDismissalEventBeingDispatched;
425    bool m_isComplete;
426
427    RefPtr<SerializedScriptValue> m_pendingStateObject;
428
429    bool m_needsClear;
430
431    KURL m_submittedFormURL;
432
433    Timer<FrameLoader> m_checkTimer;
434    bool m_shouldCallCheckCompleted;
435    bool m_shouldCallCheckLoadComplete;
436
437    Frame* m_opener;
438    HashSet<Frame*> m_openedFrames;
439
440    bool m_didPerformFirstNavigation;
441    bool m_loadingFromCachedPage;
442    bool m_suppressOpenerInNewFrame;
443
444    bool m_currentNavigationHasShownBeforeUnloadConfirmPanel;
445
446    SandboxFlags m_forcedSandboxFlags;
447
448    RefPtr<FrameNetworkingContext> m_networkingContext;
449
450    KURL m_previousURL;
451    RefPtr<HistoryItem> m_requestedHistoryItem;
452    OwnPtr<PageActivityAssertionToken> m_activityAssertion;
453};
454
455// This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for
456// modal dialog creation.  The lookupFrame is for looking up the frame name in case
457// the frame name references a frame different from the openerFrame, e.g. when it is
458// "_self" or "_parent".
459//
460// FIXME: Consider making this function part of an appropriate class (not FrameLoader)
461// and moving it to a more appropriate location.
462PassRefPtr<Frame> createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
463
464} // namespace WebCore
465
466#endif // FrameLoader_h
467