/*
 * Copyright (C) 2006, 2007, 2011, 2015 Apple Inc. All rights reserved.
 * Copyright (C) 2006, 2007 Samuel Weinig <sam@webkit.org>
 *
 * 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.
 */

typedef (
#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
    WebGLRenderingContext or
#endif
#if defined(ENABLE_WEBGL2) && ENABLE_WEBGL2
    WebGL2RenderingContext or
#endif
#if defined(ENABLE_WEBGPU) && ENABLE_WEBGPU
    WebGPURenderingContext or
#endif
    ImageBitmapRenderingContext or 
    CanvasRenderingContext2D) RenderingContext;

[
    Constructor,
    ConstructorCallWith=Document,
    CustomToJSObject,
    DOMJIT,
    ExportMacro=WEBCORE_EXPORT,
    JSCustomHeader,
    JSCustomMarkFunction,
    JSGenerateToNativeObject,
] interface Document : Node {
    readonly attribute DOMImplementation implementation; // FIXME: Should be [SameObject].
    [ImplementedAs=urlForBindings] readonly attribute USVString URL;
    [ImplementedAs=urlForBindings] readonly attribute USVString documentURI;
    readonly attribute USVString origin;
    readonly attribute DOMString compatMode;
    [ImplementedAs=characterSetWithUTF8Fallback] readonly attribute DOMString characterSet;
    [ImplementedAs=characterSetWithUTF8Fallback] readonly attribute DOMString charset; // Historical alias of .characterSet,
    [ImplementedAs=characterSetWithUTF8Fallback] readonly attribute DOMString inputEncoding; // Historical alias of .characterSet.
    readonly attribute DOMString contentType;

    readonly attribute DocumentType? doctype;
    [DOMJIT=Getter] readonly attribute Element? documentElement;

    HTMLCollection getElementsByTagName(DOMString qualifiedName);
    HTMLCollection getElementsByTagNameNS(DOMString? namespaceURI, DOMString localName);
    HTMLCollection getElementsByClassName(DOMString classNames);

    [NewObject, MayThrowException, ImplementedAs=createElementForBindings] Element createElement(DOMString localName); // FIXME: missing options parameter.
    [NewObject, MayThrowException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName); // FIXME: missing options parameter.
    [NewObject] DocumentFragment createDocumentFragment();
    [NewObject] Text createTextNode(DOMString data);
    [NewObject, MayThrowException] CDATASection createCDATASection(DOMString data);
    [NewObject] Comment createComment(DOMString data);
    [NewObject, MayThrowException] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);

    [CEReactions, MayThrowException, NewObject] Node importNode(Node node, optional boolean deep = false);
    [CEReactions, MayThrowException] Node adoptNode(Node node);

    [NewObject, MayThrowException] Attr createAttribute(DOMString localName);
    [NewObject, MayThrowException] Attr createAttributeNS(DOMString? namespaceURI, DOMString qualifiedName);

    [MayThrowException, NewObject] Event createEvent(DOMString type);

    [NewObject] Range createRange();

    // NodeFilter.SHOW_ALL = 0xFFFFFFFF.
    [NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
    [NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);

    // Extensions from HTML specification (https://html.spec.whatwg.org/#the-document-object).
    [PutForwards=href, Unforgeable] readonly attribute Location? location;
    attribute USVString domain;
    readonly attribute USVString referrer;
    attribute USVString cookie;
    readonly attribute DOMString lastModified;
    readonly attribute DocumentReadyState readyState;

    // DOM tree accessors.
    [CEReactions] attribute DOMString title;
    [CEReactions] attribute DOMString dir;
    [CEReactions, DOMJIT=Getter, ImplementedAs=bodyOrFrameset] attribute HTMLElement? body;
    readonly attribute HTMLHeadElement? head;
    readonly attribute HTMLCollection images; // Should be [SameObject].
    readonly attribute HTMLCollection embeds; // Should be [SameObject].
    readonly attribute HTMLCollection plugins; // Should be [SameObject].
    readonly attribute HTMLCollection links; // Should be [SameObject].
    readonly attribute HTMLCollection forms; // Should be [SameObject].
    readonly attribute HTMLCollection scripts; // Should be [SameObject].
    NodeList getElementsByName([AtomicString] DOMString elementName);
    readonly attribute HTMLScriptElement? currentScript; // FIXME: Should return a HTMLOrSVGScriptElement.

    // dynamic markup insertion
    // FIXME: The HTML spec says this should consult the "responsible document". We should ensure
    // that the caller document matches those semantics. It is possible we should replace it with
    // the existing 'incumbent document' concept.
    [CEReactions, CallWith=ResponsibleDocument, ImplementedAs=openForBindings, MayThrowException] Document open(optional DOMString type = "text/html", optional DOMString replace = "");
    [CallWith=ActiveWindow&FirstWindow, ImplementedAs=openForBindings, MayThrowException] WindowProxy open(USVString url, DOMString name, DOMString features);
    [CEReactions, ImplementedAs=closeForBindings, MayThrowException] void close();
    [CEReactions, CallWith=ResponsibleDocument, MayThrowException] void write(DOMString... text);
    [CEReactions, CallWith=ResponsibleDocument, MayThrowException] void writeln(DOMString... text);

    // User interaction.
    [ImplementedAs=windowProxy] readonly attribute WindowProxy? defaultView;
    boolean hasFocus();
    [CEReactions] attribute DOMString designMode;
    [CEReactions] boolean execCommand(DOMString commandId, optional boolean showUI = false, optional DOMString? value = null); // FIXME: value should not be nullable.
    boolean queryCommandEnabled(DOMString commandId);
    boolean queryCommandIndeterm(DOMString commandId);
    boolean queryCommandState(DOMString commandId);
    boolean queryCommandSupported(DOMString commandId);
    DOMString queryCommandValue(DOMString commandId);

    // Special event handler IDL attributes that only apply to Document objects.
    [LenientThis] attribute EventHandler onreadystatechange;

    // Extensions from the CSSOM specification (https://drafts.csswg.org/cssom/#extensions-to-the-document-interface).
    // FIXME: Should likely be moved to DocumentOrShadowRoot.
    readonly attribute StyleSheetList styleSheets; // FIXME: Should be [SameObject].

    // Extensions from the CSSOM-View specification (https://drafts.csswg.org/cssom-view/#extensions-to-the-document-interface).
    readonly attribute Element? scrollingElement;

    // Extensions from Selection API (https://www.w3.org/TR/selection-api/#extensions-to-document-interface).
    // FIXME: Should likely be moved to DocumentOrShadowRoot.
    DOMSelection? getSelection();

    // XPath extensions (https://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator).
    [MayThrowException] XPathExpression createExpression(optional DOMString expression = "undefined", optional XPathNSResolver? resolver); // FIXME: Using "undefined" as default parameter value is wrong.
    XPathNSResolver createNSResolver(Node? nodeResolver);
    [MayThrowException] XPathResult evaluate(optional DOMString expression = "undefined", optional Node? contextNode, optional XPathNSResolver? resolver, optional unsigned short type = 0, optional XPathResult? inResult); // FIXME: Using "undefined" as default parameter value is wrong.

    // Extensions from FullScreen API (https://fullscreen.spec.whatwg.org/#api).
    // FIXME: Should probably be unprefixed.
    [Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen] readonly attribute boolean webkitFullscreenEnabled;
    [Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen, ImplementedAs=webkitFullscreenElementForBindings] readonly attribute Element? webkitFullscreenElement;
    [Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen] void webkitExitFullscreen();
    [Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen] readonly attribute boolean webkitIsFullScreen; // Mozilla version.
    [Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen] readonly attribute boolean webkitFullScreenKeyboardInputAllowed; // Mozilla version.
    [Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen, ImplementedAs=webkitCurrentFullScreenElementForBindings] readonly attribute Element webkitCurrentFullScreenElement; // Mozilla version.
    [Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen] void webkitCancelFullScreen(); // Mozilla version.
    [NotEnumerable, Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen] attribute EventHandler onwebkitfullscreenchange;
    [NotEnumerable, Conditional=FULLSCREEN_API, EnabledBySetting=FullScreen] attribute EventHandler onwebkitfullscreenerror;

    // Extensions from Pointer Lock API (https://www.w3.org/TR/pointerlock/#extensions-to-the-document-interface).
    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventHandler onpointerlockchange; // FIXME: Should be enumerable.
    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventHandler onpointerlockerror; // FIXME: Should be enumerable.
    [Conditional=POINTER_LOCK] void exitPointerLock();

    // Extensions from CSS Font Loading API (https://drafts.csswg.org/css-font-loading/#font-face-source).
    // FIXME: Should be in a separate FontFaceSource interface.
    readonly attribute FontFaceSet fonts;

    // Extensions from Page visibility API (https://www.w3.org/TR/page-visibility/#sec-document-interface).
    readonly attribute boolean hidden;
    readonly attribute VisibilityState visibilityState;
    attribute EventHandler onvisibilitychange;

    // FIXME: Those have been dropped from the DOM specification.
    readonly attribute DOMString? xmlEncoding;
    attribute DOMString? xmlVersion;
    attribute boolean xmlStandalone;

    // FIXME: Blink has already dropped this (https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/s3ezjTuC8ig).
    CSSStyleDeclaration getOverrideStyle(optional Element? element = null, optional DOMString pseudoElement = "undefined");

    // FIXME: Should be moved to GlobalEventHandlers (http://w3c.github.io/selection-api/#extensions-to-globaleventhandlers).
    [NotEnumerable] attribute EventHandler onselectstart; // FIXME: Should be enumerable.
    [NotEnumerable] attribute EventHandler onselectionchange; // FIXME: Should be enumerable.

    // Non standard: It has been superseeded by caretPositionFromPoint which we do not implement yet.
    Range caretRangeFromPoint(optional long x = 0, optional long y = 0);

    // FIXME: This is not standard and has been dropped from Blink already.
    RenderingContext? getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);

    // Non standard, to bring up with standards working group.
    [EnabledBySetting=StorageAccessAPI] Promise<bool> hasStorageAccess();
    [EnabledBySetting=StorageAccessAPI] Promise<void> requestStorageAccess();

    // Obsolete features from https://html.spec.whatwg.org/multipage/obsolete.html

    [CEReactions] attribute [TreatNullAs=EmptyString] DOMString fgColor;
    [CEReactions, ImplementedAs=linkColorForBindings] attribute [TreatNullAs=EmptyString] DOMString linkColor;
    [CEReactions] attribute [TreatNullAs=EmptyString] DOMString vlinkColor;
    [CEReactions] attribute [TreatNullAs=EmptyString] DOMString alinkColor;
    [CEReactions] attribute [TreatNullAs=EmptyString] DOMString bgColor;

    readonly attribute HTMLCollection anchors; /* [SameObject] */
    readonly attribute HTMLCollection applets; /* [SameObject] */

    void clear();
    void captureEvents();
    void releaseEvents();

    [Replaceable] readonly attribute HTMLAllCollection all; /* [SameObject] */

    [EnabledAtRuntime=WebAnimations] readonly attribute DocumentTimeline timeline;
    [EnabledAtRuntime=WebAnimations] sequence<WebAnimation> getAnimations();
};

enum DocumentReadyState { "loading", "interactive", "complete" };

Document implements DocumentAndElementEventHandlers;
Document implements ParentNode;
Document implements NonElementParentNode;
Document implements DocumentOrShadowRoot;
Document implements GlobalEventHandlers;
