KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > gargoylesoftware > htmlunit > javascript > host > NodeImpl


1 /*
2  * Copyright (c) 2002, 2005 Gargoyle Software Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * 3. The end-user documentation included with the redistribution, if any, must
13  * include the following acknowledgment:
14  *
15  * "This product includes software developed by Gargoyle Software Inc.
16  * (http://www.GargoyleSoftware.com/)."
17  *
18  * Alternately, this acknowledgment may appear in the software itself, if
19  * and wherever such third-party acknowledgments normally appear.
20  * 4. The name "Gargoyle Software" must not be used to endorse or promote
21  * products derived from this software without prior written permission.
22  * For written permission, please contact info@GargoyleSoftware.com.
23  * 5. Products derived from this software may not be called "HtmlUnit", nor may
24  * "HtmlUnit" appear in their name, without prior written permission of
25  * Gargoyle Software Inc.
26  *
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30  * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */

38 package com.gargoylesoftware.htmlunit.javascript.host;
39
40 import org.jaxen.JaxenException;
41 import org.mozilla.javascript.Context;
42
43 import com.gargoylesoftware.htmlunit.html.DomNode;
44 import com.gargoylesoftware.htmlunit.html.HtmlElement;
45 import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
46 import com.gargoylesoftware.htmlunit.html.xpath.HtmlUnitXPath;
47 import com.gargoylesoftware.htmlunit.javascript.ElementArray;
48
49 /**
50  * The javascript object "NodeImpl" which is the base class for all DOM
51  * objects. This will typically wrap an instance of {@link DomNode}.
52  *
53  * @version $Revision: 100 $
54  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
55  * @author David K. Taylor
56  * @author Barnaby Court
57  * @author <a HREF="mailto:cse@dynabean.de">Christian Sell</a>
58  * @author <a HREF="mailto:george@murnock.com">George Murnock</a>
59  * @author Chris Erskine
60  */

