/*
 * Copyright (C) 2008 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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 COMPUTER, 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. 
 *
 */

[
    Conditional=WORKERS,
    JSCustomMarkFunction,
    JSCustomGetOwnPropertySlotAndDescriptor,
    EventTarget,
    ExtendsDOMGlobalObject,
    IsWorkerContext,
    JSLegacyParent=JSWorkerContextBase,
    JSNoStaticTables,
    OmitConstructor,
    V8CustomToJSObject,
    V8NoWrapperCache
] interface WorkerContext {

    // WorkerGlobalScope
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
             [Replaceable] readonly attribute  WorkerContext self;
#endif
             [Replaceable] readonly attribute WorkerLocation location;
    void close();
             attribute EventListener onerror;

    // WorkerUtils
    [Custom] void importScripts(/*[Variadic] in DOMString urls */);
             [Replaceable] readonly attribute WorkerNavigator navigator;

    // Timers
    [Custom] long setTimeout(in any handler, in [Optional=DefaultIsUndefined] long timeout);
    void clearTimeout(in [Optional=DefaultIsUndefined] long handle);
    [Custom] long setInterval(in any handler, in [Optional=DefaultIsUndefined] long timeout);
    void clearInterval(in [Optional=DefaultIsUndefined] long handle);


    // EventTarget interface
    void addEventListener(in DOMString type, 
                          in EventListener listener, 
                          in [Optional] boolean useCapture);
    void removeEventListener(in DOMString type, 
                             in EventListener listener, 
                             in [Optional] boolean useCapture);
    boolean dispatchEvent(in Event evt)
        raises(EventException);

#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
    // Constructors
    attribute MessageEventConstructor MessageEvent;
    attribute WorkerLocationConstructor WorkerLocation;

#if defined(ENABLE_CHANNEL_MESSAGING) && ENABLE_CHANNEL_MESSAGING
    [JSCustomGetter] attribute MessageChannelConstructor MessageChannel;
#endif
    [JSCustomGetter] attribute EventSourceConstructor EventSource;
    [JSCustomGetter] attribute XMLHttpRequestConstructor XMLHttpRequest;
#endif

#if defined(ENABLE_BLOB) && ENABLE_BLOB
    attribute BlobConstructor Blob;
    attribute FileReaderConstructor FileReader;
    attribute FileReaderSyncConstructor FileReaderSync;
#endif

    [Conditional=BLOB] attribute DOMURLConstructor URL;
    [Conditional=BLOB] attribute DOMURLConstructor webkitURL; // FIXME: deprecate this.

    attribute ArrayBufferConstructor ArrayBuffer; // Usable with new operator
    attribute Int8ArrayConstructor Int8Array; // Usable with new operator
    attribute Uint8ArrayConstructor Uint8Array; // Usable with new operator
    attribute Uint8ClampedArrayConstructor Uint8ClampedArray; // Usable with new operator
    attribute Int16ArrayConstructor Int16Array; // Usable with new operator
    attribute Uint16ArrayConstructor Uint16Array; // Usable with new operator
    attribute Int32ArrayConstructor Int32Array; // Usable with new operator
    attribute Uint32ArrayConstructor Uint32Array; // Usable with new operator
    attribute Float32ArrayConstructor Float32Array; // Usable with new operator
    attribute Float64ArrayConstructor Float64Array; // Usable with new operator
    attribute DataViewConstructor DataView; // Usable with new operator
};

