blob: 4996e6b4b7c88a05d2b7f19a81f50d909744733b [file] [log] [blame]
* Copyright (C) 1999 Lars Knoll (
* (C) 1999 Antti Koivisto (
* (C) 2001 Dirk Mueller (
* (C) 2006 Alexey Proskuryakov (
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All
* rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
* (
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2011 Google Inc. All rights reserved.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* Library General Public License for more details.
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
#include <bitset>
#include <string>
#include <utility>
#include "base/memory/scoped_refptr.h"
#include "base/timer/elapsed_timer.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/platform/web_focus_type.h"
#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/renderer/core/accessibility/axid.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/container_node.h"
#include "third_party/blink/renderer/core/dom/create_element_flags.h"
#include "third_party/blink/renderer/core/dom/document_encoding_data.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/dom/document_shutdown_notifier.h"
#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
#include "third_party/blink/renderer/core/dom/document_timing.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/dom/live_node_list_registry.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
#include "third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h"
#include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
#include "third_party/blink/renderer/core/dom/text_link_colors.h"
#include "third_party/blink/renderer/core/dom/tree_scope.h"
#include "third_party/blink/renderer/core/dom/user_action_element_set.h"
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element.h"
#include "third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace base {
class SingleThreadTaskRunner;
namespace ukm {
class UkmRecorder;
} // namespace ukm
namespace blink {
class AnimationClock;
class AXContext;
class AXObjectCache;
class Attr;
class BeforeUnloadEventListener;
class CDATASection;
class CSSStyleSheet;
class CanvasFontCache;
class ChromeClient;
class Comment;
class ComputedAccessibleNode;
class WindowAgent;
class WindowAgentFactory;
class ComputedStyle;
class ConsoleMessage;
class ContextFeatures;
class CookieJar;
class V0CustomElementMicrotaskRunQueue;
class V0CustomElementRegistrationContext;
class DOMImplementation;
class DOMWindow;
class DocumentFragment;
class DocumentInit;
class DocumentLoader;
class DocumentMarkerController;
class DocumentNameCollection;
class DocumentOutliveTimeReporter;
class DocumentParser;
class DocumentResourceCoordinator;
class DocumentState;
class DocumentTimeline;
class DocumentType;
class DOMFeaturePolicy;
class DoubleSize;
class Element;
class ElementDataCache;
class ElementRegistrationOptions;
class Event;
class EventFactoryBase;
class EventListener;
template <typename EventType>
class EventWithHitTestResults;
class FloatQuad;
class FloatRect;
class FontMatchingMetrics;
class FormController;
class HTMLAllCollection;
class HTMLBodyElement;
class HTMLCollection;
class HTMLDialogElement;
class HTMLElement;
class HTMLFrameOwnerElement;
class HTMLHeadElement;
class HTMLImportLoader;
class HTMLImportsController;
class HTMLLinkElement;
class HTMLScriptElementOrSVGScriptElement;
class HitTestRequest;
class HttpRefreshScheduler;
class IdleRequestOptions;
class IntersectionObserver;
class IntersectionObserverController;
class IntersectionObserverEntry;
class LayoutView;
class LazyLoadImageObserver;
class LiveNodeListBase;
class LocalDOMWindow;
class Locale;
class LocalFrame;
class LocalFrameView;
class Location;
class MediaQueryListListener;
class MediaQueryMatcher;
class NavigationInitiatorImpl;
class NodeIterator;
class NthIndexCache;
class OriginAccessEntry;
class Page;
class PendingAnimations;
class ProcessingInstruction;
class PropertyRegistry;
class QualifiedName;
class Range;
class ResizeObserverController;
class ResourceFetcher;
class RootScrollerController;
class ScriptValue;
class SVGDocumentExtensions;
class SVGUseElement;
class Text;
class TrustedHTML;
class ScriptElementBase;
class ScriptPromise;
class ScriptRunner;
class ScriptableDocumentParser;
class ScriptedAnimationController;
class SecurityOrigin;
class SelectorQueryCache;
class SerializedScriptValue;
class Settings;
class SlotAssignmentEngine;
class SnapCoordinator;
class StringOrElementCreationOptions;
class StyleEngine;
class StyleResolver;
class StylePropertyMapReadOnly;
class StyleSheetList;
class TextAutosizer;
class TransformSource;
class TreeWalker;
class V8NodeFilter;
class ViewportData;
class VisitedLinkState;
class WebComputedAXTree;
class WebMouseEvent;
class WorkletAnimationController;
enum ContentSecurityPolicyDisposition : uint8_t;
enum class CSSPropertyID;
enum class ScrollbarMode;
struct AnnotatedRegionValue;
struct FocusParams;
struct IconURL;
struct PhysicalOffset;
using MouseEventWithHitTestResults = EventWithHitTestResults<WebMouseEvent>;
enum NodeListInvalidationType : int {
kDoNotInvalidateOnAttributeChanges = 0,
const int kNumNodeListInvalidationTypes = kInvalidateOnAnyAttrChange + 1;
enum DocumentClass {
kDefaultDocumentClass = 0,
kHTMLDocumentClass = 1,
kXHTMLDocumentClass = 1 << 1,
kImageDocumentClass = 1 << 2,
kPluginDocumentClass = 1 << 3,
kMediaDocumentClass = 1 << 4,
kSVGDocumentClass = 1 << 5,
kXMLDocumentClass = 1 << 6,
kViewSourceDocumentClass = 1 << 7,
enum ShadowCascadeOrder {
enum class SecureContextState { kUnknown, kNonSecure, kSecure };
using DocumentClassFlags = unsigned char;
// A map of IDL attribute name to Element value, for one particular element.
// For example,
// el1.ariaActiveDescendant = el2
// would add the following pair to the ExplicitlySetAttrElementMap for el1:
// ("ariaActiveDescendant", el2)
// This represents 'explicitly set attr-element' in the HTML specification.
// Note that in the interest of simplicitly, attributes that reflect a single
// element reference are implemented using the same ExplicitlySetAttrElementsMap
// storage, but only store a single element vector which is DCHECKED at the
// calling site.
using ExplicitlySetAttrElementsMap =
HeapHashMap<QualifiedName, Member<HeapVector<Member<Element>>>>;
// A document ( is the root node
// of a tree of DOM nodes, generally resulting from the parsing of an markup
// (typically, HTML) resource. It provides both the content to be displayed to
// the user in a frame and an execution context for JavaScript code.
class CORE_EXPORT Document : public ContainerNode,
public TreeScope,
public SecurityContext,
public ExecutionContext,
public DocumentShutdownNotifier,
public SynchronousMutationNotifier,
public Supplementable<Document> {
// Factory for web-exposed Document constructor. The argument document must be
// a document instance representing window.document, and it works as the
// source of ExecutionContext and security origin of the new document.
static Document* Create(Document&);
// Construct a Document instance with the default DocumentInit and
// kDefaultDocumentClass.
explicit Document(const DocumentInit& init,
DocumentClassFlags flags = kDefaultDocumentClass);
~Document() override;
static Range* CreateRangeAdjustedToTreeScope(const TreeScope&,
const Position&);
// Support JS introspection of frame policy (e.g. feature policy).
DOMFeaturePolicy* featurePolicy();
MediaQueryMatcher& GetMediaQueryMatcher();
void MediaQueryAffectingValueChanged();
using SecurityContext::GetContentSecurityPolicy;
using SecurityContext::GetMutableSecurityOrigin;
using SecurityContext::GetSecurityOrigin;
using TreeScope::getElementById;
// ExecutionContext overrides:
bool IsDocument() const final { return true; }
bool ShouldInstallV8Extensions() const final;
ContentSecurityPolicy* GetContentSecurityPolicyForWorld() override;
bool CanContainRangeEndPoint() const override { return true; }
SelectorQueryCache& GetSelectorQueryCache();
// Focus Management.
Element* ActiveElement() const;
bool hasFocus() const;
// DOM methods & attributes for Document
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste, kBeforepaste)
DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange, kPointerlockchange)
DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror, kPointerlockerror)
DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange)
DEFINE_ATTRIBUTE_EVENT_LISTENER(visibilitychange, kVisibilitychange)
ViewportData& GetViewportData() const { return *viewport_data_; }
String OutgoingReferrer() const override;
network::mojom::ReferrerPolicy GetReferrerPolicy() const override;
void SetDoctype(DocumentType*);
DocumentType* doctype() const { return doc_type_.Get(); }
DOMImplementation& implementation();
Element* documentElement() const { return document_element_.Get(); }
Location* location() const;
Element* CreateElementForBinding(const AtomicString& local_name,
ExceptionState& = ASSERT_NO_EXCEPTION);
Element* CreateElementForBinding(const AtomicString& local_name,
const StringOrElementCreationOptions&,
Element* createElementNS(const AtomicString& namespace_uri,
const AtomicString& qualified_name,
Element* createElementNS(const AtomicString& namespace_uri,
const AtomicString& qualified_name,
const StringOrElementCreationOptions&,
DocumentFragment* createDocumentFragment();
Text* createTextNode(const String& data);
Comment* createComment(const String& data);
CDATASection* createCDATASection(const String& data, ExceptionState&);
ProcessingInstruction* createProcessingInstruction(const String& target,
const String& data,
Attr* createAttribute(const AtomicString& name, ExceptionState&);
Attr* createAttributeNS(const AtomicString& namespace_uri,
const AtomicString& qualified_name,
Node* importNode(Node* imported_node, bool deep, ExceptionState&);
// "create an element" defined in DOM standard. This supports both of
// autonomous custom elements and customized built-in elements.
Element* CreateElement(const QualifiedName&,
const CreateElementFlags,
const AtomicString& is);
// Creates an element without custom element processing.
Element* CreateRawElement(const QualifiedName&,
const CreateElementFlags = CreateElementFlags());
Element* ElementFromPoint(double x, double y) const;
HeapVector<Member<Element>> ElementsFromPoint(double x, double y) const;
Range* caretRangeFromPoint(int x, int y);
Element* scrollingElement();
// When calling from C++ code, use this method. scrollingElement() is
// just for the web IDL implementation.
Element* ScrollingElementNoLayout();
String readyState() const;
AtomicString characterSet() const { return Document::EncodingName(); }
AtomicString EncodingName() const;
void SetContent(const String&);
String SuggestedMIMEType() const;
void SetMimeType(const AtomicString&);
AtomicString contentType() const; // DOM 4 document.contentType
const AtomicString& ContentLanguage() const { return content_language_; }
void SetContentLanguage(const AtomicString&);
String xmlEncoding() const { return xml_encoding_; }
String xmlVersion() const { return xml_version_; }
enum StandaloneStatus { kStandaloneUnspecified, kStandalone, kNotStandalone };
bool xmlStandalone() const { return xml_standalone_ == kStandalone; }
StandaloneStatus XmlStandaloneStatus() const {
return static_cast<StandaloneStatus>(xml_standalone_);
bool HasXMLDeclaration() const { return has_xml_declaration_; }
void SetXMLEncoding(const String& encoding) {
xml_encoding_ = encoding;
} // read-only property, only to be set from XMLDocumentParser
void setXMLVersion(const String&, ExceptionState&);
void setXMLStandalone(bool, ExceptionState&);
void SetHasXMLDeclaration(bool has_xml_declaration) {
has_xml_declaration_ = has_xml_declaration ? 1 : 0;
String visibilityState() const;
bool IsPageVisible() const;
bool hidden() const;
void DidChangeVisibilityState();
bool wasDiscarded() const;
void SetWasDiscarded(bool);
// If the document is "prefetch only", it will not be fully contstructed,
// and should never be displayed. Only a few resources will be loaded and
// scanned, in order to warm up caches.
bool IsPrefetchOnly() const;
Node* adoptNode(Node* source, ExceptionState&);
HTMLCollection* images();
HTMLCollection* embeds();
HTMLCollection* applets();
HTMLCollection* links();
HTMLCollection* forms();
HTMLCollection* anchors();
HTMLCollection* scripts();
HTMLAllCollection* all();
HTMLCollection* WindowNamedItems(const AtomicString& name);
DocumentNameCollection* DocumentNamedItems(const AtomicString& name);
HTMLCollection* DocumentAllNamedItems(const AtomicString& name);
// "defaultView" attribute defined in HTML spec.
LocalDOMWindow* defaultView() const;
bool IsHTMLDocument() const { return document_classes_ & kHTMLDocumentClass; }
bool IsXHTMLDocument() const {
return document_classes_ & kXHTMLDocumentClass;
bool IsXMLDocument() const { return document_classes_ & kXMLDocumentClass; }
bool IsImageDocument() const {
return document_classes_ & kImageDocumentClass;
bool IsSVGDocument() const { return document_classes_ & kSVGDocumentClass; }
bool IsPluginDocument() const {
return document_classes_ & kPluginDocumentClass;
bool IsMediaDocument() const {
return document_classes_ & kMediaDocumentClass;
bool HasSVGRootNode() const;
bool IsFrameSet() const;
bool IsSrcdocDocument() const { return is_srcdoc_document_; }
bool IsMobileDocument() const { return is_mobile_document_; }
StyleResolver* GetStyleResolver() const;
StyleResolver& EnsureStyleResolver() const;
bool IsViewSource() const { return is_view_source_; }
void SetIsViewSource(bool);
bool IsImmersiveArOverlay() const { return is_immersive_ar_overlay_; }
void SetIsImmersiveArOverlay(bool);
bool SawElementsInKnownNamespaces() const {
return saw_elements_in_known_namespaces_;
bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) override;
bool IsScriptExecutionReady() const {
return HaveImportsLoaded() && HaveScriptBlockingStylesheetsLoaded();
bool IsForExternalHandler() const { return is_for_external_handler_; }
void SetIsForExternalHandler() {
is_for_external_handler_ = true;
// This is a DOM function.
StyleSheetList& StyleSheets();
StyleEngine& GetStyleEngine() {
return *style_engine_.Get();
void ScheduleUseShadowTreeUpdate(SVGUseElement&);
void UnscheduleUseShadowTreeUpdate(SVGUseElement&);
void EvaluateMediaQueryList();
FormController& GetFormController();
DocumentState* GetDocumentState() const;
void SetStateForNewControls(const Vector<String>&);
LocalFrameView* View() const; // can be null
LocalFrame* GetFrame() const { return frame_; } // can be null
// Returns frame_ for current document, or if this is an HTML import, master
// document's frame_, if any. Can be null.
// TODO(kochi): Audit usage of this interface (
LocalFrame* GetFrameOfMasterDocument() const;
Page* GetPage() const; // can be null
Settings* GetSettings() const; // can be null
float DevicePixelRatio() const;
Range* createRange();
NodeIterator* createNodeIterator(Node* root,
unsigned what_to_show,
TreeWalker* createTreeWalker(Node* root,
unsigned what_to_show,
// Special support for editing
Text* CreateEditingTextNode(const String&);
void SetupFontBuilder(ComputedStyle& document_style);
bool NeedsLayoutTreeUpdate() const;
// Whether we need layout tree update for this node or not, without
// considering nodes in display locked subtrees.
bool NeedsLayoutTreeUpdateForNode(const Node&,
bool ignore_adjacent_style = false) const;
// Whether we need layout tree update for this node or not, including nodes in
// display locked subtrees.
bool NeedsLayoutTreeUpdateForNodeIncludingDisplayLocked(
const Node&,
bool ignore_adjacent_style = false) const;
// Update ComputedStyles and attach LayoutObjects if necessary, but don't
// lay out.
void UpdateStyleAndLayoutTree();
void UpdateStyleAndLayoutTreeForNode(const Node*);
void UpdateStyleAndLayoutTreeForSubtree(const Node*);
enum ForcedLayoutStatus { IsForcedLayout, IsNotForcedLayout };
void UpdateStyleAndLayout(ForcedLayoutStatus = IsForcedLayout);
void LayoutUpdated();
enum RunPostLayoutTasks {
void UpdateStyleAndLayoutForNode(const Node*);
scoped_refptr<const ComputedStyle> StyleForPage(int page_index);
// Ensures that location-based data will be valid for a given node.
// This will run style and layout if they are currently dirty, and it may also
// run compositing inputs if the node is in a sticky subtree (as the sticky
// offset may change the node's position).
// Due to this you should only call this if you definitely need valid location
// data, otherwise use one of the |UpdateStyleAndLayout...| methods above.
void EnsurePaintLocationDataValidForNode(const Node*);
// Returns true if page box (margin boxes and page borders) is visible.
bool IsPageBoxVisible(int page_index);
// Returns the preferred page size and margins in pixels, assuming 96
// pixels per inch. pageSize, marginTop, marginRight, marginBottom,
// marginLeft must be initialized to the default values that are used if
// auto is specified.
void PageSizeAndMarginsInPixels(int page_index,
DoubleSize& page_size,
int& margin_top,
int& margin_right,
int& margin_bottom,
int& margin_left);
ResourceFetcher* Fetcher() const override { return fetcher_.Get(); }
using ExecutionContext::NotifyContextDestroyed;
void Initialize();
virtual void Shutdown();
void InitContentSecurityPolicy(ContentSecurityPolicy*);
// If you have a Document, use GetLayoutView() instead which is faster.
void GetLayoutObject() const = delete;
LayoutView* GetLayoutView() const { return layout_view_; }
// This will return an AXObjectCache only if there's one or more
// AXContext associated with this document. When all associated
// AXContexts are deleted, the AXObjectCache will be removed.
AXObjectCache* ExistingAXObjectCache() const;
Document& AXObjectCacheOwner() const;
void ClearAXObjectCache();
// to get visually ordered hebrew and arabic pages right
bool VisuallyOrdered() const { return visually_ordered_; }
DocumentLoader* Loader() const;
// This is the DOM API enteredDocument is the responsible
// document of the entry settings object.
void open(Document* entered_document, ExceptionState&);
// This is used internally and does not handle exceptions.
void open();
DocumentParser* OpenForNavigation(ParserSynchronizationPolicy,
const AtomicString& mime_type,
const AtomicString& encoding);
DocumentParser* ImplicitOpen(ParserSynchronizationPolicy);
// This is the DOM API implementation.
// opens a new window when called with three arguments.
Document* open(v8::Isolate*,
const AtomicString& type,
const AtomicString& replace,
DOMWindow* open(v8::Isolate*,
const String& url_string,
const AtomicString& name,
const AtomicString& features,
// This is the DOM API document.close().
void close(ExceptionState&);
// This is used internally and does not handle exceptions.
void close();
// Corresponds to "9. Abort the active document of browsingContext."
void Abort();
void CheckCompleted();
// Dispatches beforeunload into this document. Returns true if the
// beforeunload handler indicates that it is safe to proceed with an unload,
// false otherwise.
// |chrome_client| is used to synchronously get user consent (via a modal
// javascript dialog) to allow the unload to proceed if the beforeunload
// handler returns a non-null value, indicating unsaved state. If a
// null |chrome_client| is provided and the beforeunload returns a non-null
// value this function will automatically return false, indicating that the
// unload should not proceed. A null chrome client is set to by the freezing
// logic, which uses this to determine if a non-empty beforeunload handler
// is present before allowing discarding to proceed.
// |is_reload| indicates if the beforeunload is being triggered because of a
// reload operation, otherwise it is assumed to be a page close or navigation.
// |did_allow_navigation| is set to reflect the choice made by the user via
// the modal dialog. The value is meaningless if |auto_cancel|
// is true, in which case it will always be set to false.
bool DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
bool is_reload,
bool& did_allow_navigation);
struct UnloadEventTiming {
base::TimeTicks unload_event_start;
base::TimeTicks unload_event_end;
// Dispatches "pagehide", "visibilitychange" and "unload" events, if not
// dispatched already. Fills unload timing if present and |committing_origin|
// has access to the unload timing of the document.
void DispatchUnloadEvents(SecurityOrigin* committing_origin,
void DispatchFreezeEvent();
enum PageDismissalType {
PageDismissalType PageDismissalEventBeingDispatched() const;
void CancelParsing();
void write(const String& text,
Document* entered_document = nullptr,
ExceptionState& = ASSERT_NO_EXCEPTION);
void writeln(const String& text,
Document* entered_document = nullptr,
ExceptionState& = ASSERT_NO_EXCEPTION);
void write(v8::Isolate*, const Vector<String>& text, ExceptionState&);
void writeln(v8::Isolate*, const Vector<String>& text, ExceptionState&);
// TrustedHTML variants of the above.
// TODO(mkwst): Write a spec for this.
void write(v8::Isolate*, TrustedHTML*, ExceptionState&);
void writeln(v8::Isolate*, TrustedHTML*, ExceptionState&);
bool IsTrustedTypesEnabledForDoc() const;
bool WellFormed() const { return well_formed_; }
// Return the document URL, or an empty URL if it's unavailable.
// This is not an implementation of web-exposed Document.prototype.URL.
const KURL& Url() const final { return url_; }
void SetURL(const KURL&);
// Bind the url to document.url, if unavailable bind to about:blank.
KURL urlForBinding() const;
// To understand how these concepts relate to one another, please see the
// comments surrounding their declaration.
// Document base URL.
const KURL& BaseURL() const final;
void SetBaseURLOverride(const KURL&);
const KURL& BaseURLOverride() const { return base_url_override_; }
KURL ValidBaseElementURL() const;
const AtomicString& BaseTarget() const { return base_target_; }
void ProcessBaseElement();
// Fallback base URL.
KURL FallbackBaseURL() const;
// Creates URL based on passed relative url and this documents base URL.
// Depending on base URL value it is possible that parent document
// base URL will be used instead. Uses CompleteURLWithOverride internally.
KURL CompleteURL(const String&) const final;
// Creates URL based on passed relative url and passed base URL override.
KURL CompleteURLWithOverride(const String&,
const KURL& base_url_override) const;
// Determines whether a new document should take on the same origin as that of
// the document which created it.
static bool ShouldInheritSecurityOriginFromOwner(const KURL&);
String UserAgent() const final;
void DisableEval(const String& error_message) final;
// TODO( Implement Document's HTTPS state in more
// spec-conformant way.
HttpsState GetHttpsState() const final {
return CalculateHttpsState(GetSecurityOrigin());
CSSStyleSheet& ElementSheet();
virtual DocumentParser* CreateParser();
DocumentParser* Parser() const { return parser_.Get(); }
ScriptableDocumentParser* GetScriptableDocumentParser() const;
// FinishingPrinting denotes that the non-printing layout state is being
// restored.
enum PrintingState {
bool Printing() const { return printing_ == kPrinting; }
bool BeforePrintingOrPrinting() const {
return printing_ == kPrinting || printing_ == kBeforePrinting;
bool FinishingOrIsPrinting() {
return printing_ == kPrinting || printing_ == kFinishingPrinting;
void SetPrinting(PrintingState);
bool IsPaintingPreview() const { return is_painting_preview_; }
bool IsCapturingLayout() const {
return printing_ == kPrinting || is_painting_preview_;
void SetIsPaintingPreview(bool);
enum CompatibilityMode { kQuirksMode, kLimitedQuirksMode, kNoQuirksMode };
void SetCompatibilityMode(CompatibilityMode);
CompatibilityMode GetCompatibilityMode() const { return compatibility_mode_; }
String compatMode() const;
bool InQuirksMode() const { return compatibility_mode_ == kQuirksMode; }
bool InLimitedQuirksMode() const {
return compatibility_mode_ == kLimitedQuirksMode;
bool InNoQuirksMode() const { return compatibility_mode_ == kNoQuirksMode; }
bool InLineHeightQuirksMode() const { return !InNoQuirksMode(); }
enum DocumentReadyState { kLoading, kInteractive, kComplete };
void SetReadyState(DocumentReadyState);
bool IsLoadCompleted() const;
bool IsFreezingInProgress() const { return is_freezing_in_progress_; }
enum ParsingState { kParsing, kInDOMContentLoaded, kFinishedParsing };
void SetParsingState(ParsingState);
bool Parsing() const { return parsing_state_ == kParsing; }
bool HasFinishedParsing() const { return parsing_state_ == kFinishedParsing; }
bool ShouldScheduleLayout() const;
TextLinkColors& GetTextLinkColors() { return text_link_colors_; }
const TextLinkColors& GetTextLinkColors() const { return text_link_colors_; }
VisitedLinkState& GetVisitedLinkState() const { return *visited_link_state_; }
MouseEventWithHitTestResults PerformMouseEventHitTest(const HitTestRequest&,
const PhysicalOffset&,
const WebMouseEvent&);
void SetHadKeyboardEvent(bool had_keyboard_event) {
had_keyboard_event_ = had_keyboard_event;
bool HadKeyboardEvent() const { return had_keyboard_event_; }
void SetLastFocusType(WebFocusType last_focus_type);
WebFocusType LastFocusType() const { return last_focus_type_; }
bool SetFocusedElement(Element*, const FocusParams&);
void ClearFocusedElement();
Element* FocusedElement() const { return focused_element_.Get(); }
UserActionElementSet& UserActionElements() { return user_action_elements_; }
const UserActionElementSet& UserActionElements() const {
return user_action_elements_;
ExplicitlySetAttrElementsMap* GetExplicitlySetAttrElementsMap(Element*);
// Returns false if the function fails. e.g. |pseudo| is not supported.
bool SetPseudoStateForTesting(Element& element,
const String& pseudo,
bool matches);
void EnqueueAutofocusCandidate(Element&);
bool HasAutofocusCandidates() const;
void FlushAutofocusCandidates();
void FinalizeAutofocus();
void SetSequentialFocusNavigationStartingPoint(Node*);
Element* SequentialFocusNavigationStartingPoint(WebFocusType) const;
void SetActiveElement(Element*);
Element* GetActiveElement() const { return active_element_.Get(); }
Element* HoverElement() const { return hover_element_.Get(); }
void RemoveFocusedElementOfSubtree(Node&, bool among_children_only = false);
void HoveredElementDetached(Element&);
void ActiveChainNodeDetached(Element&);
// Updates hover and active state of elements in the Document. The
// |is_active| param specifies whether the active state should be set or
// unset. |update_active_chain| is used to prevent updates to elements
// outside the frozen active chain; passing false will only refresh the
// active state of elements in the existing chain, but not outside of it. The
// given element is the inner-most element whose state is being modified.
// Hover is always applied.
void UpdateHoverActiveState(bool is_active,
bool update_active_chain,
// Updates for :target (CSS3 selector).
void SetCSSTarget(Element*);
Element* CssTarget() const { return css_target_; }
void ScheduleLayoutTreeUpdateIfNeeded();
bool HasPendingForcedStyleRecalc() const;
void RegisterNodeList(const LiveNodeListBase*);
void UnregisterNodeList(const LiveNodeListBase*);
void RegisterNodeListWithIdNameCache(const LiveNodeListBase*);
void UnregisterNodeListWithIdNameCache(const LiveNodeListBase*);
bool ShouldInvalidateNodeListCaches(
const QualifiedName* attr_name = nullptr) const;
void InvalidateNodeListCaches(const QualifiedName* attr_name);
void AttachNodeIterator(NodeIterator*);
void DetachNodeIterator(NodeIterator*);
void MoveNodeIteratorsToNewDocument(Node&, Document&);
void AttachRange(Range*);
void DetachRange(Range*);
void DidMoveTreeToNewDocument(const Node& root);
// nodeChildrenWillBeRemoved is used when removing all node children at once.
void NodeChildrenWillBeRemoved(ContainerNode&);
// nodeWillBeRemoved is only safe when removing one node at a time.
void NodeWillBeRemoved(Node&);
bool CanAcceptChild(const Node& new_child,
const Node* next,
const Node* old_child,
ExceptionState&) const;
void DidInsertText(const CharacterData&, unsigned offset, unsigned length);
void DidRemoveText(const CharacterData&, unsigned offset, unsigned length);
void DidMergeTextNodes(const Text& merged_node,
const Text& node_to_be_removed,
unsigned old_length);
void DidSplitTextNode(const Text& old_node);
void ClearDOMWindow() { dom_window_ = nullptr; }
LocalDOMWindow* domWindow() const { return dom_window_; }
// Helper functions for forwarding LocalDOMWindow event related tasks to the
// LocalDOMWindow if it exists.
void SetWindowAttributeEventListener(const AtomicString& event_type,
EventListener* GetWindowAttributeEventListener(
const AtomicString& event_type);
static void RegisterEventFactory(std::unique_ptr<EventFactoryBase>);
static Event* createEvent(ScriptState*,
const String& event_type,
// keep track of what types of event listeners are registered, so we don't
// dispatch events unnecessarily
enum ListenerType {
kDOMSubtreeModifiedListener = 1,
kDOMNodeInsertedListener = 1 << 1,
kDOMNodeRemovedListener = 1 << 2,
kDOMNodeRemovedFromDocumentListener = 1 << 3,
kDOMNodeInsertedIntoDocumentListener = 1 << 4,
kDOMCharacterDataModifiedListener = 1 << 5,
kAnimationEndListener = 1 << 6,
kAnimationStartListener = 1 << 7,
kAnimationIterationListener = 1 << 8,
kTransitionRunListener = 1 << 9,
kTransitionStartListener = 1 << 10,
kTransitionEndListener = 1 << 11,
kTransitionCancelListener = 1 << 12,
kScrollListener = 1 << 13,
kLoadListenerAtCapturePhaseOrAtStyleElement = 1 << 14
// 1 bit remaining
bool HasListenerType(ListenerType listener_type) const {
return (listener_types_ & listener_type);
void AddListenerTypeIfNeeded(const AtomicString& event_type, EventTarget&);
bool HasMutationObserversOfType(MutationType type) const {
return mutation_observer_types_ & type;
bool HasMutationObservers() const { return mutation_observer_types_; }
void AddMutationObserverTypes(MutationType types) {
mutation_observer_types_ |= types;
IntersectionObserverController* GetIntersectionObserverController();
IntersectionObserverController& EnsureIntersectionObserverController();
ResizeObserverController* GetResizeObserverController() const {
return resize_observer_controller_;
ResizeObserverController& EnsureResizeObserverController();
// Returns the owning element in the parent document. Returns nullptr if
// this is the top level document or the owner is remote.
HTMLFrameOwnerElement* LocalOwner() const;
void WillChangeFrameOwnerProperties(int margin_width,
int margin_height,
bool is_display_none);
String title() const { return title_; }
void setTitle(const String&);
Element* TitleElement() const { return title_element_.Get(); }
void SetTitleElement(Element*);
void RemoveTitle(Element* title_element);
const AtomicString& dir();
void setDir(const AtomicString&);
String cookie(ExceptionState&) const;
void setCookie(const String&, ExceptionState&);
bool CookiesEnabled() const;
const AtomicString& referrer() const;
String domain() const;
void setDomain(const String& new_domain, ExceptionState&);
void OverrideLastModified(const AtomicString& modified) {
override_last_modified_ = modified;
String lastModified() const;
Element* FindInPageRoot() const { return find_in_page_root_.Get(); }
void SetFindInPageRoot(Element* find_in_page_root);
// The cookieURL is used to query the cookie database for this document's
// cookies. For example, if the cookie URL is, we'll
// use the non-Secure cookies for when computing
// document.cookie.
// Q: How is the cookieURL different from the document's URL?
// A: The two URLs are the same almost all the time. However, if one
// document inherits the security context of another document, it
// inherits its cookieURL but not its URL.
const KURL& CookieURL() const { return cookie_url_; }
void SetCookieURL(const KURL& url) { cookie_url_ = url; }
scoped_refptr<const SecurityOrigin> TopFrameOrigin() const;
const KURL SiteForCookies() const;
// Storage Access API methods to check for or request access to storage that
// may otherwise be blocked.
ScriptPromise hasStorageAccess(ScriptState* script_state) const;
ScriptPromise requestStorageAccess(ScriptState* script_state) const;
// The following implements the rule from HTML 4 for what valid names are.
// To get this right for all the XML cases, we probably have to improve this
// or move it and make it sensitive to the type of document.
static bool IsValidName(const String&);
// The following breaks a qualified name into a prefix and a local name.
// It also does a validity check, and returns false if the qualified name
// is invalid. It also sets ExceptionCode when name is invalid.
static bool ParseQualifiedName(const AtomicString& qualified_name,
AtomicString& prefix,
AtomicString& local_name,
// Checks to make sure prefix and namespace do not conflict (per DOM Core 3)
static bool HasValidNamespaceForElements(const QualifiedName&);
static bool HasValidNamespaceForAttributes(const QualifiedName&);
// "body element" as defined by HTML5
// (
// That is, the first body or frameset child of the document element.
HTMLElement* body() const;
// "HTML body element" as defined by CSSOM View spec
// (
// That is, the first body child of the document element.
HTMLBodyElement* FirstBodyElement() const;
void setBody(HTMLElement*, ExceptionState&);
void WillInsertBody();
HTMLHeadElement* head() const;
// Decide which element is to define the viewport's overflow policy.
Element* ViewportDefiningElement() const;
DocumentMarkerController& Markers() const { return *markers_; }
// Support for Javascript execCommand, and related methods
// See "core/editing/commands/" for implementations.
bool execCommand(const String& command,
bool show_ui,
const String& value,
bool IsRunningExecCommand() const { return is_running_exec_command_; }
bool queryCommandEnabled(const String& command, ExceptionState&);
bool queryCommandIndeterm(const String& command, ExceptionState&);
bool queryCommandState(const String& command, ExceptionState&);
bool queryCommandSupported(const String& command, ExceptionState&);
String queryCommandValue(const String& command, ExceptionState&);
KURL OpenSearchDescriptionURL();
// designMode support
bool InDesignMode() const { return design_mode_; }
String designMode() const;
void setDesignMode(const String&);
// The document of the parent frame.
Document* ParentDocument() const;
Document& TopDocument() const;
Document* ContextDocument() const;
ScriptRunner* GetScriptRunner() { return script_runner_.Get(); }
void currentScriptForBinding(HTMLScriptElementOrSVGScriptElement&) const;
void PushCurrentScript(ScriptElementBase*);
void PopCurrentScript(ScriptElementBase*);
void SetTransformSource(std::unique_ptr<TransformSource>);
TransformSource* GetTransformSource() const {
return transform_source_.get();
void IncDOMTreeVersion() {
dom_tree_version_ = ++global_tree_version_;
uint64_t DomTreeVersion() const { return dom_tree_version_; }
uint64_t StyleVersion() const { return style_version_; }
enum PendingSheetLayout {
Vector<IconURL> IconURLs(int icon_types_mask);
base::Optional<Color> ThemeColor() const;
// Returns the HTMLLinkElement currently in use for the Web Manifest.
// Returns null if there is no such element.
HTMLLinkElement* LinkManifest() const;
// Returns the HTMLLinkElement holding the canonical URL. Returns null if
// there is no such element.
HTMLLinkElement* LinkCanonical() const;
void UpdateFocusAppearanceAfterLayout();
void CancelFocusAppearanceUpdate();
// Return true after UpdateFocusAppearanceAfterLayout() call and before
// updating focus appearance.
bool WillUpdateFocusAppearance() const;
bool IsDNSPrefetchEnabled() const { return is_dns_prefetch_enabled_; }
void ParseDNSPrefetchControlHeader(const String&);
void TasksWerePaused() final;
void TasksWereUnpaused() final;
bool TasksNeedPause() final;
void FinishedParsing();
void SetEncodingData(const DocumentEncodingData& new_data);
const WTF::TextEncoding& Encoding() const {
return encoding_data_.Encoding();
bool EncodingWasDetectedHeuristically() const {
return encoding_data_.WasDetectedHeuristically();
bool SawDecodingError() const { return encoding_data_.SawDecodingError(); }
void SetAnnotatedRegionsDirty(bool f) { annotated_regions_dirty_ = f; }
bool AnnotatedRegionsDirty() const { return annotated_regions_dirty_; }
bool HasAnnotatedRegions() const { return has_annotated_regions_; }
void SetHasAnnotatedRegions(bool f) { has_annotated_regions_ = f; }
const Vector<AnnotatedRegionValue>& AnnotatedRegions() const;
void SetAnnotatedRegions(const Vector<AnnotatedRegionValue>&);
void RemoveAllEventListeners() final;
const SVGDocumentExtensions* SvgExtensions();
SVGDocumentExtensions& AccessSVGExtensions();
bool AllowInlineEventHandler(Node*,
const String& context_url,
const WTF::OrdinalNumber& context_line);
void StatePopped(scoped_refptr<SerializedScriptValue>);
enum LoadEventProgress {
bool LoadEventStillNeeded() const {
return load_event_progress_ == kLoadEventNotRun;
bool LoadEventFinished() const {
return load_event_progress_ >= kLoadEventCompleted;
bool UnloadStarted() const {
return load_event_progress_ >= kPageHideInProgress;
bool ProcessingBeforeUnload() const {
return load_event_progress_ == kBeforeUnloadEventInProgress;
void SetContainsPlugins() { contains_plugins_ = true; }
bool ContainsPlugins() const { return contains_plugins_; }
bool IsContextThread() const final;
bool IsJSExecutionForbidden() const final { return false; }
void EnqueueResizeEvent();
void EnqueueScrollEventForNode(Node*);
void EnqueueScrollEndEventForNode(Node*);
void EnqueueOverscrollEventForNode(Node* target,
double delta_x,
double delta_y);
void EnqueueDisplayLockActivationTask(base::OnceClosure);
void EnqueueAnimationFrameTask(base::OnceClosure);
void EnqueueAnimationFrameEvent(Event*);
// Only one event for a target/event type combination will be dispatched per
// frame.
void EnqueueUniqueAnimationFrameEvent(Event*);
void EnqueueMediaQueryChangeListeners(
void EnqueueVisualViewportScrollEvent();
void EnqueueVisualViewportResizeEvent();
void DispatchEventsForPrinting();
bool HasFullscreenSupplement() const { return has_fullscreen_supplement_; }
void SetHasFullscreenSupplement() { has_fullscreen_supplement_ = true; }
void exitPointerLock();
Element* PointerLockElement() const;
// Used to allow element that loads data without going through a FrameLoader
// to delay the 'load' event.
void IncrementLoadEventDelayCount() { ++load_event_delay_count_; }
void DecrementLoadEventDelayCount();
void CheckLoadEventSoon();
bool IsDelayingLoadEvent();
void LoadPluginsSoon();
// This calls checkCompleted() sync and thus can cause JavaScript execution.
void DecrementLoadEventDelayCountAndCheckLoadEvent();
const DocumentTiming& GetTiming() const { return document_timing_; }
int RequestAnimationFrame(FrameRequestCallbackCollection::FrameCallback*);
void CancelAnimationFrame(int id);
void ServiceScriptedAnimations(
base::TimeTicks monotonic_animation_start_time);
void SetCurrentFrameIsThrottled(bool throttled) {
current_frame_is_throttled_ = true;
int RequestPostAnimationFrame(FrameRequestCallbackCollection::FrameCallback*);
void CancelPostAnimationFrame(int id);
void RunPostAnimationFrameCallbacks();
int RequestIdleCallback(ScriptedIdleTaskController::IdleTask*,
const IdleRequestOptions*);
void CancelIdleCallback(int id);
EventTarget* ErrorEventTarget() final;
void ExceptionThrown(ErrorEvent*) final;
void InitDNSPrefetch();
bool IsInDocumentWrite() const { return write_recursion_depth_ > 0; }
TextAutosizer* GetTextAutosizer();
ScriptValue registerElement(ScriptState*,
const AtomicString& name,
const ElementRegistrationOptions*,
V0CustomElementRegistrationContext* RegistrationContext() const;
V0CustomElementMicrotaskRunQueue* CustomElementMicrotaskRunQueue();
void ClearImportsController();
HTMLImportsController* EnsureImportsController();
HTMLImportsController* ImportsController() const {
return imports_controller_;
HTMLImportLoader* ImportLoader() const;
bool IsHTMLImport() const;
// TODO(kochi): Audit usage of this interface (
Document& MasterDocument() const;
void DidLoadAllImports();
void AdjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>&,
const LayoutObject&) const;
void AdjustFloatRectForScrollAndAbsoluteZoom(FloatRect&,
const LayoutObject&) const;
void SetContextFeatures(ContextFeatures&);
ContextFeatures& GetContextFeatures() const { return *context_features_; }
ElementDataCache* GetElementDataCache() { return element_data_cache_.Get(); }
void DidLoadAllScriptBlockingResources();
void DidAddPendingParserBlockingStylesheet();
void DidLoadAllPendingParserBlockingStylesheets();
void DidRemoveAllPendingStylesheets();
bool InStyleRecalc() const {
return lifecycle_.GetState() == DocumentLifecycle::kInStyleRecalc;
// Return a Locale for the default locale if the argument is null or empty.
Locale& GetCachedLocale(const AtomicString& locale = g_null_atom);
AnimationClock& GetAnimationClock();
const AnimationClock& GetAnimationClock() const;
DocumentTimeline& Timeline() const { return *timeline_; }
PendingAnimations& GetPendingAnimations() { return *pending_animations_; }
WorkletAnimationController& GetWorkletAnimationController() {
return *worklet_animation_controller_;
void AddToTopLayer(Element*, const Element* before = nullptr);
void RemoveFromTopLayer(Element*);
const HeapVector<Member<Element>>& TopLayerElements() const {
return top_layer_elements_;
HTMLDialogElement* ActiveModalDialog() const;
// A non-null template_document_host_ implies that |this| was created by
// EnsureTemplateDocument().
bool IsTemplateDocument() const { return !!template_document_host_; }
Document& EnsureTemplateDocument();
Document* TemplateDocumentHost() { return template_document_host_; }
// TODO(thestig): Rename these and related functions, since we can call them
// for controls outside of forms as well.
void DidAssociateFormControl(Element*);
void AddConsoleMessageImpl(ConsoleMessage*, bool discard_duplicates) final;
LocalDOMWindow* ExecutingWindow() const final;
LocalFrame* ExecutingFrame();
DocumentLifecycle& Lifecycle() { return lifecycle_; }
const DocumentLifecycle& Lifecycle() const { return lifecycle_; }
bool IsActive() const { return lifecycle_.IsActive(); }
bool IsDetached() const {
return lifecycle_.GetState() >= DocumentLifecycle::kStopping;
bool IsStopped() const {
return lifecycle_.GetState() == DocumentLifecycle::kStopped;
enum HttpRefreshType { kHttpRefreshFromHeader, kHttpRefreshFromMetaTag };
void MaybeHandleHttpRefresh(const String&, HttpRefreshType);
bool IsHttpRefreshScheduledWithin(base::TimeDelta interval);
void SetHasViewportUnits() { has_viewport_units_ = true; }
bool HasViewportUnits() const { return has_viewport_units_; }
void SetResizedForViewportUnits();
void ClearResizedForViewportUnits();
void UpdateActiveStyle();
void Trace(Visitor*) override;
AtomicString ConvertLocalName(const AtomicString&);
void PlatformColorsChanged();
HostsUsingFeatures::Value& HostsUsingFeaturesValue() {
return hosts_using_features_value_;
NthIndexCache* GetNthIndexCache() const { return nth_index_cache_; }
bool IsSecureContext(String& error_message) const override;
bool IsSecureContext() const override;
void SetSecureContextStateForTesting(SecureContextState state) {
secure_context_state_ = state;
CanvasFontCache* GetCanvasFontCache();
// Used by unit tests so that all parsing will be main thread for
// controlling parsing and chunking precisely.
static void SetThreadedParsingEnabledForTesting(bool);
static bool ThreadedParsingEnabledForTesting();
void IncrementNodeCount() { node_count_++; }
void DecrementNodeCount() {
DCHECK_GT(node_count_, 0);
int NodeCount() const { return node_count_; }
SnapCoordinator& GetSnapCoordinator();
void DidEnforceInsecureRequestPolicy();
void DidEnforceInsecureNavigationsSet();
// Temporary flag for some UseCounter items.
enum class InDOMNodeRemovedHandlerState {
void SetInDOMNodeRemovedHandlerState(InDOMNodeRemovedHandlerState state) {
in_dom_node_removed_handler_state_ = state;
InDOMNodeRemovedHandlerState GetInDOMNodeRemovedHandlerState() const {
return in_dom_node_removed_handler_state_;
bool InDOMNodeRemovedHandler() const {
return in_dom_node_removed_handler_state_ !=
void CountDetachingNodeAccessInDOMNodeRemovedHandler();
bool MayContainV0Shadow() const { return may_contain_v0_shadow_; }
ShadowCascadeOrder GetShadowCascadeOrder() const {
return shadow_cascade_order_;
void SetShadowCascadeOrder(ShadowCascadeOrder);
bool ContainsV1ShadowTree() const {
return shadow_cascade_order_ == ShadowCascadeOrder::kShadowCascadeV1;
Element* rootScroller() const;
void setRootScroller(Element*, ExceptionState& = ASSERT_NO_EXCEPTION);
RootScrollerController& GetRootScrollerController() const {
return *root_scroller_controller_;
bool IsInMainFrame() const;
const PropertyRegistry* GetPropertyRegistry() const;
PropertyRegistry* GetPropertyRegistry();
// Used to notify the embedder when the user edits the value of a
// text field in a non-secure context.
void MaybeQueueSendDidEditFieldInInsecureContext();
CoreProbeSink* GetProbeSink() final;
service_manager::InterfaceProvider* GetInterfaceProvider() final;
BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() final;
// May return nullptr when PerformanceManager instrumentation is disabled.
DocumentResourceCoordinator* GetResourceCoordinator();
// Apply pending feature policy headers.
void ApplyPendingFeaturePolicyHeaders();
// Set the report-only feature policy on this document in response to an HTTP
// Feature-Policy-Report-Only header.
void ApplyReportOnlyFeaturePolicyFromHeader(
const String& feature_policy_report_only_header);
const AtomicString& bgColor() const;
void setBgColor(const AtomicString&);
const AtomicString& fgColor() const;
void setFgColor(const AtomicString&);
const AtomicString& alinkColor() const;
void setAlinkColor(const AtomicString&);
const AtomicString& linkColor() const;
void setLinkColor(const AtomicString&);
const AtomicString& vlinkColor() const;
void setVlinkColor(const AtomicString&);
void clear() {}
void captureEvents() {}
void releaseEvents() {}
ukm::UkmRecorder* UkmRecorder();
ukm::SourceId UkmSourceID() const;
// Tracks and reports UKM metrics of the number of attempted font family match
// attempts (both successful and not successful) by the page.
FontMatchingMetrics* GetFontMatchingMetrics();
// May return nullptr.
FrameOrWorkerScheduler* GetScheduler() override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override;
void RecordUkmOutliveTimeAfterShutdown(int outlive_time_count);
bool CurrentFrameHadRAF() const;
bool NextFrameHasPendingRAF() const;
const AtomicString& RequiredCSP();
StylePropertyMapReadOnly* ComputedStyleMap(Element*);
void AddComputedStyleMapItem(Element*, StylePropertyMapReadOnly*);
StylePropertyMapReadOnly* RemoveComputedStyleMapItem(Element*);
void NavigateLocalAdsFrames();
SlotAssignmentEngine& GetSlotAssignmentEngine();
bool IsSlotAssignmentOrLegacyDistributionDirty() const;
unsigned& SlotAssignmentRecalcForbiddenRecursionDepth() {
return slot_assignment_recalc_forbidden_recursion_depth_;
bool IsSlotAssignmentRecalcForbidden() {
return slot_assignment_recalc_forbidden_recursion_depth_ > 0;
bool IsSlotAssignmentRecalcForbidden() { return false; }
unsigned& FlatTreeTraversalForbiddenRecursionDepth() {
return flat_tree_traversal_forbidden_recursion_depth_;
bool IsFlatTreeTraversalForbidden() {
return flat_tree_traversal_forbidden_recursion_depth_ > 0;
unsigned& SlotAssignmentRecalcDepth() {
return slot_assignment_recalc_depth_;
bool IsInSlotAssignmentRecalc() const {
// Since we forbid recursive slot assignement recalc, the depth should be
// <= 1.
DCHECK_LE(slot_assignment_recalc_depth_, 1u);
return slot_assignment_recalc_depth_ == 1;
bool IsVerticalScrollEnforced() const { return is_vertical_scroll_enforced_; }
bool IsLazyLoadPolicyEnforced() const;
bool IsFocusAllowed() const;
NavigationInitiatorImpl& NavigationInitiator();
LazyLoadImageObserver& EnsureLazyLoadImageObserver();
WindowAgent& GetWindowAgent();
void CountPotentialFeaturePolicyViolation(
mojom::FeaturePolicyFeature) const override;
void ReportFeaturePolicyViolation(
const String& message = g_empty_string,
// If source_file is set to empty string,
// current JS file would be used as source_file instead.
const String& source_file = g_empty_string) const override;
void IncrementNumberOfCanvases();
void ProcessJavaScriptUrl(const KURL&, ContentSecurityPolicyDisposition);
// Functions to keep count of display locks in this document.
void AddActivationBlockingDisplayLock();
void RemoveActivationBlockingDisplayLock();
int ActivationBlockingDisplayLockCount() const;
void AddLockedDisplayLock();
void RemoveLockedDisplayLock();
int LockedDisplayLockCount() const;
// Manage the element's observation for display lock activation.
void RegisterDisplayLockActivationObservation(Element*);
void UnregisterDisplayLockActivationObservation(Element*);
// Deferred compositor commits are disallowed by default, and are only allowed
// for same-origin navigations to an html document fetched with http.
bool DeferredCompositorCommitIsAllowed() {
return deferred_compositor_commit_is_allowed_;
void SetDeferredCompositorCommitIsAllowed(bool new_value) {
deferred_compositor_commit_is_allowed_ = new_value;
// Returns whether the document is inside the scope specified in the Web App
// Manifest. If the document doesn't run in a context of a Web App or has no
// associated Web App Manifest, it will return false.
bool IsInWebAppScope() const;
ComputedAccessibleNode* GetOrCreateComputedAccessibleNode(
AXID ax_id,
WebComputedAXTree* tree);
bool HaveRenderBlockingResourcesLoaded() const;
// Sets a beforeunload handler for documents which are embedding plugins. This
// includes PluginDocument as well as an HTMLDocument which embeds a plugin
// inside a cross-process frame (MimeHandlerView).
void SetShowBeforeUnloadDialog(bool show_dialog);
TrustedTypePolicyFactory* GetTrustedTypes() const override;
bool RequireTrustedTypes() const override;
void ColorSchemeChanged();
void ClearIsolatedWorldCSPForTesting(int32_t world_id);
// A META element with name=color-scheme was added, removed, or modified.
// Update the presentation level color-scheme property for the root element.
void ColorSchemeMetaChanged();
// Use counter related functions.
void CountUse(mojom::WebFeature feature) final;
void CountDeprecation(mojom::WebFeature feature) final;
void CountUse(mojom::WebFeature feature) const;
void CountProperty(CSSPropertyID property_id) const;
void CountAnimatedProperty(CSSPropertyID property_id) const;
// Count |feature| only when this document is associated with a cross-origin
// iframe.
void CountUseOnlyInCrossOriginIframe(mojom::WebFeature feature) const;
// Return whether the Feature was previously counted for this document.
// NOTE: only for use in testing.
bool IsUseCounted(mojom::WebFeature) const;
// Return whether the property was previously counted for this document.
// NOTE: only for use in testing.
bool IsPropertyCounted(CSSPropertyID property) const;
// Return whether the animated property was previously counted for this
// document.
// NOTE: only for use in testing.
bool IsAnimatedPropertyCounted(CSSPropertyID property) const;
void ClearUseCounterForTesting(mojom::WebFeature);
void SetSecurityOrigin(scoped_refptr<SecurityOrigin>) final;
// Bind Content Security Policy to this document. This will cause the
// CSP to resolve the 'self' attribute and all policies will then be
// applied to this document.
void BindContentSecurityPolicy();
bool InForcedColorsMode() const;
// Capture the toggle event during parsing either by HTML parser or XML
// parser.
void SetToggleDuringParsing(bool toggle_during_parsing) {
toggle_during_parsing_ = toggle_during_parsing;
bool ToggleDuringParsing() { return toggle_during_parsing_; }
// We setup a dummy document to sanitize clipboard markup before pasting.
// Sets and indicates whether this is the dummy document.
void SetIsForMarkupSanitization(bool is_for_sanitization) {
is_for_markup_sanitization_ = is_for_sanitization;
bool IsForMarkupSanitization() const { return is_for_markup_sanitization_; }
bool HasPendingJavaScriptUrlsForTest() {
return !pending_javascript_urls_.IsEmpty();
String GetFragmentDirective() const { return fragment_directive_; }
bool UseCountFragmentDirective() const {
return use_count_fragment_directive_;
bool AllowDirtyShadowV0Traversal() const {
return allow_dirty_shadow_v0_traversal_;
void SetAllowDirtyShadowV0Traversal(bool allow) {
allow_dirty_shadow_v0_traversal_ = allow;
void ClearXMLVersion() { xml_version_ = String(); }
virtual Document* CloneDocumentWithoutChildren() const;
void LockCompatibilityMode() { compatibility_mode_locked_ = true; }
ParserSynchronizationPolicy GetParserSynchronizationPolicy() const {
return parser_sync_policy_;
friend class IgnoreDestructiveWriteCountIncrementer;
friend class ThrowOnDynamicMarkupInsertionCountIncrementer;
friend class IgnoreOpensDuringUnloadCountIncrementer;
friend class NthIndexCache;
class NetworkStateObserver;
class SecurityContextInit;
Document(const DocumentInit& initization,
SecurityContextInit init_helper,
DocumentClassFlags document_classes);
// Post initialization of the object handling of the feature policy.
void FeaturePolicyInitialized(
const DocumentInit& document_initializer,
const SecurityContextInit& security_initializer);
friend class AXContext;
void AddAXContext(AXContext*);
void RemoveAXContext(AXContext*);
bool IsDocumentFragment() const =
delete; // This will catch anyone doing an unnecessary check.
bool IsDocumentNode() const =
delete; // This will catch anyone doing an unnecessary check.
bool IsElementNode() const =
delete; // This will catch anyone doing an unnecessary check.
ScriptedAnimationController& EnsureScriptedAnimationController();
ScriptedIdleTaskController& EnsureScriptedIdleTaskController();
void InitSecurityContext(const DocumentInit&,
const SecurityContextInit& security_initializer);
void InitSecureContextState();
SecurityContext& GetSecurityContext() final { return *this; }
const SecurityContext& GetSecurityContext() const final { return *this; }
bool HasPendingVisualUpdate() const {
return lifecycle_.GetState() == DocumentLifecycle::kVisualUpdatePending;
bool ShouldScheduleLayoutTreeUpdate() const;
void ScheduleLayoutTreeUpdate();
bool NeedsFullLayoutTreeUpdate() const;
void PropagateStyleToViewport();
void UpdateUseShadowTreesIfNeeded();
void EvaluateMediaQueryListIfNeeded();
void UpdateStyleInvalidationIfNeeded();
void UpdateStyle();
void NotifyLayoutTreeOfSubtreeChanges();
bool ChildrenCanHaveStyle() const final;
// ImplicitClose() actually does the work of closing the input stream.
void ImplicitClose();
bool ShouldComplete();
// Returns |true| if both document and its owning frame are still attached.
// Any of them could be detached during the check, e.g. by calling
// iframe.remove() from an event handler.
bool CheckCompletedInternal();
void DetachParser();
void BeginLifecycleUpdatesIfRenderingReady();
void ChildrenChanged(const ChildrenChange&) override;
String nodeName() const final;
NodeType getNodeType() const final;
bool ChildTypeAllowed(NodeType) const final;
Node* Clone(Document&, CloneChildrenFlag) const override;
void CloneDataFromDocument(const Document&);
ShadowCascadeOrder shadow_cascade_order_ = kShadowCascadeNone;
void UpdateTitle(const String&);
void DispatchDidReceiveTitle();
void UpdateFocusAppearance();
void UpdateBaseURL();
void ExecuteScriptsWaitingForResources();
void ExecuteJavaScriptUrls();
void CancelPendingJavaScriptUrls();
void LoadEventDelayTimerFired(TimerBase*);
void PluginLoadingTimerFired(TimerBase*);
void AddListenerType(ListenerType listener_type) {
listener_types_ |= listener_type;
void AddMutationEventListenerTypeIfEnabled(ListenerType);
void DidAssociateFormControlsTimerFired(TimerBase*);
void ClearFocusedElementSoon();
void ClearFocusedElementTimerFired(TimerBase*);
bool HasNonEmptyFragment() const;
bool HaveScriptBlockingStylesheetsLoaded() const;
void SetHoverElement(Element*);
using EventFactorySet = HashSet<std::unique_ptr<EventFactoryBase>>;
static EventFactorySet& EventFactories();
void SetNthIndexCache(NthIndexCache* nth_index_cache) {
DCHECK(!nth_index_cache_ || !nth_index_cache);
nth_index_cache_ = nth_index_cache;
const OriginAccessEntry& AccessEntryFromURL();
void SendDidEditFieldInInsecureContext();
bool HaveImportsLoaded() const;
void UpdateActiveState(bool is_active, bool update_active_chain, Element*);
void UpdateHoverState(Element*);
const AtomicString& BodyAttributeValue(const QualifiedName&) const;
void SetBodyAttribute(const QualifiedName&, const AtomicString&);
const ParsedFeaturePolicy GetOwnerContainerPolicy() const;
const FeaturePolicy* GetParentFeaturePolicy() const;
// Returns true if use of |method_name| for markup insertion is allowed by
// feature policy; otherwise returns false and throws a DOM exception.
bool AllowedToUseDynamicMarkUpInsertion(const char* method_name,
void SetFreezingInProgress(bool is_freezing_in_progress) {
is_freezing_in_progress_ = is_freezing_in_progress;
void NotifyFocusedElementChanged(Element* old_focused_element,
Element* new_focused_element);
void DisplayNoneChangedForFrame();
IntersectionObserver& EnsureDisplayLockActivationObserver();
void ProcessDisplayLockActivationObservation(
const HeapVector<Member<IntersectionObserverEntry>>&);
DocumentLifecycle lifecycle_;
bool evaluate_media_queries_on_style_recalc_;
// If we do ignore the pending stylesheet count, then we need to add a boolean
// to track that this happened so that we can do a full repaint when the
// stylesheets do eventually load.
PendingSheetLayout pending_sheet_layout_;
Member<WindowAgentFactory> window_agent_factory_;
Member<LocalFrame> frame_;
Member<LocalDOMWindow> dom_window_;
Member<HTMLImportsController> imports_controller_;
// The document of creator browsing context for frame-less documents such as
// documents created by DOMParser and DOMImplementation.
WeakMember<Document> context_document_;
Member<ResourceFetcher> fetcher_;
Member<DocumentParser> parser_;
Member<ContextFeatures> context_features_;
Member<HttpRefreshScheduler> http_refresh_scheduler_;
bool well_formed_;
// When doing find-in-page and we need to calculate style & layout tree for
// invisible nodes, this variable will be set with the invisible root for
// the currently processed block in find-in-page.
WeakMember<Element> find_in_page_root_;
// Document URLs.
KURL url_; // Document.URL: The URL from which this document was retrieved.
KURL base_url_; // Node.baseURI: The URL to use when resolving relative URLs.
KURL base_url_override_; // An alternative base URL that takes precedence
// over base_url_ (but not base_element_url_).
KURL base_element_url_; // The URL set by the <base> element.
KURL cookie_url_; // The URL to use for cookie access.
std::unique_ptr<OriginAccessEntry> access_entry_from_url_;
AtomicString base_target_;
// Mime-type of the document in case it was cloned or created by XHR.
AtomicString mime_type_;
Member<DocumentType> doc_type_;
Member<DOMImplementation> implementation_;
Member<CSSStyleSheet> elem_sheet_;
PrintingState printing_;
bool is_painting_preview_;
CompatibilityMode compatibility_mode_;
// This is cheaper than making setCompatibilityMode virtual.
bool compatibility_mode_locked_;
TaskHandle execute_scripts_waiting_for_resources_task_handle_;
TaskHandle javascript_url_task_handle_;
struct PendingJavascriptUrl {
PendingJavascriptUrl(const KURL& input_url,
ContentSecurityPolicyDisposition input_disposition)
: url(input_url), disposition(input_disposition) {}
KURL url;
ContentSecurityPolicyDisposition disposition;
Vector<PendingJavascriptUrl> pending_javascript_urls_;
bool autofocus_processed_flag_ = false;
WebFocusType last_focus_type_;
bool had_keyboard_event_;
TaskRunnerTimer<Document> clear_focused_element_timer_;
// We implement this as a Vector because its maximum size is typically 1.
HeapVector<Member<Element>> autofocus_candidates_;
Member<Element> focused_element_;
Member<Range> sequential_focus_navigation_starting_point_;
Member<Element> hover_element_;
Member<Element> active_element_;
Member<Element> document_element_;
UserActionElementSet user_action_elements_;
Member<RootScrollerController> root_scroller_controller_;
uint64_t dom_tree_version_;
static uint64_t global_tree_version_;
uint64_t style_version_;
HeapHashSet<WeakMember<NodeIterator>> node_iterators_;
using AttachedRangeSet = HeapHashSet<WeakMember<Range>>;
AttachedRangeSet ranges_;
uint16_t listener_types_;
MutationObserverOptions mutation_observer_types_;
Member<StyleEngine> style_engine_;
Member<StyleSheetList> style_sheet_list_;
Member<FormController> form_controller_;
TextLinkColors text_link_colors_;
const Member<VisitedLinkState> visited_link_state_;
bool visually_ordered_;
using ElementComputedStyleMap =
HeapHashMap<WeakMember<Element>, Member<StylePropertyMapReadOnly>>;
ElementComputedStyleMap element_computed_style_map_;
DocumentReadyState ready_state_;
ParsingState parsing_state_;
bool is_dns_prefetch_enabled_;
bool have_explicitly_disabled_dns_prefetch_;
bool contains_plugins_;
unsigned ignore_destructive_write_count_;
unsigned throw_on_dynamic_markup_insertion_count_;
unsigned ignore_opens_during_unload_count_;
bool ignore_opens_and_writes_for_abort_ = false;
String title_;
String raw_title_;
Member<Element> title_element_;
Vector<AXContext*> ax_contexts_;
Member<AXObjectCache> ax_object_cache_;
Member<DocumentMarkerController> markers_;
bool update_focus_appearance_after_layout_ = false;
Member<Element> css_target_;
bool was_discarded_;
LoadEventProgress load_event_progress_;
bool is_freezing_in_progress_;
base::ElapsedTimer start_time_;
Member<ScriptRunner> script_runner_;
HeapVector<Member<ScriptElementBase>> current_script_stack_;
std::unique_ptr<TransformSource> transform_source_;
String xml_encoding_;
String xml_version_;
unsigned xml_standalone_ : 2;
unsigned has_xml_declaration_ : 1;
AtomicString content_language_;
DocumentEncodingData encoding_data_;
bool design_mode_;
bool is_running_exec_command_;
HeapHashSet<WeakMember<const LiveNodeListBase>>
LiveNodeListRegistry node_lists_;
Member<SVGDocumentExtensions> svg_extensions_;
Vector<AnnotatedRegionValue> annotated_regions_;
bool has_annotated_regions_;
bool annotated_regions_dirty_;
std::unique_ptr<SelectorQueryCache> selector_query_cache_;
// It is safe to keep a raw, untraced pointer to this stack-allocated
// cache object: it is set upon the cache object being allocated on
// the stack and cleared upon leaving its allocated scope. Hence it
// is acceptable not to trace it -- should a conservative GC occur,
// the cache object's references will be traced by a stack walk.
NthIndexCache* nth_index_cache_ = nullptr;
DocumentClassFlags document_classes_;
bool is_view_source_;
bool is_immersive_ar_overlay_;
bool saw_elements_in_known_namespaces_;
bool is_srcdoc_document_;
bool is_mobile_document_;
LayoutView* layout_view_;
// For early return in Fullscreen::fromIfExists()
bool has_fullscreen_supplement_;
// The last element in |top_layer_elements_| is topmost in the top layer
// stack and is thus the one that will be visually on top.
HeapVector<Member<Element>> top_layer_elements_;
int load_event_delay_count_;
TaskRunnerTimer<Document> load_event_delay_timer_;
TaskRunnerTimer<Document> plugin_loading_timer_;
DocumentTiming document_timing_;
Member<MediaQueryMatcher> media_query_matcher_;
bool write_recursion_is_too_deep_;
unsigned write_recursion_depth_;
Member<ScriptedAnimationController> scripted_animation_controller_;
bool current_frame_is_throttled_;
Member<ScriptedIdleTaskController> scripted_idle_task_controller_;
Member<TextAutosizer> text_autosizer_;
Member<V0CustomElementRegistrationContext> registration_context_;
Member<V0CustomElementMicrotaskRunQueue> custom_element_microtask_run_queue_;
void ElementDataCacheClearTimerFired(TimerBase*);
TaskRunnerTimer<Document> element_data_cache_clear_timer_;
Member<ElementDataCache> element_data_cache_;
using LocaleIdentifierToLocaleMap =
HashMap<AtomicString, std::unique_ptr<Locale>>;
LocaleIdentifierToLocaleMap locale_cache_;
Member<DocumentTimeline> timeline_;
Member<PendingAnimations> pending_animations_;
Member<WorkletAnimationController> worklet_animation_controller_;
Member<Document> template_document_;
Member<Document> template_document_host_;
TaskRunnerTimer<Document> did_associate_form_controls_timer_;
HeapHashSet<Member<SVGUseElement>> use_elements_needing_update_;
bool has_viewport_units_;
ParserSynchronizationPolicy parser_sync_policy_;
HostsUsingFeatures::Value hosts_using_features_value_;
Member<CanvasFontCache> canvas_font_cache_;
Member<IntersectionObserverController> intersection_observer_controller_;
Member<ResizeObserverController> resize_observer_controller_;
int node_count_;
// Temporary flag for some UseCounter items.
InDOMNodeRemovedHandlerState in_dom_node_removed_handler_state_ =
bool may_contain_v0_shadow_ = false;
Member<SnapCoordinator> snap_coordinator_;
Member<PropertyRegistry> property_registry_;
bool logged_field_edit_;
TaskHandle sensitive_input_edited_task_;
SecureContextState secure_context_state_;
Member<NetworkStateObserver> network_state_observer_;
std::unique_ptr<DocumentOutliveTimeReporter> document_outlive_time_reporter_;
// |ukm_recorder_| and |source_id_| will allow objects that are part of
// the document to record UKM.
std::unique_ptr<ukm::UkmRecorder> ukm_recorder_;
int64_t ukm_source_id_;
bool needs_to_record_ukm_outlive_time_;
// Tracks and reports UKM metrics of the number of attempted font family match
// attempts (both successful and not successful) by the page.
std::unique_ptr<FontMatchingMetrics> font_matching_metrics_;
unsigned slot_assignment_recalc_forbidden_recursion_depth_ = 0;
unsigned slot_assignment_recalc_depth_ = 0;
unsigned flat_tree_traversal_forbidden_recursion_depth_ = 0;
Member<DOMFeaturePolicy> policy_;
Member<SlotAssignmentEngine> slot_assignment_engine_;
// TODO(tkent): Should it be moved to LocalFrame or LocalFrameView?
Member<ViewportData> viewport_data_;
// This is set through feature policy 'vertical-scroll'.
bool is_vertical_scroll_enforced_ = false;
// The number of canvas elements on the document
int num_canvases_ = 0;
// Number of activation blocking display locks currently in this document.
int activation_blocking_display_lock_count_ = 0;
// Number of locked display locks in the document.
int locked_display_lock_count_ = 0;
bool deferred_compositor_commit_is_allowed_ = false;
// True when the document was created (in DomImplementation) for specific MIME
// types that are handled externally. The document in this case is the
// counterpart to a PluginDocument except that it contains a FrameView as
// opposed to a PluginView.
bool is_for_external_handler_ = false;
// Allow traversal of Shadow DOM V0 traversal with dirty distribution.
// Required for marking ancestors style-child-dirty for FlatTreeStyleRecalc.
bool allow_dirty_shadow_v0_traversal_ = false;
Member<NavigationInitiatorImpl> navigation_initiator_;
Member<LazyLoadImageObserver> lazy_load_image_observer_;
// Tracks which features have already been potentially violated in this
// document. This helps to count them only once per page load.
// We don't use std::bitset to avoid to include feature_policy.mojom-blink.h.
mutable Vector<bool> potentially_violated_features_;
// Pending parsed headers to send to browser after DidCommitNavigation
// IPC.
ParsedFeaturePolicy pending_parsed_headers_;
AtomicString override_last_modified_;
// Map from isolated world IDs to their ContentSecurityPolicy instances.
Member<HeapHashMap<int, Member<ContentSecurityPolicy>>>
// Used to keep track of which ComputedAccessibleNodes have already been
// instantiated in this document to avoid constructing duplicates.
HeapHashMap<AXID, Member<ComputedAccessibleNode>> computed_node_mapping_;
// When the document contains MimeHandlerView, this variable might hold a
// beforeunload handler. This will be set by the blink embedder when
// necessary.
// Used to communicate state associated with resource management to the
// embedder.
std::unique_ptr<DocumentResourceCoordinator> resource_coordinator_;
// Used for document.cookie. May be null.
std::unique_ptr<CookieJar> cookie_jar_;
// A dummy scheduler to return when the document is detached.
// All operations on it result in no-op, but due to this it's safe to
// use the returned value of GetScheduler() without additional checks.
// A task posted to a task runner obtained from one of its task runners
// will be forwarded to the default task runner.
// TODO(altimin): We should be able to remove it after we complete
// frame:document lifetime refactoring.
std::unique_ptr<FrameOrWorkerScheduler> detached_scheduler_;
bool toggle_during_parsing_ = false;
bool is_for_markup_sanitization_ = false;
String fragment_directive_;
bool use_count_fragment_directive_ = false;
HeapHashMap<WeakMember<Element>, Member<ExplicitlySetAttrElementsMap>>
Member<IntersectionObserver> display_lock_activation_observer_;
extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Document>;
inline void Document::ScheduleLayoutTreeUpdateIfNeeded() {
// Inline early out to avoid the function calls below.
if (HasPendingVisualUpdate())
if (ShouldScheduleLayoutTreeUpdate() && NeedsLayoutTreeUpdate())
DEFINE_TYPE_CASTS(thisType, Document, document, document->Is##thisType(), \
// This is needed to avoid ambiguous overloads with the Node and TreeScope
// versions.
// Put these methods here, because they require the Document definition, but we
// really want to inline them.
inline bool Node::IsDocumentNode() const {
return this == GetDocument();
Node* EventTargetNodeForDocument(Document*);
template <>
struct DowncastTraits<Document> {
static bool AllowFrom(const ExecutionContext& context) {
return context.IsDocument();
static bool AllowFrom(const Node& node) { return node.IsDocumentNode(); }
} // namespace blink
#ifndef NDEBUG
// Outside the blink namespace for ease of invocation from gdb.
CORE_EXPORT void showLiveDocumentInstances();