61 public class NodeImpl extends SimpleScriptable {
62
63     private ElementArray childNodes_; //has to be a member to have equality (==) working
64
private static final long serialVersionUID = -5695262053081637445L;
65
66
67     /**
68      * Create an instance.
69      */

70     public NodeImpl() {
71     }
72
73
74     /**
75      * Javascript constructor. This must be declared in every javascript file because
76      * the rhino engine won't walk up the hierarchy looking for constructors.
77      */

78     public void jsConstructor() {
79     }
80
81
82     /**
83      * Get the JavaScript property "nodeType" for the current node.
84      * @return The node type
85      */

86     public short jsxGet_nodeType() {
87         return getDomNodeOrDie().getNodeType();
88     }
89
90
91     /**
92      * Get the JavaScript property "nodeName" for the current node.
93      * @return The node name
94      */

95     public String JavaDoc jsxGet_nodeName() {
96         final DomNode domNode = getDomNodeOrDie();
97         String JavaDoc nodeName = domNode.getNodeName();
98         
99         // If this is an HtmlElement then flip the result to uppercase. This should really be
100
// changed in HtmlElement itself but that would break backwards compatibility fairly
101
// significantly as that one is documented as always returning a lowercase value.
102
if( domNode instanceof HtmlElement ) {
103             nodeName = nodeName.toUpperCase();
104         }
105         return nodeName;
106     }
107
108
109     /**
110      * Get the JavaScript property "nodeValue" for the current node.
111      * @return The node value
112      */

113     public String JavaDoc jsxGet_nodeValue() {
114         return getDomNodeOrDie().getNodeValue();
115     }
116
117
118     /**
119      * Set the JavaScript property "nodeValue" for the current node.
120      * @param newValue The new node value
121      */

122     public void jsxSet_nodeValue( final String JavaDoc newValue ) {
123         getDomNodeOrDie().setNodeValue( newValue );
124     }
125
126
127     /**
128      * Add a DOM node to the node
129      * @param childObject The node to add to this node
130      * @return The newly added child node.
131      */

132     public Object JavaDoc jsxFunction_appendChild(final Object JavaDoc childObject) {
133
134         Object JavaDoc appendedChild = null;
135         if (childObject instanceof NodeImpl) {
136             // Get XML node for the DOM node passed in
137
final DomNode childDomNode =
138                 ((NodeImpl) childObject).getDomNodeOrDie();
139
140             // Get the parent XML node that the child should be added to.
141
final DomNode parentNode = getDomNodeOrDie();
142
143             // Append the child to the parent node
144
parentNode.appendChild(childDomNode);
145             appendedChild = childObject;
146         }
147         return appendedChild;
148     }
149
150
151     /**
152      * Duplicate an XML node
153      * @param deep If true, recursively clone all descendents. Otherwise,
154      * just clone this node.
155      * @return The newly cloned node.
156      */

157     public Object JavaDoc jsxFunction_cloneNode(final boolean deep) {
158         final DomNode domNode = getDomNodeOrDie();
159         final DomNode clonedNode = domNode.cloneNode( deep );
160         return getJavaScriptNode(clonedNode);
161     }
162
163
164     /**
165      * Add a DOM node as a child to this node before the referenced
166      * node. If the referenced node is null, append to the end.
167      * @param newChildObject The node to add to this node
168      * @param refChildObject The node before which to add the new child
169      * @return The newly added child node.
170      */

171     public Object JavaDoc jsxFunction_insertBefore(
172             final Object JavaDoc newChildObject, final Object JavaDoc refChildObject) {
173         Object JavaDoc appendedChild = null;
174
175         if (newChildObject instanceof NodeImpl) {
176
177             final DomNode newChildNode =
178                 ((NodeImpl) newChildObject).getDomNodeOrDie();
179
180             final DomNode refChildNode;
181             if(refChildObject != null) {
182                 refChildNode = ((NodeImpl) refChildObject).getDomNodeOrDie();
183             }
184             else {
185                 refChildNode = null;
186             }
187
188             // Append the child to the parent node
189
if (refChildNode != null ) {
190                 refChildNode.insertBefore(newChildNode);
191                 appendedChild = newChildObject;
192             }
193             else {
194                 getDomNodeOrDie().appendChild(newChildNode);
195             }
196         }
197         return appendedChild;
198     }
199
200
201     /**
202      * Remove a DOM node from this node
203      * @param childObject The node to remove from this node
204      * @return The removed child node.
205      */

206     public Object JavaDoc jsxFunction_removeChild(final Object JavaDoc childObject) {
207         Object JavaDoc removedChild = null;
208
209         if (childObject instanceof NodeImpl) {
210             // Get XML node for the DOM node passed in
211
final DomNode childNode =
212                 ((NodeImpl) childObject).getDomNodeOrDie();
213
214             // Remove the child from the parent node
215
childNode.remove();
216             removedChild = childObject;
217         }
218         return removedChild;
219     }
220     
221     /**
222      * Returns whether this node has any children.
223      * @return boolean true if this node has any children, false otherwise.
224      */

225     public boolean jsxFunction_hasChildNodes() {
226         return getDomNodeOrDie().getChildIterator().hasNext();
227     }
228     
229     /**
230      * Returns the child nodes of the current element.
231      * @return The child nodes of the current element.
232      */

233     public Object JavaDoc jsxGet_childNodes() {
234         if (childNodes_ == null) {
235             childNodes_ = (ElementArray) makeJavaScriptObject(ElementArray.JS_OBJECT_NAME);
236             try {
237                 childNodes_.init(getDomNodeOrDie(), new HtmlUnitXPath("./* | text()"));
238             }
239             catch (final JaxenException je) {
240                 throw Context.reportRuntimeError("Failed to initialize collection element.childNodes: "
241                         + je.getMessage());
242             }
243         }
244         return childNodes_;
245     }
246
247
248     /**
249      * Replace a child DOM node with another DOM node.
250      * @param newChildObject The node to add as a child of this node
251      * @param oldChildObject The node to remove as a child of this node
252      * @return The removed child node.
253      */

254     public Object JavaDoc jsxFunction_replaceChild(
255             final Object JavaDoc newChildObject, final Object JavaDoc oldChildObject) {
256         Object JavaDoc removedChild = null;
257
258         if (newChildObject instanceof NodeImpl &&
259             oldChildObject instanceof NodeImpl) {
260             // Get XML nodes for the DOM nodes passed in
261
final DomNode newChildNode =
262                 ((NodeImpl) newChildObject).getDomNodeOrDie();
263
264             final DomNode oldChildNode;
265             if(oldChildObject != null) {
266                 // Replace the old child with the new child.
267
oldChildNode = ((NodeImpl) oldChildObject).getDomNodeOrDie();
268                 oldChildNode.replace(newChildNode);
269                 removedChild = oldChildObject;
270             }
271         }
272         return removedChild;
273     }
274
275
276     /**
277      * Get the JavaScript property "parentNode" for the node that
278      * contains the current node.
279      * @return The parent node
280      */

281     public Object JavaDoc jsxGet_parentNode() {
282         return getJavaScriptNode( getDomNodeOrDie().getParentNode() );
283     }
284
285
286     /**
287      * Get the JavaScript property "nextSibling" for the node that
288      * contains the current node.
289      * @return The next sibling node or null if the current node has
290      * no next sibling.
291      */

292     public Object JavaDoc jsxGet_nextSibling() {
293         return getJavaScriptNode( getDomNodeOrDie().getNextSibling() );
294     }
295
296
297     /**
298      * Get the JavaScript property "previousSibling" for the node that
299      * contains the current node.
300      * @return The previous sibling node or null if the current node has
301      * no previous sibling.
302      */

303     public Object JavaDoc jsxGet_previousSibling() {
304         return getJavaScriptNode( getDomNodeOrDie().getPreviousSibling() );
305     }
306
307
308     /**
309      * Get the JavaScript property "firstChild" for the node that
310      * contains the current node.
311      * @return The first child node or null if the current node has
312      * no children.
313      */

314     public Object JavaDoc jsxGet_firstChild() {
315         return getJavaScriptNode( getDomNodeOrDie().getFirstChild() );
316     }
317
318
319     /**
320      * Get the JavaScript property "lastChild" for the node that
321      * contains the current node.
322      * @return The last child node or null if the current node has
323      * no children.
324      */

325     public Object JavaDoc jsxGet_lastChild() {
326         return getJavaScriptNode( getDomNodeOrDie().getLastChild() );
327     }
328
329
330     /**
331      * Get the JavaScript node for a given DomNode
332      * @param domNode The DomNode
333      * @return The JavaScript node or null if the DomNode was null.
334      */

335     protected Object JavaDoc getJavaScriptNode( final DomNode domNode ) {
336         if ( domNode == null ) {
337             return null;
338         }
339         return getScriptableFor( domNode );
340     }
341 }
342
Popular Tags