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

[
    JSCustomHeader,
    JSCustomMarkFunction,
    JSCustomPushEventHandlerScope,
    JSCustomIsReachable,
    JSCustomFinalize,
    CustomToJSObject,
    EventTarget,
    JSGenerateToNativeObject,
    JSInlineGetOwnPropertySlot,
    ObjCPolymorphic,
    V8DependentLifetime
] interface Node
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    : Object, EventTarget
#endif /* defined(LANGUAGE_OBJECTIVE_C) */
 {
    // 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;

    readonly attribute [TreatReturnedNullStringAs=Null] DOMString        nodeName;

             // FIXME: the spec says this can also raise on retrieval.
             attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString        nodeValue
                 setter raises(DOMException);

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

    [ObjCLegacyUnnamedParameters, Custom] Node insertBefore(in [CustomReturn] Node newChild,
                                                            in Node refChild)
        raises(DOMException);
    [ObjCLegacyUnnamedParameters, Custom] Node replaceChild(in Node newChild,
                                                            in [CustomReturn] Node oldChild)
        raises(DOMException);
    [Custom] Node               removeChild(in [CustomReturn] Node oldChild)
        raises(DOMException);
    [Custom] Node               appendChild(in [CustomReturn] Node newChild)
        raises(DOMException);

    boolean            hasChildNodes();
    Node               cloneNode(in [Optional=DefaultIsUndefined] boolean deep);
    void               normalize();

    // Introduced in DOM Level 2:

    [ObjCLegacyUnnamedParameters] boolean isSupported(in [Optional=DefaultIsUndefined] DOMString feature, 
                                       in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString version);

    readonly attribute [TreatReturnedNullStringAs=Null] DOMString        namespaceURI;
             attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString        prefix
                 setter raises(DOMException);
    readonly attribute [TreatReturnedNullStringAs=Null] DOMString        localName;

#if defined(LANGUAGE_OBJECTIVE_C)
    readonly attribute NamedNodeMap     attributes;
    boolean            hasAttributes();
#endif


    // Introduced in DOM Level 3:

    readonly attribute [TreatReturnedNullStringAs=Null] DOMString       baseURI;

             // FIXME: the spec says this can also raise on retrieval.
             attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString       textContent
                 setter raises(DOMException);

    boolean            isSameNode(in [Optional=DefaultIsUndefined] Node other);
    boolean            isEqualNode(in [Optional=DefaultIsUndefined] Node other);
    [TreatReturnedNullStringAs=Null] DOMString          lookupPrefix(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI);
    boolean            isDefaultNamespace(in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString namespaceURI);
    [TreatReturnedNullStringAs=Null] DOMString          lookupNamespaceURI(in [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(in [Optional=DefaultIsUndefined] Node other);

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

    // IE extensions
    readonly attribute Element          parentElement;

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    // Objective-C extensions
    readonly attribute boolean          isContentEditable;

    void inspect();
#endif /* defined(LANGUAGE_OBJECTIVE_C) */

#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
    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 event)
        raises(EventException);
#endif
#endif

#if defined(LANGUAGE_CPP) && LANGUAGE_CPP
    [Custom] void addEventListener(in DOMString type, 
                                      in EventListener listener, 
                                      in boolean useCapture);
    [Custom] void removeEventListener(in DOMString type, 
                                         in EventListener listener, 
                                         in boolean useCapture);
    boolean dispatchEvent(in Event event)
        raises(EventException);
#endif

};

