/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
 * 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.
 * (http://www.torchmobile.com/)
 * 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
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * 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.
 *
 */

#ifndef Document_h
#define Document_h

#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "bindings/core/v8/ScriptValue.h"
#include "core/CoreExport.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/DocumentEncodingData.h"
#include "core/dom/DocumentInit.h"
#include "core/dom/DocumentLifecycle.h"
#include "core/dom/DocumentTiming.h"
#include "core/dom/ExecutionContext.h"
#include "core/dom/MutationObserver.h"
#include "core/dom/TextLinkColors.h"
#include "core/dom/TreeScope.h"
#include "core/dom/UserActionElementSet.h"
#include "core/dom/ViewportDescription.h"
#include "core/dom/custom/V0CustomElement.h"
#include "core/fetch/ClientHintsPreferences.h"
#include "core/frame/DOMTimerCoordinator.h"
#include "core/frame/HostsUsingFeatures.h"
#include "core/html/parser/ParserSynchronizationPolicy.h"
#include "core/page/PageVisibilityState.h"
#include "platform/Length.h"
#include "platform/Timer.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/ReferrerPolicy.h"
#include "public/platform/WebFocusType.h"
#include "public/platform/WebInsecureRequestPolicy.h"
#include "wtf/HashSet.h"
#include "wtf/PassRefPtr.h"
#include <memory>

namespace blink {

class AnimationClock;
class DocumentTimeline;
class AXObjectCache;
class Attr;
class CDATASection;
class CSSStyleDeclaration;
class CSSStyleSheet;
class CancellableTaskFactory;
class CanvasFontCache;
class CanvasRenderingContext2D;
class CanvasRenderingContext2DOrWebGLRenderingContext;
class CharacterData;
class ChromeClient;
class CompositorPendingAnimations;
class Comment;
class ConsoleMessage;
class ContextFeatures;
class V0CustomElementMicrotaskRunQueue;
class V0CustomElementRegistrationContext;
class DOMImplementation;
class DOMWindow;
class DocumentFragment;
class DocumentLoader;
class DocumentMarkerController;
class DocumentNameCollection;
class DocumentParser;
class DocumentState;
class DocumentType;
class Element;
class ElementDataCache;
class ElementRegistrationOptions;
class Event;
class EventFactoryBase;
class EventListener;
template <typename EventType>
class EventWithHitTestResults;
class ExceptionState;
class FloatQuad;
class FloatRect;
class FormController;
class Frame;
class FrameHost;
class FrameRequestCallback;
class FrameView;
class HTMLAllCollection;
class HTMLBodyElement;
class HTMLCanvasElement;
class HTMLCollection;
class HTMLDialogElement;
class HTMLElement;
class HTMLFrameOwnerElement;
class HTMLHeadElement;
class HTMLImportLoader;
class HTMLImportsController;
class HTMLLinkElement;
class HTMLScriptElementOrSVGScriptElement;
class HitTestRequest;
class IdleRequestCallback;
class IdleRequestOptions;
class InputDeviceCapabilities;
class IntersectionObserverController;
class LayoutPoint;
class LayoutView;
class LayoutViewItem;
class LiveNodeListBase;
class LocalDOMWindow;
class Locale;
class LocalFrame;
class Location;
class MainThreadTaskRunner;
class MediaQueryListListener;
class MediaQueryMatcher;
class NodeFilter;
class NodeIntersectionObserverData;
class NodeIterator;
class NthIndexCache;
class OriginAccessEntry;
class Page;
class PlatformMouseEvent;
class ProcessingInstruction;
class PropertyRegistry;
class QualifiedName;
class Range;
class ResizeObserverController;
class ResourceFetcher;
class RootScrollerController;
class SVGDocumentExtensions;
class SVGUseElement;
class ScriptRunner;
class ScriptableDocumentParser;
class ScriptedAnimationController;
class ScriptedIdleTaskController;
class ScrollStateCallback;
class SecurityOrigin;
class SegmentedString;
class SelectorQueryCache;
class SerializedScriptValue;
class Settings;
class SnapCoordinator;
class StyleEngine;
class StyleResolver;
class StyleSheet;
class StyleSheetList;
class Text;
class TextAutosizer;
class Touch;
class TouchList;
class TransformSource;
class TreeWalker;
class VisitedLinkState;
class VisualViewport;
class WebGLRenderingContext;
enum class SelectionBehaviorOnFocus;
struct AnnotatedRegionValue;
struct FocusParams;
struct IconURL;

using MouseEventWithHitTestResults =
    EventWithHitTestResults<PlatformMouseEvent>;
using ExceptionCode = int;

enum StyleResolverUpdateMode {
  // Discards the StyleResolver and rebuilds it.
  FullStyleUpdate,
  // Attempts to use StyleInvalidationAnalysis to avoid discarding the entire
  // StyleResolver.
  AnalyzedStyleUpdate
};

enum NodeListInvalidationType {
  DoNotInvalidateOnAttributeChanges = 0,
  InvalidateOnClassAttrChange,
  InvalidateOnIdNameAttrChange,
  InvalidateOnNameAttrChange,
  InvalidateOnForAttrChange,
  InvalidateForFormControls,
  InvalidateOnHRefAttrChange,
  InvalidateOnAnyAttrChange,
};
const int numNodeListInvalidationTypes = InvalidateOnAnyAttrChange + 1;

enum DocumentClass {
  DefaultDocumentClass = 0,
  HTMLDocumentClass = 1,
  XHTMLDocumentClass = 1 << 1,
  ImageDocumentClass = 1 << 2,
  PluginDocumentClass = 1 << 3,
  MediaDocumentClass = 1 << 4,
  SVGDocumentClass = 1 << 5,
  XMLDocumentClass = 1 << 6,
};

enum ShadowCascadeOrder { ShadowCascadeNone, ShadowCascadeV0, ShadowCascadeV1 };

enum CreateElementFlags {
  CreatedByParser = 1 << 0,
  // Synchronous custom elements flag:
  // https://dom.spec.whatwg.org/#concept-create-element
  // TODO(kojii): Remove these flags, add an option not to queue upgrade, and
  // let parser/DOM methods to upgrade synchronously when necessary.
  SynchronousCustomElements = 0 << 1,
  AsynchronousCustomElements = 1 << 1,

  // Aliases by callers.
  // Clone a node: https://dom.spec.whatwg.org/#concept-node-clone
  CreatedByCloneNode = AsynchronousCustomElements,
  CreatedByImportNode = CreatedByCloneNode,
  // https://dom.spec.whatwg.org/#dom-document-createelement
  CreatedByCreateElement = SynchronousCustomElements,
  // https://html.spec.whatwg.org/#create-an-element-for-the-token
  CreatedByFragmentParser = CreatedByParser | AsynchronousCustomElements,
};

using DocumentClassFlags = unsigned char;

class CORE_EXPORT Document : public ContainerNode,
                             public TreeScope,
                             public SecurityContext,
                             public ExecutionContext,
                             public Supplementable<Document> {
  DEFINE_WRAPPERTYPEINFO();
  USING_GARBAGE_COLLECTED_MIXIN(Document);

 public:
  static Document* create(const DocumentInit& initializer = DocumentInit()) {
    return new Document(initializer);
  }
  ~Document() override;

  MediaQueryMatcher& mediaQueryMatcher();

  void mediaQueryAffectingValueChanged();

  using SecurityContext::getSecurityOrigin;
  using SecurityContext::contentSecurityPolicy;
  using TreeScope::getElementById;

  bool canContainRangeEndPoint() const override { return true; }

  SelectorQueryCache& selectorQueryCache();

  // Focus Management.
  Element* activeElement() const;
  bool hasFocus() const;

  // DOM methods & attributes for Document

  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(selectionchange);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);

  bool shouldMergeWithLegacyDescription(ViewportDescription::Type) const;
  bool shouldOverrideLegacyDescription(ViewportDescription::Type) const;
  void setViewportDescription(const ViewportDescription&);
  ViewportDescription viewportDescription() const;
  Length viewportDefaultMinWidth() const { return m_viewportDefaultMinWidth; }

  String outgoingReferrer() const override;
  ReferrerPolicy getReferrerPolicy() const override;

  void setDoctype(DocumentType*);
  DocumentType* doctype() const { return m_docType.get(); }

  DOMImplementation& implementation();

  Element* documentElement() const { return m_documentElement.get(); }

  // Returns whether the Document has an AppCache manifest.
  bool hasAppCacheManifest() const;

  Location* location() const;

  Element* createElement(const AtomicString& name, ExceptionState&);
  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,
                                                     ExceptionState&);
  Attr* createAttribute(const AtomicString& name, ExceptionState&);
  Attr* createAttributeNS(const AtomicString& namespaceURI,
                          const AtomicString& qualifiedName,
                          ExceptionState&,
                          bool shouldIgnoreNamespaceChecks = false);
  Node* importNode(Node* importedNode, bool deep, ExceptionState&);
  Element* createElementNS(const AtomicString& namespaceURI,
                           const AtomicString& qualifiedName,
                           ExceptionState&);
  Element* createElement(const QualifiedName&, CreateElementFlags);

  Element* elementFromPoint(int x, int y) const;
  HeapVector<Member<Element>> elementsFromPoint(int x, int y) const;
  Range* caretRangeFromPoint(int x, int y);
  Element* scrollingElement();

  void addNonAttachedStyle(Element&, RefPtr<ComputedStyle>);
  ComputedStyle* getNonAttachedStyle(Element&);

  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 m_contentLanguage; }
  void setContentLanguage(const AtomicString&);

  String xmlEncoding() const { return m_xmlEncoding; }
  String xmlVersion() const { return m_xmlVersion; }
  enum StandaloneStatus { StandaloneUnspecified, Standalone, NotStandalone };
  bool xmlStandalone() const { return m_xmlStandalone == Standalone; }
  StandaloneStatus xmlStandaloneStatus() const {
    return static_cast<StandaloneStatus>(m_xmlStandalone);
  }
  bool hasXMLDeclaration() const { return m_hasXMLDeclaration; }

  void setXMLEncoding(const String& encoding) {
    m_xmlEncoding = encoding;
  }  // read-only property, only to be set from XMLDocumentParser
  void setXMLVersion(const String&, ExceptionState&);
  void setXMLStandalone(bool, ExceptionState&);
  void setHasXMLDeclaration(bool hasXMLDeclaration) {
    m_hasXMLDeclaration = hasXMLDeclaration ? 1 : 0;
  }

  String origin() const { return getSecurityOrigin()->toString(); }
  String suborigin() const {
    return getSecurityOrigin()->hasSuborigin()
               ? getSecurityOrigin()->suborigin()->name()
               : String();
  }

  String visibilityState() const;
  PageVisibilityState pageVisibilityState() const;
  bool hidden() const;
  void didChangeVisibilityState();

  // 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* allForBinding();
  HTMLAllCollection* all();

  HTMLCollection* windowNamedItems(const AtomicString& name);
  DocumentNameCollection* documentNamedItems(const AtomicString& name);

  bool isHTMLDocument() const { return m_documentClasses & HTMLDocumentClass; }
  bool isXHTMLDocument() const {
    return m_documentClasses & XHTMLDocumentClass;
  }
  bool isXMLDocument() const { return m_documentClasses & XMLDocumentClass; }
  bool isImageDocument() const {
    return m_documentClasses & ImageDocumentClass;
  }
  bool isSVGDocument() const { return m_documentClasses & SVGDocumentClass; }
  bool isPluginDocument() const {
    return m_documentClasses & PluginDocumentClass;
  }
  bool isMediaDocument() const {
    return m_documentClasses & MediaDocumentClass;
  }

  bool hasSVGRootNode() const;

  bool isFrameSet() const;

  bool isSrcdocDocument() const { return m_isSrcdocDocument; }
  bool isMobileDocument() const { return m_isMobileDocument; }

  StyleResolver* styleResolver() const;
  StyleResolver& ensureStyleResolver() const;

  bool isViewSource() const { return m_isViewSource; }
  void setIsViewSource(bool);

  bool sawElementsInKnownNamespaces() const {
    return m_sawElementsInKnownNamespaces;
  }

  bool isRenderingReady() const {
    return haveImportsLoaded() && haveRenderBlockingStylesheetsLoaded();
  }
  bool isScriptExecutionReady() const {
    return haveImportsLoaded() && haveScriptBlockingStylesheetsLoaded();
  }

  // This is a DOM function.
  StyleSheetList& styleSheets();

  StyleEngine& styleEngine() {
    DCHECK(m_styleEngine.get());
    return *m_styleEngine.get();
  }

  bool gotoAnchorNeededAfterStylesheetsLoad() {
    return m_gotoAnchorNeededAfterStylesheetsLoad;
  }
  void setGotoAnchorNeededAfterStylesheetsLoad(bool b) {
    m_gotoAnchorNeededAfterStylesheetsLoad = b;
  }

  void scheduleUseShadowTreeUpdate(SVGUseElement&);
  void unscheduleUseShadowTreeUpdate(SVGUseElement&);

  // FIXME: SVG filters should change to store the filter on the ComputedStyle
  // instead of the LayoutObject so we can get rid of this hack.
  void scheduleSVGFilterLayerUpdateHack(Element&);
  void unscheduleSVGFilterLayerUpdateHack(Element&);

  void evaluateMediaQueryList();

  FormController& formController();
  DocumentState* formElementsState() const;
  void setStateForNewFormElements(const Vector<String>&);

  FrameView* view() const;                       // can be null
  LocalFrame* frame() const { return m_frame; }  // can be null
  FrameHost* frameHost() const;                  // can be null
  Page* page() const;                            // can be null
  Settings* settings() const;                    // can be null

  float devicePixelRatio() const;

  Range* createRange();

  NodeIterator* createNodeIterator(Node* root,
                                   unsigned whatToShow,
                                   NodeFilter*);
  TreeWalker* createTreeWalker(Node* root, unsigned whatToShow, NodeFilter*);

  // Special support for editing
  Text* createEditingTextNode(const String&);

  void setupFontBuilder(ComputedStyle& documentStyle);

  bool needsLayoutTreeUpdate() const;
  bool needsLayoutTreeUpdateForNode(const Node&) const;
  // Update ComputedStyles and attach LayoutObjects if necessary, but don't
  // lay out.
  void updateStyleAndLayoutTree();
  // Same as updateStyleAndLayoutTree() except ignoring pending stylesheets.
  void updateStyleAndLayoutTreeIgnorePendingStylesheets();
  void updateStyleAndLayoutTreeForNode(const Node*);
  void updateStyleAndLayout();
  void layoutUpdated();
  enum RunPostLayoutTasks {
    RunPostLayoutTasksAsyhnchronously,
    RunPostLayoutTasksSynchronously,
  };
  void updateStyleAndLayoutIgnorePendingStylesheets(
      RunPostLayoutTasks = RunPostLayoutTasksAsyhnchronously);
  void updateStyleAndLayoutIgnorePendingStylesheetsForNode(Node*);
  PassRefPtr<ComputedStyle> styleForElementIgnoringPendingStylesheets(Element*);
  PassRefPtr<ComputedStyle> styleForPage(int pageIndex);

  // Returns true if page box (margin boxes and page borders) is visible.
  bool isPageBoxVisible(int pageIndex);

  // 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 pageIndex,
                                  DoubleSize& pageSize,
                                  int& marginTop,
                                  int& marginRight,
                                  int& marginBottom,
                                  int& marginLeft);

  ResourceFetcher* fetcher() const { return m_fetcher.get(); }

  void initialize();
  virtual void shutdown();

  void attachLayoutTree(const AttachContext& = AttachContext()) override {
    NOTREACHED();
  }
  void detachLayoutTree(const AttachContext& = AttachContext()) override {
    NOTREACHED();
  }

  // If you have a Document, use layoutView() instead which is faster.
  void layoutObject() const = delete;

  LayoutView* layoutView() const { return m_layoutView; }
  LayoutViewItem layoutViewItem() const;

  Document& axObjectCacheOwner() const;
  AXObjectCache* existingAXObjectCache() const;
  AXObjectCache* axObjectCache() const;
  void clearAXObjectCache();

  // to get visually ordered hebrew and arabic pages right
  bool visuallyOrdered() const { return m_visuallyOrdered; }

  DocumentLoader* loader() const;

  // This is the DOM API document.open(). enteredDocument is the responsible
  // document of the entry settings object.
  void open(Document* enteredDocument, ExceptionState&);
  // This is used internally and does not handle exceptions.
  void open();
  DocumentParser* implicitOpen(ParserSynchronizationPolicy);

  // This is the DOM API document.close()
  void close(ExceptionState&);
  // This is used internally and does not handle exceptions.
  void close();
  // implicitClose() actually does the work of closing the input stream.
  void implicitClose();

  bool dispatchBeforeUnloadEvent(ChromeClient&,
                                 bool isReload,
                                 bool& didAllowNavigation);
  void dispatchUnloadEvents();

  enum PageDismissalType {
    NoDismissal,
    BeforeUnloadDismissal,
    PageHideDismissal,
    UnloadVisibilityChangeDismissal,
    UnloadDismissal
  };
  PageDismissalType pageDismissalEventBeingDispatched() const;

  void cancelParsing();

  void write(const SegmentedString& text,
             Document* enteredDocument = nullptr,
             ExceptionState& = ASSERT_NO_EXCEPTION);
  void write(const String& text,
             Document* enteredDocument = nullptr,
             ExceptionState& = ASSERT_NO_EXCEPTION);
  void writeln(const String& text,
               Document* enteredDocument = nullptr,
               ExceptionState& = ASSERT_NO_EXCEPTION);
  void write(LocalDOMWindow*, const Vector<String>& text, ExceptionState&);
  void writeln(LocalDOMWindow*, const Vector<String>& text, ExceptionState&);

  bool wellFormed() const { return m_wellFormed; }

  const KURL& url() const { return m_url; }
  void setURL(const KURL&);

  // To understand how these concepts relate to one another, please see the
  // comments surrounding their declaration.
  const KURL& baseURL() const { return m_baseURL; }
  void setBaseURLOverride(const KURL&);
  const KURL& baseURLOverride() const { return m_baseURLOverride; }
  KURL validBaseElementURL() const;
  const AtomicString& baseTarget() const { return m_baseTarget; }
  void processBaseElement();

  // 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;
  // Creates URL based on passed relative url and passed base URL override.
  // Depending on baseURLOverride value it is possible that parent document
  // base URL will be used instead of it. See baseURLForOverride function
  // for details.
  KURL completeURLWithOverride(const String&,
                               const KURL& baseURLOverride) const;
  // Determines which base URL should be used given specified override.
  // If override is empty or is about:blank url and parent document exists
  // base URL of parent will be returned, passed base URL override otherwise.
  const KURL& baseURLForOverride(const KURL& baseURLOverride) const;

  String userAgent() const final;
  void disableEval(const String& errorMessage) final;

  CSSStyleSheet& elementSheet();

  virtual DocumentParser* createParser();
  DocumentParser* parser() const { return m_parser.get(); }
  ScriptableDocumentParser* scriptableDocumentParser() const;

  bool printing() const { return m_printing; }
  void setPrinting(bool isPrinting) { m_printing = isPrinting; }
  bool wasPrinting() const { return m_wasPrinting; }

  bool paginatedForScreen() const { return m_paginatedForScreen; }
  void setPaginatedForScreen(bool p) { m_paginatedForScreen = p; }

  bool paginated() const { return printing() || paginatedForScreen(); }

  enum CompatibilityMode { QuirksMode, LimitedQuirksMode, NoQuirksMode };

  void setCompatibilityMode(CompatibilityMode);
  CompatibilityMode getCompatibilityMode() const { return m_compatibilityMode; }

  String compatMode() const;

  bool inQuirksMode() const { return m_compatibilityMode == QuirksMode; }
  bool inLimitedQuirksMode() const {
    return m_compatibilityMode == LimitedQuirksMode;
  }
  bool inNoQuirksMode() const { return m_compatibilityMode == NoQuirksMode; }

  enum ReadyState { Loading, Interactive, Complete };
  void setReadyState(ReadyState);
  bool isLoadCompleted();

  enum ParsingState { Parsing, InDOMContentLoaded, FinishedParsing };
  void setParsingState(ParsingState);
  bool parsing() const { return m_parsingState == Parsing; }
  bool isInDOMContentLoaded() const {
    return m_parsingState == InDOMContentLoaded;
  }
  bool hasFinishedParsing() const { return m_parsingState == FinishedParsing; }

  bool shouldScheduleLayout() const;
  int elapsedTime() const;

  TextLinkColors& textLinkColors() { return m_textLinkColors; }
  VisitedLinkState& visitedLinkState() const { return *m_visitedLinkState; }

  MouseEventWithHitTestResults performMouseEventHitTest(
      const HitTestRequest&,
      const LayoutPoint&,
      const PlatformMouseEvent&);

  /* Newly proposed CSS3 mechanism for selecting alternate
       stylesheets using the DOM. May be subject to change as
       spec matures. - dwh
    */
  String preferredStylesheetSet() const;
  String selectedStylesheetSet() const;
  void setSelectedStylesheetSet(const String&);

  bool setFocusedElement(Element*, const FocusParams&);
  void clearFocusedElement();
  Element* focusedElement() const { return m_focusedElement.get(); }
  UserActionElementSet& userActionElements() { return m_userActionElements; }
  const UserActionElementSet& userActionElements() const {
    return m_userActionElements;
  }
  void setNeedsFocusedElementCheck();
  void setAutofocusElement(Element*);
  Element* autofocusElement() const { return m_autofocusElement.get(); }
  void setSequentialFocusNavigationStartingPoint(Node*);
  Element* sequentialFocusNavigationStartingPoint(WebFocusType) const;

  void setActiveHoverElement(Element*);
  Element* activeHoverElement() const { return m_activeHoverElement.get(); }

  Node* hoverNode() const { return m_hoverNode.get(); }

  void removeFocusedElementOfSubtree(Node*, bool amongChildrenOnly = false);
  void hoveredNodeDetached(Element&);
  void activeChainNodeDetached(Element&);

  void updateHoverActiveState(const HitTestRequest&, Element*);

  // Updates for :target (CSS3 selector).
  void setCSSTarget(Element*);
  Element* cssTarget() const { return m_cssTarget; }

  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* attrName = nullptr) const;
  void invalidateNodeListCaches(const QualifiedName* attrName);

  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&);
  // Called just before a destructive update to some CharacterData.
  void dataWillChange(const CharacterData&);
  bool canAcceptChild(const Node& newChild,
                      const Node* oldChild,
                      ExceptionState&) const;

  void didInsertText(Node*, unsigned offset, unsigned length);
  void didRemoveText(Node*, unsigned offset, unsigned length);
  void didMergeTextNodes(Text& oldNode, unsigned offset);
  void didSplitTextNode(Text& oldNode);

  void clearDOMWindow() { m_domWindow = nullptr; }
  LocalDOMWindow* domWindow() const { return m_domWindow; }

  // Helper functions for forwarding LocalDOMWindow event related tasks to the
  // LocalDOMWindow if it exists.
  void setWindowAttributeEventListener(const AtomicString& eventType,
                                       EventListener*);
  EventListener* getWindowAttributeEventListener(const AtomicString& eventType);

  static void registerEventFactory(std::unique_ptr<EventFactoryBase>);
  static Event* createEvent(ExecutionContext*,
                            const String& eventType,
                            ExceptionState&);

  // keep track of what types of event listeners are registered, so we don't
  // dispatch events unnecessarily
  enum ListenerType {
    DOMSUBTREEMODIFIED_LISTENER = 1,
    DOMNODEINSERTED_LISTENER = 1 << 1,
    DOMNODEREMOVED_LISTENER = 1 << 2,
    DOMNODEREMOVEDFROMDOCUMENT_LISTENER = 1 << 3,
    DOMNODEINSERTEDINTODOCUMENT_LISTENER = 1 << 4,
    DOMCHARACTERDATAMODIFIED_LISTENER = 1 << 5,
    ANIMATIONEND_LISTENER = 1 << 6,
    ANIMATIONSTART_LISTENER = 1 << 7,
    ANIMATIONITERATION_LISTENER = 1 << 8,
    TRANSITIONEND_LISTENER = 1 << 9,
    SCROLL_LISTENER = 1 << 10
    // 5 bits remaining
  };

  bool hasListenerType(ListenerType listenerType) const {
    return (m_listenerTypes & listenerType);
  }
  void addListenerTypeIfNeeded(const AtomicString& eventType);

  bool hasMutationObserversOfType(MutationObserver::MutationType type) const {
    return m_mutationObserverTypes & type;
  }
  bool hasMutationObservers() const { return m_mutationObserverTypes; }
  void addMutationObserverTypes(MutationObserverOptions types) {
    m_mutationObserverTypes |= types;
  }

  IntersectionObserverController* intersectionObserverController();
  IntersectionObserverController& ensureIntersectionObserverController();
  NodeIntersectionObserverData& ensureIntersectionObserverData();

  ResizeObserverController* resizeObserverController() const {
    return m_resizeObserverController;
  }
  ResizeObserverController& ensureResizeObserverController();

  void updateViewportDescription();

  // 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;

  // Returns true if this document belongs to a frame that the parent document
  // made invisible (for instance by setting as style display:none).
  bool isInInvisibleSubframe() const;

  String title() const { return m_title; }
  void setTitle(const String&);

  Element* titleElement() const { return m_titleElement.get(); }
  void setTitleElement(Element*);
  void removeTitle(Element* titleElement);

  const AtomicString& dir();
  void setDir(const AtomicString&);

  String cookie(ExceptionState&) const;
  void setCookie(const String&, ExceptionState&);

  const AtomicString& referrer() const;

  String domain() const;
  void setDomain(const String& newDomain, ExceptionState&);

  String lastModified() const;

  // The cookieURL is used to query the cookie database for this document's
  // cookies. For example, if the cookie URL is http://example.com, we'll
  // use the non-Secure cookies for example.com 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 m_cookieURL; }
  void setCookieURL(const KURL& url) { m_cookieURL = url; }

  const KURL firstPartyForCookies() 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& qualifiedName,
                                 AtomicString& prefix,
                                 AtomicString& localName,
                                 ExceptionState&);

  // 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
  // (https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2).
  // That is, the first body or frameset child of the document element.
  HTMLElement* body() const;

  // "HTML body element" as defined by CSSOM View spec
  // (http://dev.w3.org/csswg/cssom-view/#the-html-body-element).
  // 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. If
  // |rootStyle| is set, use that as the style for the root element, rather than
  // obtaining it on our own. The reason for this is that style may not have
  // been associated with the elements yet - in which case it may have been
  // calculated on the fly (without associating it with the actual element)
  // somewhere.
  Element* viewportDefiningElement(
      const ComputedStyle* rootStyle = nullptr) const;

  DocumentMarkerController& markers() const { return *m_markers; }

  bool execCommand(const String& command,
                   bool showUI,
                   const String& value,
                   ExceptionState&);
  bool isRunningExecCommand() const { return m_isRunningExecCommand; }
  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 m_designMode; }
  String designMode() const;
  void setDesignMode(const String&);

  Document* parentDocument() const;
  Document& topDocument() const;
  Document* contextDocument();

  ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }

  Element* currentScript() const {
    return !m_currentScriptStack.isEmpty() ? m_currentScriptStack.last().get()
                                           : nullptr;
  }
  void currentScriptForBinding(HTMLScriptElementOrSVGScriptElement&) const;
  void pushCurrentScript(Element*);
  void popCurrentScript();

  void setTransformSource(std::unique_ptr<TransformSource>);
  TransformSource* transformSource() const { return m_transformSource.get(); }

  void incDOMTreeVersion() {
    DCHECK(m_lifecycle.stateAllowsTreeMutations());
    m_domTreeVersion = ++s_globalTreeVersion;
  }
  uint64_t domTreeVersion() const { return m_domTreeVersion; }

  uint64_t styleVersion() const { return m_styleVersion; }

  enum PendingSheetLayout {
    NoLayoutWithPendingSheets,
    DidLayoutWithPendingSheets,
    IgnoreLayoutWithPendingSheets
  };

  bool didLayoutWithPendingStylesheets() const {
    return m_pendingSheetLayout == DidLayoutWithPendingSheets;
  }
  bool ignoreLayoutWithPendingStylesheets() const {
    return m_pendingSheetLayout == IgnoreLayoutWithPendingSheets;
  }

  bool hasNodesWithPlaceholderStyle() const {
    return m_hasNodesWithPlaceholderStyle;
  }
  void setHasNodesWithPlaceholderStyle() {
    m_hasNodesWithPlaceholderStyle = true;
  }

  Vector<IconURL> iconURLs(int iconTypesMask);

  Color themeColor() const;

  // Returns the HTMLLinkElement currently in use for the Web Manifest.
  // Returns null if there is no such element.
  HTMLLinkElement* linkManifest() const;

  void setUseSecureKeyboardEntryWhenActive(bool);
  bool useSecureKeyboardEntryWhenActive() const;

  void updateFocusAppearanceSoon(SelectionBehaviorOnFocus);
  void cancelFocusAppearanceUpdate();

  bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
  void parseDNSPrefetchControlHeader(const String&);

  // FIXME(crbug.com/305497): This should be removed once LocalDOMWindow is an
  // ExecutionContext.
  void postTask(const WebTraceLocation&,
                std::unique_ptr<ExecutionContextTask>,
                const String& taskNameForInstrumentation = emptyString())
      override;  // Executes the task on context's thread asynchronously.
  void postInspectorTask(const WebTraceLocation&,
                         std::unique_ptr<ExecutionContextTask>);

  void tasksWereSuspended() final;
  void tasksWereResumed() final;
  void suspendScheduledTasks() final;
  void resumeScheduledTasks() final;
  bool tasksNeedSuspension() final;

  void finishedParsing();

  void setEncodingData(const DocumentEncodingData& newData);
  const WTF::TextEncoding& encoding() const {
    return m_encodingData.encoding();
  }

  bool encodingWasDetectedHeuristically() const {
    return m_encodingData.wasDetectedHeuristically();
  }
  bool sawDecodingError() const { return m_encodingData.sawDecodingError(); }

  void setAnnotatedRegionsDirty(bool f) { m_annotatedRegionsDirty = f; }
  bool annotatedRegionsDirty() const { return m_annotatedRegionsDirty; }
  bool hasAnnotatedRegions() const { return m_hasAnnotatedRegions; }
  void setHasAnnotatedRegions(bool f) { m_hasAnnotatedRegions = f; }
  const Vector<AnnotatedRegionValue>& annotatedRegions() const;
  void setAnnotatedRegions(const Vector<AnnotatedRegionValue>&);

  void removeAllEventListeners() final;

  const SVGDocumentExtensions* svgExtensions();
  SVGDocumentExtensions& accessSVGExtensions();

  void initContentSecurityPolicy(ContentSecurityPolicy* = nullptr);

  bool isSecureTransitionTo(const KURL&) const;

  bool allowInlineEventHandler(Node*,
                               EventListener*,
                               const String& contextURL,
                               const WTF::OrdinalNumber& contextLine);
  bool allowExecutingScripts(Node*);

  void enforceSandboxFlags(SandboxFlags mask) override;

  void statePopped(PassRefPtr<SerializedScriptValue>);

  enum LoadEventProgress {
    LoadEventNotRun,
    LoadEventInProgress,
    LoadEventCompleted,
    BeforeUnloadEventInProgress,
    BeforeUnloadEventCompleted,
    PageHideInProgress,
    UnloadVisibilityChangeInProgress,
    UnloadEventInProgress,
    UnloadEventHandled
  };
  bool loadEventStillNeeded() const {
    return m_loadEventProgress == LoadEventNotRun;
  }
  bool processingLoadEvent() const {
    return m_loadEventProgress == LoadEventInProgress;
  }
  bool loadEventFinished() const {
    return m_loadEventProgress >= LoadEventCompleted;
  }
  bool unloadStarted() const {
    return m_loadEventProgress >= PageHideInProgress;
  }
  bool processingBeforeUnload() const {
    return m_loadEventProgress == BeforeUnloadEventInProgress;
  }
  void suppressLoadEvent();

  void setContainsPlugins() { m_containsPlugins = true; }
  bool containsPlugins() const { return m_containsPlugins; }

  bool isContextThread() const final;
  bool isJSExecutionForbidden() const final { return false; }

  bool containsValidityStyleRules() const {
    return m_containsValidityStyleRules;
  }
  void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }

  void enqueueResizeEvent();
  void enqueueScrollEventForNode(Node*);
  void enqueueAnimationFrameEvent(Event*);
  // Only one event for a target/event type combination will be dispatched per
  // frame.
  void enqueueUniqueAnimationFrameEvent(Event*);
  void enqueueMediaQueryChangeListeners(
      HeapVector<Member<MediaQueryListListener>>&);
  void enqueueVisualViewportScrollEvent();
  void enqueueVisualViewportResizeEvent();

  void dispatchEventsForPrinting();

  bool hasFullscreenSupplement() const { return m_hasFullscreenSupplement; }
  void setHasFullscreenSupplement() { m_hasFullscreenSupplement = 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() { ++m_loadEventDelayCount; }
  void decrementLoadEventDelayCount();
  void checkLoadEventSoon();
  bool isDelayingLoadEvent();
  void loadPluginsSoon();

  Touch* createTouch(DOMWindow*,
                     EventTarget*,
                     int identifier,
                     double pageX,
                     double pageY,
                     double screenX,
                     double screenY,
                     double radiusX,
                     double radiusY,
                     float rotationAngle,
                     float force) const;
  TouchList* createTouchList(HeapVector<Member<Touch>>&) const;

  const DocumentTiming& timing() const { return m_documentTiming; }

  int requestAnimationFrame(FrameRequestCallback*);
  void cancelAnimationFrame(int id);
  void serviceScriptedAnimations(double monotonicAnimationStartTime);

  int requestIdleCallback(IdleRequestCallback*, const IdleRequestOptions&);
  void cancelIdleCallback(int id);

  EventTarget* errorEventTarget() final;
  void exceptionThrown(ErrorEvent*) final;

  void initDNSPrefetch();

  bool isInDocumentWrite() const { return m_writeRecursionDepth > 0; }

  TextAutosizer* textAutosizer();

  Element* createElement(const AtomicString& localName,
                         const AtomicString& typeExtension,
                         ExceptionState&);
  Element* createElementNS(const AtomicString& namespaceURI,
                           const AtomicString& qualifiedName,
                           const AtomicString& typeExtension,
                           ExceptionState&);
  ScriptValue registerElement(
      ScriptState*,
      const AtomicString& name,
      const ElementRegistrationOptions&,
      ExceptionState&,
      V0CustomElement::NameSet validNames = V0CustomElement::StandardNames);
  V0CustomElementRegistrationContext* registrationContext() {
    return m_registrationContext.get();
  }
  V0CustomElementMicrotaskRunQueue* customElementMicrotaskRunQueue();

  void setImportsController(HTMLImportsController*);
  HTMLImportsController* importsController() const {
    return m_importsController;
  }
  HTMLImportLoader* importLoader() const;

  bool haveImportsLoaded() const;
  void didLoadAllImports();

  void adjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>&,
                                                LayoutObject&);
  void adjustFloatRectForScrollAndAbsoluteZoom(FloatRect&, LayoutObject&);

  void setContextFeatures(ContextFeatures&);
  ContextFeatures& contextFeatures() const { return *m_contextFeatures; }

  ElementDataCache* elementDataCache() { return m_elementDataCache.get(); }

  void didLoadAllScriptBlockingResources();
  void didRemoveAllPendingStylesheet();

  bool inStyleRecalc() const {
    return m_lifecycle.state() == DocumentLifecycle::InStyleRecalc;
  }

  // Return a Locale for the default locale if the argument is null or empty.
  Locale& getCachedLocale(const AtomicString& locale = nullAtom);

  AnimationClock& animationClock();
  DocumentTimeline& timeline() const { return *m_timeline; }
  CompositorPendingAnimations& compositorPendingAnimations() {
    return *m_compositorPendingAnimations;
  }

  void addToTopLayer(Element*, const Element* before = nullptr);
  void removeFromTopLayer(Element*);
  const HeapVector<Member<Element>>& topLayerElements() const {
    return m_topLayerElements;
  }
  HTMLDialogElement* activeModalDialog() const;

  // A non-null m_templateDocumentHost implies that |this| was created by
  // ensureTemplateDocument().
  bool isTemplateDocument() const { return !!m_templateDocumentHost; }
  Document& ensureTemplateDocument();
  Document* templateDocumentHost() { return m_templateDocumentHost; }

  // TODO(thestig): Rename these and related functions, since we can call them
  // for controls outside of forms as well.
  void didAssociateFormControl(Element*);

  void addConsoleMessage(ConsoleMessage*) final;

  LocalDOMWindow* executingWindow() const final;
  LocalFrame* executingFrame();

  DocumentLifecycle& lifecycle() { return m_lifecycle; }
  bool isActive() const { return m_lifecycle.isActive(); }
  bool isDetached() const {
    return m_lifecycle.state() >= DocumentLifecycle::Stopping;
  }
  bool isStopped() const {
    return m_lifecycle.state() == DocumentLifecycle::Stopped;
  }

  enum HttpRefreshType { HttpRefreshFromHeader, HttpRefreshFromMetaTag };
  void maybeHandleHttpRefresh(const String&, HttpRefreshType);

  void updateSecurityOrigin(PassRefPtr<SecurityOrigin>);

  void setHasViewportUnits() { m_hasViewportUnits = true; }
  bool hasViewportUnits() const { return m_hasViewportUnits; }
  void notifyResizeForViewportUnits();

  void updateStyleInvalidationIfNeeded();

  DECLARE_VIRTUAL_TRACE();

  DECLARE_VIRTUAL_TRACE_WRAPPERS();

  bool hasSVGFilterElementsRequiringLayerUpdate() const {
    return m_layerUpdateSVGFilterElements.size();
  }

  AtomicString convertLocalName(const AtomicString&);

  void platformColorsChanged();

  DOMTimerCoordinator* timers() final;

  v8::Local<v8::Object> wrap(v8::Isolate*,
                             v8::Local<v8::Object> creationContext) override;
  v8::Local<v8::Object> associateWithWrapper(
      v8::Isolate*,
      const WrapperTypeInfo*,
      v8::Local<v8::Object> wrapper) override WARN_UNUSED_RETURN;

  HostsUsingFeatures::Value& HostsUsingFeaturesValue() {
    return m_hostsUsingFeaturesValue;
  }

  NthIndexCache* nthIndexCache() const { return m_nthIndexCache; }

  bool isSecureContext(
      String& errorMessage,
      const SecureContextCheck = StandardSecureContextCheck) const override;
  bool isSecureContext(
      const SecureContextCheck = StandardSecureContextCheck) const override;

  ClientHintsPreferences& clientHintsPreferences() {
    return m_clientHintsPreferences;
  }

  CanvasFontCache* canvasFontCache();

  // 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() { m_nodeCount++; }
  void decrementNodeCount() {
    DCHECK_GT(m_nodeCount, 0);
    m_nodeCount--;
  }
  int nodeCount() const { return m_nodeCount; }

  SnapCoordinator* snapCoordinator();

  void enforceInsecureRequestPolicy(WebInsecureRequestPolicy);

  bool mayContainV0Shadow() const { return m_mayContainV0Shadow; }

  ShadowCascadeOrder shadowCascadeOrder() const { return m_shadowCascadeOrder; }
  void setShadowCascadeOrder(ShadowCascadeOrder);

  bool containsV1ShadowTree() const {
    return m_shadowCascadeOrder == ShadowCascadeOrder::ShadowCascadeV1;
  }

  Element* rootScroller() const;
  void setRootScroller(Element*, ExceptionState&);
  RootScrollerController* rootScrollerController() const {
    return m_rootScrollerController.get();
  }

  bool isInMainFrame() const;

  void onVisibilityMaybeChanged(bool visible);

  PropertyRegistry* propertyRegistry();

 protected:
  Document(const DocumentInit&, DocumentClassFlags = DefaultDocumentClass);

  void didUpdateSecurityOrigin() final;

  void clearXMLVersion() { m_xmlVersion = String(); }

  virtual Document* cloneDocumentWithoutChildren();

  bool importContainerNodeChildren(ContainerNode* oldContainerNode,
                                   ContainerNode* newContainerNode,
                                   ExceptionState&);
  void lockCompatibilityMode() { m_compatibilityModeLocked = true; }
  ParserSynchronizationPolicy getParserSynchronizationPolicy() const {
    return m_parserSyncPolicy;
  }

 private:
  friend class IgnoreDestructiveWriteCountIncrementer;
  friend class ThrowOnDynamicMarkupInsertionCountIncrementer;
  friend class NthIndexCache;

  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&);
  SecurityContext& securityContext() final { return *this; }
  EventQueue* getEventQueue() const final;

  bool hasPendingVisualUpdate() const {
    return m_lifecycle.state() == DocumentLifecycle::VisualUpdatePending;
  }

  bool shouldScheduleLayoutTreeUpdate() const;
  void scheduleLayoutTreeUpdate();

  bool needsFullLayoutTreeUpdate() const;

  void inheritHtmlAndBodyElementStyles(StyleRecalcChange);

  bool dirtyElementsForLayerUpdate();

  void updateUseShadowTreesIfNeeded();
  void evaluateMediaQueryListIfNeeded();

  void updateStyle();
  void notifyLayoutTreeOfSubtreeChanges();

  void detachParser();

  void beginLifecycleUpdatesIfRenderingReady();

  bool isDocument() const final { return true; }

  void childrenChanged(const ChildrenChange&) override;

  String nodeName() const final;
  NodeType getNodeType() const final;
  bool childTypeAllowed(NodeType) const final;
  Node* cloneNode(bool deep) final;
  void cloneDataFromDocument(const Document&);
  bool isSecureContextImpl(
      const SecureContextCheck priviligeContextCheck) const;

  ShadowCascadeOrder m_shadowCascadeOrder = ShadowCascadeNone;

  // Same as url(), but needed for ExecutionContext to implement it without a
  // performance loss for direct calls.
  const KURL& virtualURL() const final;
  // Same as completeURL() for the same reason as above.
  KURL virtualCompleteURL(const String&) const final;

  void updateTitle(const String&);
  void updateFocusAppearanceTimerFired(TimerBase*);
  void updateBaseURL();

  void executeScriptsWaitingForResources();

  void loadEventDelayTimerFired(TimerBase*);
  void pluginLoadingTimerFired(TimerBase*);

  void addListenerType(ListenerType listenerType) {
    m_listenerTypes |= listenerType;
  }
  void addMutationEventListenerTypeIfEnabled(ListenerType);

  void didAssociateFormControlsTimerFired(TimerBase*);

  void clearFocusedElementSoon();
  void clearFocusedElementTimerFired(TimerBase*);

  bool haveScriptBlockingStylesheetsLoaded() const;
  bool haveRenderBlockingStylesheetsLoaded() const;
  void styleResolverMayHaveChanged();

  void setHoverNode(Node*);

  using EventFactorySet = HashSet<std::unique_ptr<EventFactoryBase>>;
  static EventFactorySet& eventFactories();

  void setNthIndexCache(NthIndexCache* nthIndexCache) {
    DCHECK(!m_nthIndexCache || !nthIndexCache);
    m_nthIndexCache = nthIndexCache;
  }

  const OriginAccessEntry& accessEntryFromURL();

  DocumentLifecycle m_lifecycle;

  bool m_hasNodesWithPlaceholderStyle;
  bool m_evaluateMediaQueriesOnStyleRecalc;

  // 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 m_pendingSheetLayout;

  Member<LocalFrame> m_frame;
  Member<LocalDOMWindow> m_domWindow;
  Member<HTMLImportsController> m_importsController;

  Member<ResourceFetcher> m_fetcher;
  Member<DocumentParser> m_parser;
  Member<ContextFeatures> m_contextFeatures;

  HeapHashMap<Member<Element>, RefPtr<ComputedStyle>> m_nonAttachedStyle;

  bool m_wellFormed;

  // Document URLs.
  KURL m_url;  // Document.URL: The URL from which this document was retrieved.
  KURL m_baseURL;  // Node.baseURI: The URL to use when resolving relative URLs.
  KURL m_baseURLOverride;  // An alternative base URL that takes precedence over
                           // m_baseURL (but not m_baseElementURL).
  KURL m_baseElementURL;   // The URL set by the <base> element.
  KURL m_cookieURL;        // The URL to use for cookie access.
  std::unique_ptr<OriginAccessEntry> m_accessEntryFromURL;

  AtomicString m_baseTarget;

  // Mime-type of the document in case it was cloned or created by XHR.
  AtomicString m_mimeType;

  Member<DocumentType> m_docType;
  Member<DOMImplementation> m_implementation;

  Member<CSSStyleSheet> m_elemSheet;

  bool m_printing;
  bool m_wasPrinting;
  bool m_paginatedForScreen;

  CompatibilityMode m_compatibilityMode;
  // This is cheaper than making setCompatibilityMode virtual.
  bool m_compatibilityModeLocked;

  std::unique_ptr<CancellableTaskFactory>
      m_executeScriptsWaitingForResourcesTask;

  bool m_hasAutofocused;
  Timer<Document> m_clearFocusedElementTimer;
  Member<Element> m_autofocusElement;
  Member<Element> m_focusedElement;
  Member<Range> m_sequentialFocusNavigationStartingPoint;
  Member<Node> m_hoverNode;
  Member<Element> m_activeHoverElement;
  Member<Element> m_documentElement;
  UserActionElementSet m_userActionElements;
  Member<RootScrollerController> m_rootScrollerController;

  uint64_t m_domTreeVersion;
  static uint64_t s_globalTreeVersion;

  uint64_t m_styleVersion;

  HeapHashSet<WeakMember<NodeIterator>> m_nodeIterators;
  using AttachedRangeSet = HeapHashSet<WeakMember<Range>>;
  AttachedRangeSet m_ranges;

  unsigned short m_listenerTypes;

  MutationObserverOptions m_mutationObserverTypes;

  Member<StyleEngine> m_styleEngine;
  Member<StyleSheetList> m_styleSheetList;

  Member<FormController> m_formController;

  TextLinkColors m_textLinkColors;
  const Member<VisitedLinkState> m_visitedLinkState;

  bool m_visuallyOrdered;
  ReadyState m_readyState;
  ParsingState m_parsingState;

  bool m_gotoAnchorNeededAfterStylesheetsLoad;
  bool m_isDNSPrefetchEnabled;
  bool m_haveExplicitlyDisabledDNSPrefetch;
  bool m_containsValidityStyleRules;
  bool m_containsPlugins;
  SelectionBehaviorOnFocus m_updateFocusAppearanceSelectionBahavior;

  // http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
  unsigned m_ignoreDestructiveWriteCount;
  // https://html.spec.whatwg.org/#throw-on-dynamic-markup-insertion-counter
  unsigned m_throwOnDynamicMarkupInsertionCount;

  String m_title;
  String m_rawTitle;
  Member<Element> m_titleElement;

  Member<AXObjectCache> m_axObjectCache;
  Member<DocumentMarkerController> m_markers;

  Timer<Document> m_updateFocusAppearanceTimer;

  Member<Element> m_cssTarget;

  LoadEventProgress m_loadEventProgress;

  double m_startTime;

  Member<ScriptRunner> m_scriptRunner;

  HeapVector<Member<Element>> m_currentScriptStack;

  std::unique_ptr<TransformSource> m_transformSource;

  String m_xmlEncoding;
  String m_xmlVersion;
  unsigned m_xmlStandalone : 2;
  unsigned m_hasXMLDeclaration : 1;

  AtomicString m_contentLanguage;

  DocumentEncodingData m_encodingData;

  bool m_designMode;
  bool m_isRunningExecCommand;

  HeapHashSet<WeakMember<const LiveNodeListBase>> m_listsInvalidatedAtDocument;
  // Oilpan keeps track of all registered NodeLists.
  // TODO(Oilpan): improve - only need to know if a NodeList
  // is currently alive or not for the different types.
  HeapHashSet<WeakMember<const LiveNodeListBase>>
      m_nodeLists[numNodeListInvalidationTypes];

  Member<SVGDocumentExtensions> m_svgExtensions;

  Vector<AnnotatedRegionValue> m_annotatedRegions;
  bool m_hasAnnotatedRegions;
  bool m_annotatedRegionsDirty;

  std::unique_ptr<SelectorQueryCache> m_selectorQueryCache;

  // 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.
  GC_PLUGIN_IGNORE("461878")
  NthIndexCache* m_nthIndexCache = nullptr;

  bool m_useSecureKeyboardEntryWhenActive;

  DocumentClassFlags m_documentClasses;

  bool m_isViewSource;
  bool m_sawElementsInKnownNamespaces;
  bool m_isSrcdocDocument;
  bool m_isMobileDocument;

  LayoutView* m_layoutView;

  WeakMember<Document> m_contextDocument;

  // For early return in Fullscreen::fromIfExists()
  bool m_hasFullscreenSupplement;

  HeapVector<Member<Element>> m_topLayerElements;

  int m_loadEventDelayCount;
  Timer<Document> m_loadEventDelayTimer;
  Timer<Document> m_pluginLoadingTimer;

  ViewportDescription m_viewportDescription;
  ViewportDescription m_legacyViewportDescription;
  Length m_viewportDefaultMinWidth;

  ReferrerPolicy m_referrerPolicy;

  DocumentTiming m_documentTiming;
  Member<MediaQueryMatcher> m_mediaQueryMatcher;
  bool m_writeRecursionIsTooDeep;
  unsigned m_writeRecursionDepth;

  Member<ScriptedAnimationController> m_scriptedAnimationController;
  Member<ScriptedIdleTaskController> m_scriptedIdleTaskController;
  std::unique_ptr<MainThreadTaskRunner> m_taskRunner;
  Member<TextAutosizer> m_textAutosizer;

  Member<V0CustomElementRegistrationContext> m_registrationContext;
  Member<V0CustomElementMicrotaskRunQueue> m_customElementMicrotaskRunQueue;

  void elementDataCacheClearTimerFired(TimerBase*);
  Timer<Document> m_elementDataCacheClearTimer;

  Member<ElementDataCache> m_elementDataCache;

  using LocaleIdentifierToLocaleMap =
      HashMap<AtomicString, std::unique_ptr<Locale>>;
  LocaleIdentifierToLocaleMap m_localeCache;

  Member<DocumentTimeline> m_timeline;
  Member<CompositorPendingAnimations> m_compositorPendingAnimations;

  Member<Document> m_templateDocument;
  Member<Document> m_templateDocumentHost;

  Timer<Document> m_didAssociateFormControlsTimer;

  HeapHashSet<Member<SVGUseElement>> m_useElementsNeedingUpdate;
  HeapHashSet<Member<Element>> m_layerUpdateSVGFilterElements;

  DOMTimerCoordinator m_timers;

  bool m_hasViewportUnits;

  ParserSynchronizationPolicy m_parserSyncPolicy;

  HostsUsingFeatures::Value m_hostsUsingFeaturesValue;

  ClientHintsPreferences m_clientHintsPreferences;

  Member<CanvasFontCache> m_canvasFontCache;

  Member<IntersectionObserverController> m_intersectionObserverController;
  Member<NodeIntersectionObserverData> m_intersectionObserverData;
  Member<ResizeObserverController> m_resizeObserverController;

  int m_nodeCount;

  bool m_mayContainV0Shadow = false;

  Member<SnapCoordinator> m_snapCoordinator;

  bool m_visibilityWasLogged;

  Member<PropertyRegistry> m_propertyRegistry;
};

extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Document>;

inline bool Document::shouldOverrideLegacyDescription(
    ViewportDescription::Type origin) const {
  // The different (legacy) meta tags have different priorities based on the
  // type regardless of which order they appear in the DOM. The priority is
  // given by the ViewportDescription::Type enum.
  return origin >= m_legacyViewportDescription.type;
}

inline void Document::scheduleLayoutTreeUpdateIfNeeded() {
  // Inline early out to avoid the function calls below.
  if (hasPendingVisualUpdate())
    return;
  if (shouldScheduleLayoutTreeUpdate() && needsLayoutTreeUpdate())
    scheduleLayoutTreeUpdate();
}

DEFINE_TYPE_CASTS(Document,
                  ExecutionContext,
                  context,
                  context->isDocument(),
                  context.isDocument());
DEFINE_NODE_TYPE_CASTS(Document, isDocumentNode());

#define DEFINE_DOCUMENT_TYPE_CASTS(thisType)                                \
  DEFINE_TYPE_CASTS(thisType, Document, document, document->is##thisType(), \
                    document.is##thisType())

// This is needed to avoid ambiguous overloads with the Node and TreeScope
// versions.
DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(Document)

// Put these methods here, because they require the Document definition, but we
// really want to inline them.

inline bool Node::isDocumentNode() const {
  return this == document();
}

Node* eventTargetNodeForDocument(Document*);

DEFINE_TYPE_CASTS(TreeScope, Document, document, true, true);

}  // namespace blink

#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
CORE_EXPORT void showLiveDocumentInstances();
#endif

#endif  // Document_h
