/*
 * Copyright (C) 2006-2020 Apple Inc. All rights reserved.
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

[
    CheckSecurity,
    CustomDefineOwnProperty,
    CustomDeleteProperty,
    CustomGetOwnPropertyNames,
    CustomGetOwnPropertySlot,
    CustomGetPrototype,
    CustomHeapSnapshot,
    CustomPreventExtensions,
    CustomPut,
    ExportMacro=WEBCORE_EXPORT,
    InterfaceName=Window,
    IsImmutablePrototypeExoticObject,
    IsImmutablePrototypeExoticObjectOnPrototype,
    JSCustomMarkFunction,
    JSCustomToNativeObject,
    JSLegacyParent=JSDOMWindowBase,
    LegacyUnenumerableNamedProperties,
    Global=Window,
    Exposed=Window
] interface DOMWindow : EventTarget {
    // the current browsing context
    [DoNotCheckSecurity, LegacyUnforgeable, CustomGetter] readonly attribute WindowProxy window;
    [Replaceable, DoNotCheckSecurityOnGetter, CustomGetter] readonly attribute WindowProxy self;
    [LegacyUnforgeable] readonly attribute Document document;
    attribute DOMString name;
    [DoNotCheckSecurity, PutForwards=href, LegacyUnforgeable] readonly attribute Location location;
    readonly attribute History history;
    [ImplementedAs=ensureCustomElementRegistry] readonly attribute CustomElementRegistry customElements;
    [Replaceable] readonly attribute BarProp locationbar;
    [Replaceable] readonly attribute BarProp menubar;
    [Replaceable] readonly attribute BarProp personalbar;
    [Replaceable] readonly attribute BarProp scrollbars;
    [Replaceable] readonly attribute BarProp statusbar;
    [Replaceable] readonly attribute BarProp toolbar;
    attribute DOMString status;
    [DoNotCheckSecurity, CallWith=IncumbentDocument] undefined close();
    [DoNotCheckSecurity] readonly attribute boolean closed;
    undefined stop();
    [DoNotCheckSecurity, CallWith=IncumbentWindow] undefined focus();
    [DoNotCheckSecurity] undefined blur();

    // other browsing contexts
    [Replaceable, DoNotCheckSecurityOnGetter, CustomGetter] readonly attribute WindowProxy frames;
    [Replaceable, DoNotCheckSecurityOnGetter] readonly attribute unsigned long length;
    [DoNotCheckSecurityOnGetter, LegacyUnforgeable] readonly attribute WindowProxy? top;
    [DoNotCheckSecurityOnGetter, CustomSetter] attribute WindowProxy? opener;
    [Replaceable, DoNotCheckSecurityOnGetter] readonly attribute WindowProxy? parent;
    [CheckSecurityForNode] readonly attribute Element? frameElement;
    [CallWith=ActiveWindow&FirstWindow] WindowProxy? open(optional USVString url = "", optional DOMString target = "_blank", optional [LegacyNullToEmptyString] DOMString features = "");

    // the user agent
    readonly attribute Navigator navigator;
    // FIXME: This is specified to be [SecureContext]
    readonly attribute DOMApplicationCache applicationCache;

    // user prompts
    undefined alert();
    undefined alert(DOMString message);
    [ImplementedAs=confirmForBindings]boolean confirm(optional DOMString message = "");
    DOMString? prompt(optional DOMString message = "", optional DOMString defaultValue = "");
    undefined print();

    [CallWith=GlobalObject&IncumbentWindow, DoNotCheckSecurity] undefined postMessage(any message, USVString targetOrigin, optional sequence<object> transfer = []);
    [CallWith=GlobalObject&IncumbentWindow, DoNotCheckSecurity] undefined postMessage(any message, optional WindowPostMessageOptions options);


    // Obsolete: Still part of the HTML specification (https://html.spec.whatwg.org/#Window-partial).
    undefined captureEvents();
    undefined releaseEvents();


    // Non-standard
    [Replaceable, CustomGetter] readonly attribute Event event;
    attribute DOMString defaultStatus;
    [ImplementedAs=defaultStatus] attribute DOMString defaultstatus; // For compatibility with legacy content.
    boolean find(optional DOMString string, optional boolean caseSensitive = false, optional boolean backwards = false, optional boolean wrap = false, optional boolean wholeWord = false, optional boolean searchInFrames = false, optional boolean showDialog = false);
    [Replaceable] readonly attribute  boolean offscreenBuffering;
    long webkitRequestAnimationFrame(RequestAnimationFrameCallback callback);
    [ImplementedAs=cancelAnimationFrame] undefined webkitCancelAnimationFrame(long id);
    [ImplementedAs=cancelAnimationFrame] undefined webkitCancelRequestAnimationFrame(long id);

    // Non-standard: May get added (https://github.com/whatwg/html/issues/2379).
    [Replaceable] readonly attribute Navigator clientInformation;

    // Non-standard: iOS extension - https://developer.apple.com/reference/webkitjs/gestureevent
    [NotEnumerable, Conditional=IOS_GESTURE_EVENTS] attribute EventHandler ongesturechange;
    [NotEnumerable, Conditional=IOS_GESTURE_EVENTS] attribute EventHandler ongestureend;
    [NotEnumerable, Conditional=IOS_GESTURE_EVENTS] attribute EventHandler ongesturestart;

    // Non-standard: This has been dropped from the HTML specification and by other browsers.
    [Custom] any showModalDialog(DOMString url, optional any dialogArgs, optional DOMString featureArgs);

    // Non-standard: should probably deprecate this (https://bugs.webkit.org/show_bug.cgi?id=79653).
    // Blink already deprecated it (https://bugs.chromium.org/p/chromium/issues/detail?id=437569).
    CSSRuleList getMatchedCSSRules(optional Element? element = null, optional DOMString? pseudoElement = null);

    // Non-standard: Blink has already dropped these (https://bugs.chromium.org/p/chromium/issues/detail?id=398352).
    WebKitPoint webkitConvertPointFromPageToNode(optional Node? node = null, optional WebKitPoint? p = null);
    WebKitPoint webkitConvertPointFromNodeToPage(optional Node? node = null, optional WebKitPoint? p = null);

    // Internal operations, not exposed to the Web.
    [EnabledForWorld=shadowRootIsAlwaysOpen] NodeList collectMatchingElementsInFlatTree(Node scope, DOMString selectors);
    [EnabledForWorld=shadowRootIsAlwaysOpen] Element? matchingElementInFlatTree(Node scope, DOMString selectors);
};

[
    ImplementedAs=WindowPostMessageOptions
] dictionary WindowPostMessageOptions : StructuredSerializeOptions {
    USVString targetOrigin = "/";
};

DOMWindow includes AnimationFrameProvider;
DOMWindow includes GlobalEventHandlers;
DOMWindow includes WindowEventHandlers;
DOMWindow includes WindowOrWorkerGlobalScope;
DOMWindow includes WindowLocalStorage;
DOMWindow includes WindowSessionStorage;
