blob: 0f34f1ea13baa47ac6f2b35c00911acc2f67b2ff [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dom.client;
import com.google.gwt.core.client.JavaScriptObject;
/**
* The Node interface is the primary datatype for the entire Document Object
* Model. It represents a single node in the document tree. While all objects
* implementing the Node interface expose methods for dealing with children, not
* all objects implementing the Node interface may have children.
*/
public class Node extends JavaScriptObject {
/**
* The node is an {@link Element}.
*/
public static final short ELEMENT_NODE = 1;
/**
* The node is a {@link Text} node.
*/
public static final short TEXT_NODE = 3;
/**
* The node is a {@link Document}.
*/
public static final short DOCUMENT_NODE = 9;
/**
* Assert that the given {@link JavaScriptObject} is a DOM node and
* automatically typecast it.
*/
public static Node as(JavaScriptObject o) {
assert is(o);
return (Node) o;
}
/**
* Determines whether the given {@link JavaScriptObject} is a DOM node. A
* <code>null</code> object will cause this method to return
* <code>false</code>.
* The try catch is needed for the firefox permission error:
* "Permission denied to access property 'nodeType'"
*/
public static native boolean is(JavaScriptObject o) /*-{
try {
return (!!o) && (!!o.nodeType);
} catch (e) {
return false;
}
}-*/;
protected Node() {
}
/**
* Adds the node newChild to the end of the list of children of this node. If
* the newChild is already in the tree, it is first removed.
*
* @param newChild The node to add
* @return The node added
*/
public final native <T extends Node> T appendChild(T newChild) /*-{
return this.appendChild(newChild);
}-*/;
/**
* Returns a duplicate of this node, i.e., serves as a generic copy
* constructor for nodes. The duplicate node has no parent; (parentNode is
* null.).
*
* Cloning an Element copies all attributes and their values, including those
* generated by the XML processor to represent defaulted attributes, but this
* method does not copy any text it contains unless it is a deep clone, since
* the text is contained in a child Text node. Cloning an Attribute directly,
* as opposed to be cloned as part of an Element cloning operation, returns a
* specified attribute (specified is true). Cloning any other type of node
* simply returns a copy of this node.
*
* @param deep If true, recursively clone the subtree under the specified
* node; if false, clone only the node itself (and its attributes, if
* it is an {@link Element})
* @return The duplicate node
*/
public final native Node cloneNode(boolean deep) /*-{
return this.cloneNode(deep);
}-*/;
/**
* Gets the child node at the given index.
*
* @param index the index of the node to be retrieved
* @return the child node at the given index
*/
public final Node getChild(int index) {
assert (index >= 0) && (index < getChildCount()) : "Child index out of bounds";
return getChildNodes().getItem(index);
}
/**
* Gets the number of child nodes contained within this node.
*
* @return the number of child nodes
*/
public final int getChildCount() {
return getChildNodes().getLength();
}
/**
* A NodeList that contains all children of this node. If there are no
* children, this is a NodeList containing no nodes.
*/
public final native NodeList<Node> getChildNodes() /*-{
return this.childNodes;
}-*/;
/**
* The first child of this node. If there is no such node, this returns null.
*/
public final native Node getFirstChild() /*-{
return this.firstChild;
}-*/;
/**
* The last child of this node. If there is no such node, this returns null.
*/
public final native Node getLastChild() /*-{
return this.lastChild;
}-*/;
/**
* The node immediately following this node. If there is no such node, this
* returns null.
*/
public final native Node getNextSibling() /*-{
return this.nextSibling;
}-*/;
/**
* The name of this node, depending on its type; see the table above.
*/
public final native String getNodeName() /*-{
return this.nodeName;
}-*/;
/**
* A code representing the type of the underlying object, as defined above.
*/
public final native short getNodeType() /*-{
return this.nodeType;
}-*/;
/**
* The value of this node, depending on its type; see the table above. When it
* is defined to be null, setting it has no effect.
*/
public final native String getNodeValue() /*-{
return this.nodeValue;
}-*/;
/**
* The Document object associated with this node. This is also the
* {@link Document} object used to create new nodes.
*/
public final native Document getOwnerDocument() /*-{
return this.ownerDocument;
}-*/;
/**
* Gets the parent element of this node.
*
* @return this node's parent element, or <code>null</code> if none exists
*/
public final Element getParentElement() {
return DOMImpl.impl.getParentElement(this);
}
/**
* The parent of this node. All nodes except Document may have a parent.
* However, if a node has just been created and not yet added to the tree, or
* if it has been removed from the tree, this is null.
*/
public final native Node getParentNode() /*-{
return this.parentNode;
}-*/;
/**
* The node immediately preceding this node. If there is no such node, this
* returns null.
*/
public final native Node getPreviousSibling() /*-{
return this.previousSibling;
}-*/;
/**
* Returns whether this node has any children.
*/
public final native boolean hasChildNodes() /*-{
return this.hasChildNodes();
}-*/;
/**
* Determines whether this node has a parent element.
*
* @return true if the node has a parent element
*/
public final boolean hasParentElement() {
return getParentElement() != null;
}
/**
* Inserts the node newChild after the existing child node refChild. If
* refChild is <code>null</code>, insert newChild at the end of the list of children.
*
* @param newChild The node to insert
* @param refChild The reference node (that is, the node after which the new
* node must be inserted), or <code>null</code>
* @return The node being inserted
*/
public final Node insertAfter(Node newChild, Node refChild) {
assert (newChild != null) : "Cannot add a null child node";
Node next = (refChild == null) ? null : refChild.getNextSibling();
if (next == null) {
return appendChild(newChild);
} else {
return insertBefore(newChild, next);
}
}
/**
* Inserts the node newChild before the existing child node refChild. If
* refChild is <code>null</code>, insert newChild at the end of the list of children.
*
* @param newChild The node to insert
* @param refChild The reference node (that is, the node before which the new
* node must be inserted), or <code>null</code>
* @return The node being inserted
*/
public final native Node insertBefore(Node newChild, Node refChild) /*-{
return this.insertBefore(newChild, refChild);
}-*/;
/**
* Inserts the given child as the first child of this node.
*
* @param child the child to be inserted
* @return The node being inserted
*/
public final Node insertFirst(Node child) {
assert (child != null) : "Cannot add a null child node";
return insertBefore(child, getFirstChild());
}
/**
* Determine whether a node is equal to, or the child of, this node.
*
* @param child the potential child element
* @return <code>true</code> if the relationship holds
*/
public final boolean isOrHasChild(Node child) {
assert (child != null) : "Child cannot be null";
return DOMImpl.impl.isOrHasChild(this, child);
}
/**
* Removes the child node indicated by oldChild from the list of children, and
* returns it.
*
* @param oldChild The node being removed
* @return The node removed
*/
public final native Node removeChild(Node oldChild) /*-{
return this.removeChild(oldChild);
}-*/;
/**
* Remove all children of the node.
*/
public final native Node removeAllChildren() /*-{
while (this.lastChild) {
this.removeChild(this.lastChild);
}
}-*/;
/**
* Removes this node from its parent node if it is attached to one.
*/
public final void removeFromParent() {
Element parent = getParentElement();
if (parent != null) {
parent.removeChild(this);
}
}
/**
* Replaces the child node oldChild with newChild in the list of children, and
* returns the oldChild node.
*
* @param newChild The new node to put in the child list
* @param oldChild The node being replaced in the list
* @return The node replaced
*/
public final native Node replaceChild(Node newChild, Node oldChild) /*-{
return this.replaceChild(newChild, oldChild);
}-*/;
/**
* The value of this node, depending on its type; see the table above. When it
* is defined to be null, setting it has no effect.
*/
public final native void setNodeValue(String nodeValue) /*-{
this.nodeValue = nodeValue;
}-*/;
}