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

[
    CustomToJSObject,
    EventTarget,
    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, V8PerWorldBindings] DOMString        nodeName;

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

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

    [ObjCLegacyUnnamedParameters, Custom, V8PerWorldBindings] 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, V8PerWorldBindings] Node removeChild(in [CustomReturn] Node oldChild)
        raises(DOMException);
    [Custom, V8PerWorldBindings] Node appendChild(in [CustomReturn] Node newChild)
        raises(DOMException);

    boolean            hasChildNodes();
    [V8DeliverCustomElementCallbacks, V8PerWorldBindings]
    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, V8PerWorldBindings] DOMString        namespaceURI;
             attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, V8PerWorldBindings] DOMString        prefix
                 setter raises(DOMException);
    readonly attribute [TreatReturnedNullStringAs=Null, V8PerWorldBindings] DOMString        localName;

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


    // Introduced in DOM Level 3:

    readonly attribute [TreatReturnedNullStringAs=Null, V8PerWorldBindings] DOMString       baseURI;

             // FIXME: the spec says this can also raise on retrieval.
             attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, V8PerWorldBindings] 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 [V8PerWorldBindings] Element          parentElement;

#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
    // Objective-C extensions
    readonly attribute [V8PerWorldBindings] 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

};

