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

[
    EventTarget,
    IsWorkerContext,
    CustomToJSObject,
    NoWrapperCache
] interface WorkerContext {

    // WorkerGlobalScope
             [Replaceable] readonly attribute  WorkerContext self;
             [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(any handler, [Optional=DefaultIsUndefined] long timeout);
    void clearTimeout([Optional=DefaultIsUndefined] long handle);
    [Custom] long setInterval(any handler, [Optional=DefaultIsUndefined] long timeout);
    void clearInterval([Optional=DefaultIsUndefined] long handle);


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

    // Constructors
    attribute MessageEventConstructor MessageEvent;
    attribute WorkerLocationConstructor WorkerLocation;

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

    attribute BlobConstructor Blob;
    attribute FileReaderConstructor FileReader;
    attribute FileReaderSyncConstructor FileReaderSync;

    attribute DOMURLConstructor URL;
    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
};

