blob: df3f57abc40f7ba35fbe8e797466d207bd8ee74a [file] [log] [blame]
/*
* 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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_
#include "base/macros.h"
#include "third_party/blink/public/platform/web_scoped_virtual_time_pauser.h"
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_navigation_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/frame_types.h"
#include "third_party/blink/renderer/core/frame/sandbox_flags.h"
#include "third_party/blink/renderer/core/loader/frame_loader_state_machine.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/core/loader/history_item.h"
#include "third_party/blink/renderer/core/loader/navigation_policy.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include <memory>
namespace blink {
class Document;
class DocumentLoader;
class ExecutionContext;
class LocalFrame;
class Frame;
class LocalFrameClient;
class ProgressTracker;
class ResourceError;
class ResourceRequest;
class SerializedScriptValue;
class TracedValue;
struct FrameLoadRequest;
struct WebNavigationInfo;
struct WebNavigationParams;
namespace mojom {
enum class CommitResult : int32_t;
}
CORE_EXPORT bool IsBackForwardLoadType(WebFrameLoadType);
CORE_EXPORT bool IsReloadLoadType(WebFrameLoadType);
class CORE_EXPORT FrameLoader final {
DISALLOW_NEW();
public:
explicit FrameLoader(LocalFrame*);
~FrameLoader();
void Init();
ResourceRequest ResourceRequestForReload(
WebFrameLoadType,
ClientRedirectPolicy = ClientRedirectPolicy::kNotClientRedirect);
ProgressTracker& Progress() const { return *progress_tracker_; }
// Starts a navigation. It will eventually send the navigation to the
// browser process, or call LoadInSameDocument for same-document navigation.
// For reloads, an appropriate WebFrameLoadType should be given. Otherwise,
// kStandard should be used (and the final WebFrameLoadType
// will be computed).
void StartNavigation(const FrameLoadRequest&,
WebFrameLoadType = WebFrameLoadType::kStandard,
NavigationPolicy = kNavigationPolicyCurrentTab);
// Called when the browser process has asked this renderer process to commit
// a navigation in this frame. This method skips most of the checks assuming
// that browser process has already performed any checks necessary.
// See WebNavigationParams for details.
void CommitNavigation(
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data);
// Called when the browser process has asked this renderer process to commit a
// same document navigation in that frame. Returns false if the navigation
// cannot commit, true otherwise.
mojom::CommitResult CommitSameDocumentNavigation(
const KURL&,
WebFrameLoadType,
HistoryItem*,
ClientRedirectPolicy,
Document* origin_document,
bool has_event,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data = nullptr);
// Called when the browser process is handling the navigation, to
// create a "placeholder" document loader and mark the frame as loading.
// This placeholder document loader will be later abandoned, and only
// lives temporarily so that the rest of Blink code knows the navigation
// is in place.
bool CreatePlaceholderDocumentLoader(
const WebNavigationInfo&,
std::unique_ptr<WebDocumentLoader::ExtraData>);
// This runs the "stop document loading" algorithm in HTML:
// https://html.spec.whatwg.org/C/browsing-the-web.html#stop-document-loading
// Note, this function only cancels ongoing navigation handled through
// FrameLoader. You might also want to call
// LocalFrameClient::AbortClientNavigation() if appropriate.
//
// Warning: StopAllLoaders() may detach the LocalFrame to which this
// FrameLoader belongs. Callers need to be careful about checking the
// existence of the frame after StopAllLoaders() returns.
void StopAllLoaders();
void ReplaceDocumentWhileExecutingJavaScriptURL(const String& source,
Document* owner_document);
// Notifies the client that the initial empty document has been accessed, and
// thus it is no longer safe to show a provisional URL above the document
// without risking a URL spoof. The client must not call back into JavaScript.
void DidAccessInitialDocument();
DocumentLoader* GetDocumentLoader() const { return document_loader_.Get(); }
DocumentLoader* GetProvisionalDocumentLoader() const {
return provisional_document_loader_.Get();
}
void LoadFailed(DocumentLoader*, const ResourceError&);
bool IsLoadingMainFrame() const;
bool ShouldTreatURLAsSameAsCurrent(const KURL&) const;
bool ShouldTreatURLAsSrcdocDocument(const KURL&) const;
void SetDefersLoading(bool);
void DidExplicitOpen();
String UserAgent() const;
void DispatchDidClearWindowObjectInMainWorld();
void DispatchDidClearDocumentOfWindowObject();
void DispatchDocumentElementAvailable();
void RunScriptsAtDocumentElementAvailable();
// The following sandbox flags will be forced, regardless of changes to the
// sandbox attribute of any parent frames.
void ForceSandboxFlags(SandboxFlags flags) { forced_sandbox_flags_ |= flags; }
SandboxFlags EffectiveSandboxFlags() const;
void ModifyRequestForCSP(ResourceRequest&, Document*) const;
Frame* Opener();
void SetOpener(LocalFrame*);
const AtomicString& RequiredCSP() const { return required_csp_; }
void RecordLatestRequiredCSP();
void Detach();
void FinishedParsing();
void DidFinishNavigation();
// This prepares the FrameLoader for the next commit. It will dispatch unload
// events, abort XHR requests and detach the document. Returns true if the
// frame is ready to receive the next commit, or false otherwise.
bool PrepareForCommit();
void CommitProvisionalLoad();
FrameLoaderStateMachine* StateMachine() const { return &state_machine_; }
bool AllAncestorsAreComplete() const; // including this
bool ShouldClose(bool is_reload = false);
void DispatchUnloadEvent();
bool AllowPlugins(ReasonForCallingAllowPlugins);
void UpdateForSameDocumentNavigation(const KURL&,
SameDocumentNavigationSource,
scoped_refptr<SerializedScriptValue>,
HistoryScrollRestorationType,
WebFrameLoadType,
Document*);
bool ShouldSerializeScrollAnchor();
void SaveScrollAnchor();
void SaveScrollState();
void RestoreScrollPositionAndViewState();
// Note: When a PlzNavigtate navigation is handled by the client, we will
// have created a dummy provisional DocumentLoader, so this will return true
// while the client handles the navigation.
bool HasProvisionalNavigation() const {
return GetProvisionalDocumentLoader();
}
void DetachProvisionalDocumentLoader(DocumentLoader*);
void Trace(blink::Visitor*);
static void SetReferrerForFrameRequest(FrameLoadRequest&);
static void UpgradeInsecureRequest(ResourceRequest&, ExecutionContext*);
void ClientDroppedNavigation();
void MarkAsLoading();
ContentSecurityPolicy* GetLastOriginDocumentCSP() {
return last_origin_document_csp_.Get();
}
private:
bool PrepareRequestForThisFrame(FrameLoadRequest&);
WebFrameLoadType DetermineFrameLoadType(const KURL& url,
const AtomicString& http_method,
Document* origin_document,
const KURL& failing_url,
WebFrameLoadType);
bool ShouldPerformFragmentNavigation(bool is_form_submission,
const String& http_method,
WebFrameLoadType,
const KURL&);
void ProcessFragment(const KURL&, WebFrameLoadType, LoadStartType);
// Returns whether we should continue with new navigation.
bool CancelProvisionalLoaderForNewNavigation(
bool cancel_scheduled_navigations);
void ClearInitialScrollState();
void LoadInSameDocument(const KURL&,
scoped_refptr<SerializedScriptValue> state_object,
WebFrameLoadType,
HistoryItem*,
ClientRedirectPolicy,
Document*,
std::unique_ptr<WebDocumentLoader::ExtraData>);
void RestoreScrollPositionAndViewState(WebFrameLoadType,
bool is_same_document,
HistoryItem::ViewState*,
HistoryScrollRestorationType);
void ScheduleCheckCompleted();
void DetachDocumentLoader(Member<DocumentLoader>&,
bool flush_microtask_queue = false);
std::unique_ptr<TracedValue> ToTracedValue() const;
void TakeObjectSnapshot() const;
DocumentLoader* CreateDocumentLoader(
WebNavigationType,
std::unique_ptr<WebNavigationParams>,
std::unique_ptr<WebDocumentLoader::ExtraData>);
LocalFrameClient* Client() const;
Member<LocalFrame> frame_;
AtomicString required_csp_;
// FIXME: These should be std::unique_ptr<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.
mutable FrameLoaderStateMachine state_machine_;
Member<ProgressTracker> progress_tracker_;
// Document loaders for the three phases of frame loading. Note that while a
// new request is being loaded, the old document loader may still be
// referenced. E.g. while a new request is in the "policy" state, the old
// document loader may be consulted in particular as it makes sense to imply
// certain settings on the new loader.
Member<DocumentLoader> document_loader_;
Member<DocumentLoader> provisional_document_loader_;
bool in_stop_all_loaders_;
bool in_restore_scroll_;
SandboxFlags forced_sandbox_flags_;
bool dispatching_did_clear_window_object_in_main_world_;
bool protect_provisional_loader_;
bool detached_;
WebScopedVirtualTimePauser virtual_time_pauser_;
Member<ContentSecurityPolicy> last_origin_document_csp_;
DISALLOW_COPY_AND_ASSIGN(FrameLoader);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_