/*
 * 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.
 */

[
    Constructor,
    ConstructorCallWith=ScriptExecutionContext,
    CustomToJSObject,
    JSCustomHeader,
    JSGenerateToNativeObject,
] interface Document : Node {

    // DOM Level 1 Core
    readonly attribute DocumentType doctype;
    readonly attribute DOMImplementation implementation;
    readonly attribute Element documentElement;

    [NewObject, RaisesException, ImplementedAs=createElementForBindings] Element createElement(DOMString tagName);
    [NewObject] DocumentFragment   createDocumentFragment();
    [NewObject] Text createTextNode([Default=Undefined] optional DOMString data);
    [NewObject] Comment createComment([Default=Undefined] optional DOMString data);
    [NewObject, RaisesException] CDATASection createCDATASection([Default=Undefined] optional DOMString data);
    [ObjCLegacyUnnamedParameters, NewObject, RaisesException] ProcessingInstruction createProcessingInstruction([Default=Undefined] optional DOMString target,
                                                                                 [Default=Undefined] optional DOMString data);
    [NewObject, RaisesException] Attr createAttribute([Default=Undefined] optional DOMString name);

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    [RaisesException] EntityReference createEntityReference([Default=Undefined] optional DOMString name);
#endif

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    [ImplementedAs=getElementsByTagNameForObjC] NodeList getElementsByTagName([Default=Undefined] optional DOMString tagname);
#else
    HTMLCollection getElementsByTagName([Default=Undefined] optional DOMString tagname);
#endif

    // Introduced in DOM Level 2:

    [ObjCLegacyUnnamedParameters, NewObject, RaisesException] Node importNode([Default=Undefined] optional Node importedNode,
                    optional boolean deep);
    [ObjCLegacyUnnamedParameters, NewObject, RaisesException] Element createElementNS([TreatNullAs=NullString,TreatUndefinedAs=NullString,Default=Undefined] optional DOMString namespaceURI,
                            [TreatNullAs=NullString,Default=Undefined] optional DOMString qualifiedName);
    [ObjCLegacyUnnamedParameters, NewObject, RaisesException] Attr createAttributeNS([TreatNullAs=NullString,TreatUndefinedAs=NullString,Default=Undefined] optional DOMString namespaceURI,
                                                                          [TreatNullAs=NullString,Default=Undefined] optional DOMString qualifiedName);

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    [ObjCLegacyUnnamedParameters, ImplementedAs=getElementsByTagNameNSForObjC] NodeList getElementsByTagNameNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI, [Default=Undefined] optional DOMString localName);
#else
    HTMLCollection getElementsByTagNameNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI, [Default=Undefined] optional DOMString localName);
#endif

    // DOM Level 3 Core

    [ImplementedAs=characterSetWithUTF8Fallback] readonly attribute DOMString inputEncoding;

    [TreatReturnedNullStringAs=Null] readonly attribute DOMString xmlEncoding;
    [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, SetterRaisesException] attribute DOMString xmlVersion;
    [SetterRaisesException] attribute boolean xmlStandalone;

    [RaisesException] Node               adoptNode([Default=Undefined] optional Node source);

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C || defined(LANGUAGE_GOBJECT) && LANGUAGE_GOBJECT
    // document.documentURI was writable in DOM3 Core, but is read-only in DOM4
    // (see http://www.w3.org/TR/2011/WD-dom-20110915/#document). We need to keep
    // the writable version around for Objective C clients, but are moving to
    // read-only for other clients.
             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString documentURI;
#else
    [ImplementedAs=urlForBindings] readonly attribute DOMString documentURI;
#endif

    // DOM Level 2 Events (DocumentEvents interface)

    [RaisesException, NewObject] Event              createEvent([Default=Undefined] optional DOMString eventType);

    // DOM Level 2 Tranversal and Range (DocumentRange interface)

    [NewObject] Range              createRange();

    // DOM Level 2 Tranversal and Range (DocumentTraversal interface)

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C || defined(LANGUAGE_GOBJECT) && LANGUAGE_GOBJECT
    [ObjCLegacyUnnamedParameters, RaisesException] NodeIterator createNodeIterator(Node root,
        optional unsigned long whatToShow = 0xFFFFFFFF,
        optional NodeFilter? filter,
        optional boolean expandEntityReferences);
    [ObjCLegacyUnnamedParameters, RaisesException] TreeWalker createTreeWalker(Node root,
        optional unsigned long whatToShow = 0xFFFFFFFF,
        optional NodeFilter? filter,
        optional boolean expandEntityReferences);
