/*
 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
 *
 * 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.
 */

// FIXME: Node should inherit EventTarget.
[
    CustomToJSObject,
    EventTarget,
    DependentLifetime
] interface Node {
    // NodeType
    const unsigned short      ELEMENT_NODE                   = 1;
    const unsigned short      ATTRIBUTE_NODE                 = 2;
    const unsigned short      TEXT_NODE                      = 3;
    const unsigned short      CDATA_SECTION_NODE             = 4;
    const unsigned short      ENTITY_REFERENCE_NODE          = 5;
    const unsigned short      ENTITY_NODE                    = 6;
    const unsigned short      PROCESSING_INSTRUCTION_NODE    = 7;
    const unsigned short      COMMENT_NODE                   = 8;
    const unsigned short      DOCUMENT_NODE                  = 9;
    const unsigned short      DOCUMENT_TYPE_NODE             = 10;
    const unsigned short      DOCUMENT_FRAGMENT_NODE         = 11;
    const unsigned short      NOTATION_NODE                  = 12;

    [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString        nodeName;

             // FIXME: the spec says this can also raise on retrieval.
             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, SetterRaisesException] attribute DOMString        nodeValue;

    [PerWorldBindings] readonly attribute unsigned short   nodeType;
    [PerWorldBindings] readonly attribute Node             parentNode;
    [PerWorldBindings] readonly attribute NodeList         childNodes;
    [PerWorldBindings] readonly attribute Node             firstChild;
    [PerWorldBindings] readonly attribute Node             lastChild;
    [PerWorldBindings] readonly attribute Node             previousSibling;
    [PerWorldBindings] readonly attribute Node             nextSibling;
    [PerWorldBindings] readonly attribute Document         ownerDocument;

    [Custom, PerWorldBindings, RaisesException] Node insertBefore(Node newChild, Node refChild);
    [Custom, RaisesException] Node replaceChild(Node newChild, Node oldChild);
    [Custom, PerWorldBindings, RaisesException] Node removeChild(Node oldChild);
    [Custom, PerWorldBindings, RaisesException] Node appendChild(Node newChild);

    boolean            hasChildNodes();
    [DeliverCustomElementCallbacks, PerWorldBindings]
    Node               cloneNode([Optional=DefaultIsUndefined] boolean deep);
    void               normalize();

    // Introduced in DOM Level 2:
     boolean isSupported([Optional=DefaultIsUndefined] DOMString feature, 
                                       [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString version);

    [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString        namespaceURI;
             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, SetterRaisesException] attribute DOMString        prefix;
    [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString        localName;

    // Introduced in DOM Level 3:
    [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString       baseURI;

             // FIXME: the spec says this can also raise on retrieval.
             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, SetterRaisesException] attribute DOMString       textContent;

    boolean            isSameNode([Optional=DefaultIsUndefined] Node other);
    boolean            isEqualNode([Optional=DefaultIsUndefined] Node other);
    [TreatReturnedNullStringAs=Null] DOMString          lookupPrefix([TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI);
    boolean            isDefaultNamespace([TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI);
    [TreatReturnedNullStringAs=Null] DOMString          lookupNamespaceURI([TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString prefix);

    // DocumentPosition
    const unsigned short      DOCUMENT_POSITION_DISCONNECTED = 0x01;
    const unsigned short      DOCUMENT_POSITION_PRECEDING    = 0x02;
    const unsigned short      DOCUMENT_POSITION_FOLLOWING    = 0x04;
    const unsigned short      DOCUMENT_POSITION_CONTAINS     = 0x08;
    const unsigned short      DOCUMENT_POSITION_CONTAINED_BY = 0x10;
    const unsigned short      DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;

    unsigned short     compareDocumentPosition([Optional=DefaultIsUndefined] Node other);

    // Introduced in DOM4
    boolean contains([Optional=DefaultIsUndefined] Node other);

    // IE extensions
    [PerWorldBindings] readonly attribute Element          parentElement;

    void addEventListener(DOMString type, 
                          EventListener listener, 
                          [Optional] boolean useCapture);
    void removeEventListener(DOMString type, 
                             EventListener listener, 
                             [Optional] boolean useCapture);
    [RaisesException] boolean dispatchEvent(Event event);
};
