/*
 * Copyright (C) 2008-2016 Apple 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.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
 */

// FIXME: Add URLSearchParams and ReadableStream to the union when supported.
typedef (Blob or BufferSource or DOMFormData or USVString) BodyInit;

enum XMLHttpRequestResponseType {
    "",
    "arraybuffer",
    "blob",
    "document",
    "json",
    "text"
};

[
    ActiveDOMObject,
    ExportMacro=WEBCORE_EXPORT,
    Exposed=(Window,DedicatedWorker),
    JSCustomMarkFunction,
    JSGenerateToJSObject,
    JSGenerateToNativeObject,
    ReportExtraMemoryCost,
] interface XMLHttpRequest : XMLHttpRequestEventTarget {
    [CallWith=ScriptExecutionContext] constructor();

    // event handler
    attribute EventHandler onreadystatechange;

    // state
    const unsigned short UNSENT = 0;
    const unsigned short OPENED = 1;
    const unsigned short HEADERS_RECEIVED = 2;
    const unsigned short LOADING = 3;
    const unsigned short DONE = 4;
    readonly attribute unsigned short readyState;

    // request
    [MayThrowException] void open(ByteString method, DOMString url); // FIXME: url should be a USVString.
    [MayThrowException] void open(ByteString method, DOMString url, boolean async, optional DOMString? user = null, optional DOMString? password = null); // FIXME: url/user/password should all be a USVStrings.
    [MayThrowException] void setRequestHeader(ByteString header, ByteString value);
    attribute unsigned long timeout;
    attribute boolean withCredentials;
    readonly attribute XMLHttpRequestUpload upload;
    [MayThrowException] void send(optional (Document or BodyInit)? body = null);
    void abort();

    // response
    readonly attribute USVString responseURL;
    readonly attribute unsigned short status;
    readonly attribute ByteString statusText;
    ByteString? getResponseHeader(ByteString name);
    ByteString getAllResponseHeaders();
    [MayThrowException] void overrideMimeType(DOMString mime);
    attribute XMLHttpRequestResponseType responseType;
    [CachedAttribute, CustomGetter] readonly attribute any response;
    readonly attribute USVString responseText;
    [Exposed=Window] readonly attribute Document? responseXML;
};