#else
    [RaisesException, NewObject] NodeIterator createNodeIterator(Node root,
        optional unsigned long whatToShow = 0xFFFFFFFF,
        optional NodeFilter? filter);
    [RaisesException, NewObject] TreeWalker createTreeWalker(Node root,
        optional unsigned long whatToShow = 0xFFFFFFFF,
        optional NodeFilter? filter);
#endif

    // DOM Level 2 Abstract Views (DocumentView interface)

    readonly attribute DOMWindow defaultView;

    // DOM Level 2 Style (DocumentStyle interface)

    readonly attribute StyleSheetList styleSheets;

    // DOM Level 2 Style (DocumentCSS interface)

    [ObjCLegacyUnnamedParameters] CSSStyleDeclaration getOverrideStyle([Default=Undefined] optional Element element,
                                                        [Default=Undefined] optional DOMString pseudoElement);

    readonly attribute DOMString contentType;

    // DOM Level 3 XPath (XPathEvaluator interface)
    [ObjCLegacyUnnamedParameters, RaisesException] XPathExpression createExpression([Default=Undefined] optional DOMString expression,
                                                    [Default=Undefined] optional XPathNSResolver resolver);
    XPathNSResolver    createNSResolver(Node nodeResolver);
    [ObjCLegacyUnnamedParameters, RaisesException] XPathResult evaluate([Default=Undefined] optional DOMString expression,
                                                  [Default=Undefined] optional Node contextNode,
                                                  [Default=Undefined] optional XPathNSResolver resolver,
                                                  [Default=Undefined] optional unsigned short type,
                                                  [Default=Undefined] optional XPathResult inResult);

    // Common extensions
    boolean            execCommand([Default=Undefined] optional DOMString command,
                                   [Default=Undefined] optional boolean userInterface,
                                   [TreatNullAs=NullString, TreatUndefinedAs=NullString, Default=Undefined] optional DOMString value);

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    // FIXME: remove the these two versions once optional is implemented for Objective-C.
    boolean            execCommand(DOMString command,
                                   boolean userInterface);
    boolean            execCommand(DOMString command);
#endif

    boolean            queryCommandEnabled([Default=Undefined] optional DOMString command);
    boolean            queryCommandIndeterm([Default=Undefined] optional DOMString command);
    boolean            queryCommandState([Default=Undefined] optional DOMString command);
    boolean            queryCommandSupported([Default=Undefined] optional DOMString command);
    DOMString          queryCommandValue([Default=Undefined] optional DOMString command);

    // Moved down from HTMLDocument

             [TreatNullAs=NullString] attribute DOMString title;
    readonly attribute DOMString referrer;
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    [TreatNullAs=NullString, SetterRaisesException] attribute DOMString domain;
#else
    readonly attribute DOMString domain;
#endif
    [ImplementedAs=urlForBindings] readonly attribute DOMString URL;

    [TreatNullAs=NullString, GetterRaisesException, SetterRaisesException] attribute DOMString cookie;

    [SetterRaisesException, ImplementedAs=bodyOrFrameset, StrictTypeChecking] attribute HTMLElement body;

    readonly attribute HTMLHeadElement head;
    readonly attribute HTMLCollection images;
    readonly attribute HTMLCollection applets;
    readonly attribute HTMLCollection links;
    readonly attribute HTMLCollection forms;
    readonly attribute HTMLCollection anchors;
    readonly attribute DOMString lastModified;

    NodeList getElementsByName([Default=Undefined,AtomicString] optional DOMString elementName);

#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    [PutForwards=href, Unforgeable] readonly attribute Location? location;
#endif

    // IE extensions

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C || defined(LANGUAGE_GOBJECT) && LANGUAGE_GOBJECT
    [TreatReturnedNullStringAs=Undefined, TreatNullAs=NullString] attribute DOMString charset;
#else
    [ImplementedAs=characterSetWithUTF8Fallback] readonly attribute DOMString charset;
#endif
    [TreatReturnedNullStringAs=Undefined] readonly attribute DOMString defaultCharset;
    [TreatReturnedNullStringAs=Undefined] readonly attribute DOMString readyState;

    Element            elementFromPoint([Default=Undefined] optional long x, 
                                        [Default=Undefined] optional long y);
    Range              caretRangeFromPoint([Default=Undefined] optional long x, 
                                           [Default=Undefined] optional long y);

    // Mozilla extensions
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    DOMSelection       getSelection();
#endif
    [ImplementedAs=characterSetWithUTF8Fallback] readonly attribute DOMString characterSet;

    // WebKit extensions

    [TreatReturnedNullStringAs=Null] readonly attribute DOMString preferredStylesheetSet;
             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectedStylesheetSet;

#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
    CSSStyleDeclaration createCSSStyleDeclaration();
