previousSibling points
* to the end of the list
*/
private DomNode previousSibling_;
/**
* The next sibling. The last child's nextSibling is null
*/
private DomNode nextSibling_;
/** Start of the child list. */
private DomNode firstChild_;
/**
* This is the JavaScript object corresponding to this DOM node. It may
* be null if there isn't a corresponding JavaScript object.
*/
private transient ScriptableObject scriptObject_;
/** The ready state is is an IE-only value that is available to a large number of elements. */
private String readyState_;
/** The name of the "element" property. Used when watching property change events. */
public static final String PROPERTY_ELEMENT = "element";
/**
* The line number in the source page where the DOM node starts.
*/
private int startLineNumber_ = -1;
/**
* The column number in the source page where the DOM node starts.
*/
private int startColumnNumber_ = -1;
/**
* The line number in the source page where the DOM node ends.
*/
private int endLineNumber_ = -1;
/**
* The column number in the source page where the DOM node ends.
*/
private int endColumnNumber_ = -1;
private Listnode.
*
* @param indent white space to indent child nodes
* @param printWriter writer where child nodes are written
*/
protected void printXml(final String indent, final PrintWriter printWriter) {
printWriter.println(indent + this);
printChildrenAsXml(indent, printWriter);
}
/**
* Recursively writes the XML data for the node tree starting at node.
*
* @param indent white space to indent child nodes
* @param printWriter writer where child nodes are written
*/
protected void printChildrenAsXml(final String indent, final PrintWriter printWriter) {
DomNode child = getFirstChild();
while (child != null) {
child.printXml(indent + " ", printWriter);
child = child.getNextSibling();
}
}
/**
* {@inheritDoc}
*/
public String getNodeValue() {
return null;
}
/**
* {@inheritDoc}
*/
public void setNodeValue(final String x) {
// Default behavior is to do nothing, overridden in some subclasses
}
/**
* {@inheritDoc}
*/
public DomNode cloneNode(final boolean deep) {
final DomNode newnode;
try {
newnode = (DomNode) clone();
}
catch (final CloneNotSupportedException e) {
throw new IllegalStateException("Clone not supported for node [" + this + "]");
}
newnode.parent_ = null;
newnode.nextSibling_ = null;
newnode.previousSibling_ = null;
newnode.firstChild_ = null;
newnode.scriptObject_ = null;
// if deep, clone the kids too.
if (deep) {
for (DomNode child = firstChild_; child != null; child = child.nextSibling_) {
newnode.appendChild(child.cloneNode(true));
}
}
return newnode;
}
/**
* Makes a clone of this node.
*
* @param deep if true, the clone will be propagated to the whole subtree
* below this one. Otherwise, the new node will not have any children. The page reference
* will always be the same as this node's.
* @return a new node
* @deprecated As of 2.0, please use {@link #cloneNode(boolean)} instead.
*/
@Deprecated
public DomNode cloneDomNode(final boolean deep) {
return cloneNode(deep);
}
/**
* INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.Returns the canonical XPath expression which identifies this node, for instance * "/html/body/table[3]/tbody/tr[5]/td[2]/span/a[3]".
* *WARNING: This sort of automated XPath expression * is often quite bad at identifying a node, as it is highly sensitive to changes in * the DOM tree.
* * @return the canonical XPath expression which identifies this node * @see #getByXPath(String) */ public String getCanonicalXPath() { final DomNode parent = getParentNode(); if (parent == null) { return ""; } return parent.getCanonicalXPath() + '/' + getXPathToken(); } /** * Returns the XPath token for this node only. */ private String getXPathToken() { final DomNode parent = getParentNode(); int total = 0; int nodeIndex = 0; for (final DomNode child : parent.getChildren()) { if (child.getNodeName().equals(getNodeName())) { total++; } if (child == this) { nodeIndex = total; } } if (nodeIndex == 1 && total == 1) { return getNodeName(); } return getNodeName() + '[' + nodeIndex + ']'; } /** * Notifies the registered {@link IncorrectnessListener} of something that is not fully correct. * @param message the notification to send to the registered {@link IncorrectnessListener} */ protected void notifyIncorrectness(final String message) { final WebClient client = getPage().getEnclosingWindow().getWebClient(); final IncorrectnessListener incorrectnessListener = client.getIncorrectnessListener(); incorrectnessListener.notify(message, this); } /** * Adds a {@link DomChangeListener} to the listener list. The listener is registered for * all descendants of this node. * * @param listener the DOM structure change listener to be added * @see #removeDomChangeListener(DomChangeListener) */ public void addDomChangeListener(final DomChangeListener listener) { WebAssert.notNull("listener", listener); synchronized (domListeners_lock_) { if (domListeners_ == null) { domListeners_ = new ArrayList