#endif

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    // DOM Level 2 Style Interface
    [ObjCLegacyUnnamedParameters, ObjCUseDefaultView] CSSStyleDeclaration getComputedStyle(Element element,
                                                                  DOMString pseudoElement);

    // WebKit extension
    // FIXME: remove the first version once optional is implemented for Objective-C.
    [ObjCUseDefaultView] CSSRuleList getMatchedCSSRules(Element element,
                                              DOMString pseudoElement);
    [ObjCUseDefaultView] CSSRuleList getMatchedCSSRules(Element element,
                                              DOMString pseudoElement,
                                              optional boolean authorOnly);
                                              
#endif

#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
    CanvasRenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
#endif

    // HTML 5
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    [ImplementedAs=getElementsByClassNameForObjC] NodeList getElementsByClassName([Default=Undefined] optional DOMString classNames);
#else
    HTMLCollection getElementsByClassName([Default=Undefined] optional DOMString classNames);
#endif

    readonly attribute Element activeElement;
    boolean hasFocus();

    readonly attribute DOMString compatMode;

#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
    // Mozilla version
    readonly attribute boolean webkitIsFullScreen;
    readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
    readonly attribute Element webkitCurrentFullScreenElement;
    void webkitCancelFullScreen();

    // W3C version
    readonly attribute boolean webkitFullscreenEnabled;
    readonly attribute Element webkitFullscreenElement;
    void webkitExitFullscreen();
#endif

    [Conditional=POINTER_LOCK] void exitPointerLock();
    [Conditional=POINTER_LOCK] readonly attribute Element pointerLockElement;

    [Conditional=CSS_REGIONS] DOMNamedFlowCollection webkitGetNamedFlows();

#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    [Conditional=FONT_LOAD_EVENTS] readonly attribute FontLoader fonts;
#endif

#if defined(ENABLE_IOS_TOUCH_EVENTS) && ENABLE_IOS_TOUCH_EVENTS
#include <WebKitAdditions/DocumentIOS.idl>
#elif defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
    [NewObject, RaisesException] Touch createTouch([Default=Undefined] optional DOMWindow window,
                                                     [Default=Undefined] optional EventTarget target,
                                                     [Default=Undefined] optional long identifier,
                                                     [Default=Undefined] optional long pageX,
                                                     [Default=Undefined] optional long pageY,
                                                     [Default=Undefined] optional long screenX,
                                                     [Default=Undefined] optional long screenY,
                                                     [Default=Undefined] optional long webkitRadiusX,
                                                     [Default=Undefined] optional long webkitRadiusY,
                                                     [Default=Undefined] optional unrestricted float webkitRotationAngle,
                                                     [Default=Undefined] optional unrestricted float webkitForce);
    [NewObject, Custom, RaisesException] TouchList createTouchList();
#endif

#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    [Custom, RaisesException, Conditional=CUSTOM_ELEMENTS]
    void defineCustomElement(DOMString tagName, CustomElementInterface elementInterface);
#endif

    // Page visibility API.
    readonly attribute DOMString visibilityState;
    readonly attribute boolean hidden;

    // currentscript API: http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-document-currentscript
    readonly attribute HTMLScriptElement currentScript;

    // http://www.w3.org/TR/2014/WD-dom-20140204/#dom-document-origin
    readonly attribute DOMString origin;

    // http://dev.w3.org/csswg/cssom-view/#dom-document-scrollingelement
    readonly attribute Element scrollingElement;


    // Event Handlers

    // Unique to Element and Document
    // FIXME: Should these be exposed on Window as well (and therefore moved to GlobalEventHandlers.idl)?
    [NotEnumerable] attribute EventHandler onbeforecopy;
    [NotEnumerable] attribute EventHandler onbeforecut;
    [NotEnumerable] attribute EventHandler onbeforepaste;
    [NotEnumerable] attribute EventHandler oncopy;
    [NotEnumerable] attribute EventHandler oncut;
    [NotEnumerable] attribute EventHandler onpaste;
    [NotEnumerable] attribute EventHandler onselectstart;
    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventHandler onwebkitfullscreenchange;
    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventHandler onwebkitfullscreenerror;

    // Unique to Document and HTMLBodyElement
    [NotEnumerable] attribute EventHandler onselectionchange;

    // Unique to Document
    [LenientThis] attribute EventHandler onreadystatechange;
    [NotEnumerable, Conditional=CSP_NEXT] attribute EventHandler onsecuritypolicyviolation;
    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventHandler onpointerlockchange;
    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventHandler onpointerlockerror;
};

Document implements ParentNode;
Document implements NonElementParentNode;
Document implements GlobalEventHandlers;
