001 
002 /*
003  *  JScripter Standard 1.0 - To Script In Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package js.user;
021 
022 import js.*;
023 import js.dom.*;
024 import js.core.*;
025 
026 /**
027  * <p>An <b>opaque</b> class representing JavaScript client-side objects of the global 
028  * {@link JsClient#Element} class.</p>
029  *
030  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
031  *
032  * @javascript <b>Opaque</b> types can be resolved but no class objects for them can be
033  * generated into the target codes. Re-compilers must exit with error on the operations of
034  * accessing that kind of class objects.
035  * The <tt>checkcast</tt> operation to the class literal of this class must be ignored
036  * and <tt>instanceof</tt> to it always <tt>true</tt>.
037  */
038 public class JsElement extends JsClient.Element.Prototype implements EventTarget
039 {
040     /**
041      * <p>An <b>internal</b> class containing membership data for its enclosing
042      * opaque class.</p>
043      * <p>This class is only used inside of <b>opaque</b> or <b>internal</b> classes or
044      * class members.</p>
045      *
046      * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
047      * 
048      * @javascript Re-compilers must report error on resolving an <b>internal</b> class.
049      */
050     protected static abstract class Members extends JsClient.Element.Prototype.Members
051     {
052         /**
053          * <p>An <b>internal</b> static field defining a member ID of the field name and
054          * used internally to define a member of the same name.</p>
055          * @since 1.0
056          * @javascript Re-compilers must report error on accessing an <b>internal</b> field.
057          */
058         public final static Mid tagName = id("tagName");
059     }
060 
061     /**
062      * <p>An <b>opaque</b> class representing members of its enclosing <b>opaque</b> type.</p>
063      * <p>Note that, this class is <b>opaque</b> but its constructors are all <b>internal</b>. 
064      * This class and the subclasses of this class are used to declare either <b>opaque</b> 
065      * <tt>public</tt> instance fields of the opaque type {@link js.Var.Member} or the 
066      * <b>opaque</b> <tt>public</tt> static fields of other <b>opaque</b> types while their 
067      * constructors are used to define the fields inside <b>opaque</b> classes. Under 
068      * either circumstance, the field names must be exactly same as the member names, as 
069      * the <b>opaque</b> fields of <b>opaque</b> types are resolved by re-compilers directly 
070      * based on the field names.</p>
071      *
072      * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
073      * 
074      * @javascript <b>Opaque</b> types can be resolved but no class objects for them can be created
075      * in the target codes. Re-compilers must exit with error on operations accessing that kind 
076      * of class objects.
077      * Re-compilers must resolve an <b>opaque</b> instance field declared by this class in
078      * {@link js.Var.Member} or its subclasses to the JavaScript identifier: 
079      * <pre>q.m</pre>
080      * where <tt>m</tt> is the identifier of the field name and <tt>q</tt> is the identifier
081      * resolved from the instance of the enclosing member. Re-compilers must resolve an 
082      * <b>opaque</b> static field declared by this class in <b>opaque</b> types other than 
083      * {@link js.Var.Member} and its subclasses to the JavaScript identifier: 
084      * <pre>m</pre>
085      * where <tt>m</tt> is the identifier of the field name. And re-compilers must report
086      * error on the access to <b>opaque</b> fields declared by this class under any other 
087      * circumstances.
088      */
089     public static class Member extends JsClient.Element.Prototype.Member
090     {
091         /**
092          * <p>Internally constructs a member based on a qualifying member.</p>
093          * <p>This constructor is <b>internal</b> and only called inside of <b>opaque</b>
094          * or <b>internal</b> classes or class members.</p>
095          * <p>Note that, this constructor is <b>internal</b> but its declaring class is
096          * <b>opaque</b>. This constructor is used to define <b>opaque</b> instance fields 
097          * declared in the declaring class of this constructor itself or its subclasses. 
098          * Under this circumstance, the field names must be exactly same as the member 
099          * names, as the <b>opaque</b> instance fields of the <b>opaque</b> type 
100          * {@link js.Var.Member} or its subclasses are resolved by re-compilers directly
101          * to their names appending to the name resolved from the specified qualifying 
102          * member with a dot in between.</p>
103          * @param q A qualifying member
104          * @param mid The ID of the member to construct
105          * @since 1.0
106          * @javascript Re-compilers must report error on the invocation to an <b>internal</b> constructor.
107          */
108         public Member(JsObject.Member q, Mid mid) {
109             super(q, mid);
110         }
111         /**
112          * <p>Internally constructs a member without a qualifying member.</p>
113          * <p>This constructor is <b>internal</b> and only called inside of <b>opaque</b>
114          * or <b>internal</b> classes or class members.</p>
115          * <p>Note that, this constructor is <b>internal</b> but its declaring class is
116          * <b>opaque</b>. This constructor is used to define <b>opaque</b> static fields, 
117          * declared in <b>opaque</b> types other than the declaring class of this constructor 
118          * itself and its subclasses. Under this circumstance, the field names must be
119          * exactly same as the member names, as the <b>opaque</b> static fields of <b>opaque</b>
120          * types are generally resolved by re-compilers directly to identifiers of their names.</p>
121          * @param mid The ID of the member to construct
122          * @since 1.0
123          * @javascript Re-compilers must report error on the invocation to an <b>internal</b> constructor.
124          */
125         public Member(Mid mid) {
126             super(mid);
127         }
128         @Override
129         /**
130          * <p>Evaluates the property, represented by the current member instance, of the
131          * argument object.</p>
132          * @param o The argument object
133          * @return The value of the current member based on the object argument.
134          * @since 1.0
135          * @javascript Re-compilers must convert the instance invocation of this method into
136          * the JavaScript expression: 
137          * <pre>o.m</pre>
138          * where <tt>m</tt> is the identifier name resolved from the current member
139          * instance of the invocation.
140          */
141         public JsElement with(ObjectLike o) {
142             return new JsElement(super.with(o));
143         }
144 
145         /**
146          * <p>An <b>opaque</b> instance field defining a sub-member that is named by the
147          * name of this field, qualified by the current member instance of the field, and 
148          * to access the property of the name on an object.</p>
149          * @since 1.0
150          * @javascript Re-compilers must resolve the member of this instance field to the
151          * identifier of the field name appending to the identifier resolved from its 
152          * qualifying member with a dot in between.
153          */
154         public final Value.String.Member tagName = new Value.String.Member(this, Members.tagName);
155     }
156 
157     /**
158      * <p>Casts an <b>opaque</b> object to the current <b>opaque</b> type by wrapping it
159      * with the wrapping constructor.</p>
160      * @param var The argument of an <b>opaque</b> object.
161      * @since 1.0
162      * @javascript Re-compilers must ignore the construction operation of this constructor,
163      * that is, replacing it with its only argument.
164      */
165     public JsElement(JsObject var) {
166         super(var);
167     }
168 
169     /**
170      * <p>An <b>opaque</b> static field defining a member that is named by the field name
171      * without a qualifying member and to access the property of the name on an object.</p>
172      * @since 1.0
173      * @javascript Re-compilers must resolve the member of this static field to the
174      * identifier of the field name.
175      */
176     public static final Value.String.Member tagName = new Value.String.Member(Members.tagName);
177     /**
178      * <p>An <b>opaque</b> static field defining a member that is named by the field name
179      * without a qualifying member and to access the property of the name on an object.</p>
180      * @since 1.0
181      * @javascript Re-compilers must resolve the member of this static field to the
182      * identifier of the field name.
183      */
184     public static final JsElement.Member firstChild      = new JsElement.Member(Members.firstChild     );
185     /**
186      * <p>An <b>opaque</b> static field defining a member that is named by the field name
187      * without a qualifying member and to access the property of the name on an object.</p>
188      * @since 1.0
189      * @javascript Re-compilers must resolve the member of this static field to the
190      * identifier of the field name.
191      */
192     public static final JsElement.Member lastChild       = new JsElement.Member(Members.lastChild      );
193     /**
194      * <p>An <b>opaque</b> static field defining a member that is named by the field name
195      * without a qualifying member and to access the property of the name on an object.</p>
196      * @since 1.0
197      * @javascript Re-compilers must resolve the member of this static field to the
198      * identifier of the field name.
199      */
200     public static final JsElement.Member nextSibling     = new JsElement.Member(Members.nextSibling    );
201     /**
202      * <p>An <b>opaque</b> static field defining a member that is named by the field name
203      * without a qualifying member and to access the property of the name on an object.</p>
204      * @since 1.0
205      * @javascript Re-compilers must resolve the member of this static field to the
206      * identifier of the field name.
207      */
208     public static final JsElement.Member parentNode      = new JsElement.Member(Members.parentNode     );
209     /**
210      * <p>An <b>opaque</b> static field defining a member that is named by the field name
211      * without a qualifying member and to access the property of the name on an object.</p>
212      * @since 1.0
213      * @javascript Re-compilers must resolve the member of this static field to the
214      * identifier of the field name.
215      */
216     public static final JsElement.Member previousSibling = new JsElement.Member(Members.previousSibling);
217 
218     @Override
219     /**
220      * <p>Returns the primitive value associated with the current instance, if there is one.
221      * This invocation simply returns the instance itself for the current instance is an 
222      * object and there is no primitive value for it.</p>
223      * @return The current object itself.
224      * @since 1.0
225      * @javascript Re-compilers must convert the instance invocation of this method directly
226      * into a JavaScript invocation on its current object instance without changing the 
227      * method name, but expanding variable arguments, if any, into comma-separated values. 
228      */
229     public JsElement valueOf() {
230         return new JsElement((JsObject)var().valueOf());
231     }
232     public final JsElement var(JsElement.Member r) {
233         return r.with(this);
234     }
235     /**
236      * <p>Adds an event handler function to the set of event handlers for this element. 
237      * This is a DOM-standard method supported by all modern browsers except IE.</p>
238      * <p>This method adds the specified event <tt>listener</tt> function to the set of 
239      * listeners registered on this node to handle events of the specified <tt>type</tt>. 
240      * If <tt>useCapture</tt> is <tt>true</tt>, the <tt>listener</tt> is registered as 
241      * a capturing event listener. If <tt>useCapture</tt> is <tt>false</tt>, it is 
242      * registered as a normal event listener.</p>
243      * <p>This method may be called multiple times to register multiple event handlers 
244      * for the same type of event on the same node. Note, however, that the DOM 
245      * Specification makes no guarantees about the order in which multiple event handlers 
246      * are invoked.</p>
247      * <p>If the same event listener function is registered twice on the same node with 
248      * the same <tt>type</tt> and <tt>useCapture</tt> arguments, the second registration 
249      * is simply ignored. If a new event listener is registered on this node while an 
250      * event is being handled at this node, the new event listener is not invoked for 
251      * that event.</p>
252      * <p>When a node is duplicated with {@link JsNode#cloneNode(Boolean)} or {@link JsDocument#importNode(JsNode, Boolean)}, 
253      * the event listeners registered for the original node are not copied.</p>
254      * <p>The same method is also defined by, and works analogously on, the {@link JsDocument} 
255      * and {@link JsWindow} objects</p>
256      * @param type The type of event for which the event listener is to be invoked.
257      * @param listener The event listener function that is invoked when an event of the 
258      * specified type is dispatched to this node. When invoked, the listener function 
259      * is passed an {@link JsEvent} object and is invoked as a method of the node on 
260      * which it is registered.
261      * @param useCapture If <tt>true</tt>, the specified <tt>listener</tt> is to be 
262      * invoked only during the capturing phase of event propagation. The more common 
263      * value of <tt>false</tt> means that the <tt>listener</tt> is not invoked during 
264      * the capturing phase but instead is invoked when this node is the actual event 
265      * target or when the event bubbles up to this node from its original target.
266      * @since 1.0
267      * @see #attachEvent(String, JsFunction)
268      * @see #removeEventListener(String, JsFunction, Boolean)
269      * @see JsDocument#addEventListener(String, JsFunction, Boolean)
270      * @see JsWindow#addEventListener(String, JsFunction, Boolean)
271      * @javascript Re-compilers must convert the instance invocation of this method directly
272      * into a JavaScript invocation on its current object instance without changing the 
273      * method name, but expanding variable arguments, if any, into comma-separated values. 
274      */
275     public final void addEventListener(String type, JsFunction<?> listener, Boolean useCapture) {
276         call(addEventListener, new Vars<Object>().add(type).add(listener).add(useCapture));
277     }
278     /**
279      * <p>Removes an event handler function from the set of handlers for this element. 
280      * This is a standard DOM method implemented by all modern browsers except IE.</p>
281      * <p>This method removes the specified event <tt>listener</tt> function. The <tt>type</tt> 
282      * and <tt>useCapture</tt> arguments must be the same as they are in the 
283      * corresponding call to {@link #addEventListener(String, JsFunction, Boolean)}. If 
284      * no event listener is found that matches the specified arguments, this method does 
285      * nothing.</p>
286      * <p>Once an event <tt>listener</tt> function has been removed by this method, it 
287      * will no longer be invoked for the specified <tt>type</tt> of event on this node. 
288      * This is true even if the event <tt>listener</tt> is removed by another event 
289      * listener registered for the same type of event on the same node.</p>
290      * <p>The same method is also defined by, and works analogously on, the {@link JsDocument} 
291      * and {@link JsWindow} objects</p>
292      * @param type The type of event for which the event listener is to be deleted.
293      * @param listener The event listener function that is to be removed.
294      * @param useCapture <tt>true</tt> if a capturing event listener is to be removed; 
295      * <tt>false</tt> if a normal event listener is to be removed.
296      * @since 1.0
297      * @see #detachEvent(String, JsFunction)
298      * @see #addEventListener(String, JsFunction, Boolean)
299      * @see JsDocument#removeEventListener(String, JsFunction, Boolean)
300      * @see JsWindow#removeEventListener(String, JsFunction, Boolean)
301      * @javascript Re-compilers must convert the instance invocation of this method directly
302      * into a JavaScript invocation on its current object instance without changing the 
303      * method name, but expanding variable arguments, if any, into comma-separated values. 
304      */
305     public final void removeEventListener(String type, JsFunction<?> listener, Boolean useCapture) {
306         call(removeEventListener, new Vars<Object>().add(type).add(listener).add(useCapture));
307     }
308     /**
309      * <p>Dispatches a synthetic event to this element.</p>
310      * <p>This method dispatches a synthetic event created with {@link JsDocument#createEvent(String)} 
311      * and initialized with the initialization method defined by the {@link JsEvent} 
312      * or one of its subclasses. The node on which this method is called becomes the 
313      * target of the event, but the event first propagates down the document tree 
314      * during the capturing phase, and then, if the {@link JsEvent#bubbles} property of 
315      * the event is <tt>true</tt>, it bubbles up the document tree after being handled 
316      * at the event target itself.</p>
317      * @param evt The {@link JsEvent} object to be dispatched.
318      * @return <tt>false</tt> if the {@link JsEvent#preventDefault()} method of <tt>evt</tt> 
319      * is called at any time during the propagation of the event, or <tt>true</tt> 
320      * otherwise.
321      * @throws RuntimeException JavaScript throws a {@link JsError} object if <tt>evt</tt> 
322      * is not initialized, or if its {@link JsEvent#type} property is <tt>null</tt> or 
323      * the empty string. See {@link Js#err(Object)} for JS Simulation.
324      * @since 1.0
325      * @see JsDocument#createEvent(String)
326      * @see JsEvent#initEvent(String, Boolean, Boolean)
327      * @see JsMouseEvent#initMouseEvent(String, Boolean, Boolean, JsWindow, Number, Number, Number, Number, Number, Boolean, Boolean, Boolean, Boolean, Number, JsElement)
328      * @see JsElement#dispatchEvent(JsEvent)
329      * @javascript Re-compilers must convert the instance invocation of this method directly
330      * into a JavaScript invocation on its current object instance without changing the 
331      * method name, but expanding variable arguments, if any, into comma-separated values. 
332      */
333     public final Boolean dispatchEvent(JsEvent evt) {
334         return call(dispatchEvent, evt);
335     }
336     /**
337      * <p>Adds an event handler function to the set of handlers for this element. 
338      * This is the IE-specific alternative to {@link #addEventListener(String, JsFunction, Boolean)}.</p>
339      * <p>This method is an IE-specific event registration method. It serves the same 
340      * purpose as the standard {@link #addEventListener(String, JsFunction, Boolean)} 
341      * method, which IE does not support, but is different from that function in several 
342      * important ways:
343      * <ul>
344      * <li>Since the IE event model does not support event capturing, this method and 
345      * {@link #detachEvent(String, JsFunction)} expect only two arguments: the event 
346      * type and the handler function.</li>
347      * <li>The event handler names passed to the IE methods should include the "on" 
348      * prefix.</li>
349      * <li>Functions registered with this method are invoked with no {@link JsEvent} 
350      * {@link JsWindow#event} property of 
351      * {@link JsWindow#window} object.</li>
352      * <li>Functions registered with this method are invoked as global functions, rather 
353      * than as methods of the node on which the event occurred. That is, when an event 
354      * handler registered with this method executes, the <tt>this</tt> keyword refers to 
355      * {@link JsWindow#window} object, not to the event's target node.</li>
356      * <li>This method allows the same event handler function to be registered more than 
357      * once. When an event of the specified type occurs, the registered function is 
358      * invoked as many times as it is registered.</li>
359      * </ul>
360      * </p>
361      * <p>The same method is also defined by, and works analogously on, the {@link JsDocument} 
362      * and {@link JsWindow} objects</p>
363      * @param type The type of event for which the event listener is to be invoked, with 
364      * a leading "on" prefix.
365      * @param listener The event listener function that is invoked when an event of the 
366      * specified type is dispatched to this node. This function is not passed any 
367      * {@link JsWindow#event} 
368      * property of the {@link JsWindow} object.
369      * @since 1.0
370      * @see #addEventListener(String, JsFunction, Boolean)
371      * @see #detachEvent(String, JsFunction)
372      * @see JsDocument#attachEvent(String, JsFunction)
373      * @see JsWindow#attachEvent(String, JsFunction)
374      * @javascript Re-compilers must convert the instance invocation of this method directly
375      * into a JavaScript invocation on its current object instance without changing the 
376      * method name, but expanding variable arguments, if any, into comma-separated values. 
377      */
378     public final void attachEvent(String type, JsFunction<?> listener) {
379         call(attachEvent, new Vars<Object>().add(type).add(listener));
380     }
381     /**
382      * <p>Removes an event handler function from this element. This is the IE-specific 
383      * alternative to the standard {@link #removeEventListener(String, JsFunction, Boolean)} 
384      * method.</p>
385      * <p>This method undoes the event handler function registration performed by the 
386      * {@link #attachEvent(String, JsFunction)} method. It is the IE-specific analog to 
387      * the standard {@link #removeEventListener(String, JsFunction, Boolean)}. To remove 
388      * an event handler function for a node, simply invoke this method with the same 
389      * arguments you originally passed to {@link #attachEvent(String, JsFunction)}.</p>
390      * <p>The same method is also defined by, and works analogously on, the {@link JsDocument} 
391      * and {@link JsWindow} objects</p>
392      * @param type The type of event for which the event listener is to be invoked, with 
393      * a leading "on" prefix.
394      * @param listener The event listener function that is to be removed.
395      * @since 1.0
396      * @see #removeEventListener(String, JsFunction, Boolean)
397      * @see #attachEvent(String, JsFunction)
398      * @see JsDocument#detachEvent(String, JsFunction)
399      * @see JsWindow#detachEvent(String, JsFunction)
400      * @javascript Re-compilers must convert the instance invocation of this method directly
401      * into a JavaScript invocation on its current object instance without changing the 
402      * method name, but expanding variable arguments, if any, into comma-separated values. 
403      */
404     public final void detachEvent(String type, JsFunction<?> listener) {
405         call(detachEvent, new Vars<Object>().add(type).add(listener));
406     }
407     /**
408      * <p>Fires a specified event on the object.</p>
409      * <p>This method is IE-specific.</p>
410      * @param evt The {@link JsEvent} object to be dispatched.
411      * @return <tt>false</tt> if the {@link JsEvent#preventDefault()} method of <tt>evt</tt> 
412      * is called at any time during the propagation of the event, or <tt>true</tt> 
413      * otherwise.
414      * @throws RuntimeException JavaScript throws a {@link JsError} object if <tt>evt</tt> 
415      * is not initialized, or if its {@link JsEvent#type} property is <tt>null</tt> or 
416      * the empty string. See {@link Js#err(Object)} for JS Simulation.
417      * @since 1.0
418      * @see JsDocument#createEvent(String)
419      * @see JsEvent#initEvent(String, Boolean, Boolean)
420      * @see JsMouseEvent#initMouseEvent(String, Boolean, Boolean, JsWindow, Number, Number, Number, Number, Number, Boolean, Boolean, Boolean, Boolean, Number, JsElement)
421      * @see JsElement#dispatchEvent(JsEvent)
422      * @javascript Re-compilers must convert the instance invocation of this method directly
423      * into a JavaScript invocation on its current object instance without changing the 
424      * method name, but expanding variable arguments, if any, into comma-separated values. 
425      */
426     public final Boolean fireEvent(JsEvent evt) {
427         return call(fireEvent, evt);
428     }
429     /**
430      * <p>Returns the value of a named attribute as a string.</p>
431      * <p>This method returns the value of a named attribute of an element. Note that 
432      * the {@link JsHTMLElement} objects have JavaScript properties that match each of 
433      * the standard HTML attributes, so you need to use this method with HTML documents 
434      * only if you are querying the value of nonstandard attributes.</p>
435      * <p>In XML documents, attribute values are not available directly as element 
436      * properties and must be looked up by calling this method. For XML documents that 
437      * use name spaces, use {@link #getAttributeNS(String, String)}.</p>
438      * @param name The name of the attribute whose value is to be returned.
439      * @return The value of the named attribute as a string. If the attribute is not 
440      * defined, this method is supposed to return an empty string. Some implementations 
441      * return <tt>null</tt> in this case, however.
442      * @since 1.0
443      * @see #getAttribute(StringLike)
444      * @see #getAttributeNS(String, String)
445      * @javascript Re-compilers must convert the instance invocation of this method directly
446      * into a JavaScript invocation on its current object instance without changing the 
447      * method name, but expanding variable arguments, if any, into comma-separated values. 
448      */
449     public final String getAttribute(String name) {
450         return call(getAttribute, name);
451     }
452     /**
453      * <p>Returns the value of a named attribute as a string.</p>
454      * <p>This method returns the value of a named attribute of an element. Note that 
455      * the {@link JsHTMLElement} objects have JavaScript properties that match each of 
456      * the standard HTML attributes, so you need to use this method with HTML documents 
457      * only if you are querying the value of nonstandard attributes.</p>
458      * <p>In XML documents, attribute values are not available directly as element 
459      * properties and must be looked up by calling this method. For XML documents that 
460      * use name spaces, use {@link #getAttributeNS(String, String)}.</p>
461      * @param name The name of the attribute whose value is to be returned.
462      * @return The value of the named attribute as a string. If the attribute is not 
463      * defined, this method is supposed to return an empty string. Some implementations 
464      * return <tt>null</tt> in this case, however.
465      * @since 1.0
466      * @see #getAttribute(String)
467      * @see #getAttributeNS(String, String)
468      * @javascript Re-compilers must convert the instance invocation of this method directly
469      * into a JavaScript invocation on its current object instance without changing the 
470      * method name, but expanding variable arguments, if any, into comma-separated values. 
471      */
472     public final String getAttribute(StringLike name) {
473         return getAttribute(Js.valueOf(name));
474     }
475     /**
476      * <p>Returns the value of a named attribute as a {@link JsAttr} node.</p>
477      * <p>Note that this {@link JsAttr} node can also be obtained through the 
478      * {@link JsNode#attributes} property inherited from {@link JsNode}.</p>
479      * @param name The name of the desired attribute.
480      * @return A {@link JsAttr} node that represents the value of the named attribute, 
481      * or <tt>null</tt> if this element has no such attribute.
482      * @since 1.0
483      * @see #getAttributeNode(StringLike)
484      * @see #getAttributeNodeNS(String, String)
485      * @javascript Re-compilers must convert the instance invocation of this method directly
486      * into a JavaScript invocation on its current object instance without changing the 
487      * method name, but expanding variable arguments, if any, into comma-separated values. 
488      */
489     public final JsAttr getAttributeNode(String name) {
490         return new JsAttr(call(getAttributeNode, name));
491     }
492     /**
493      * <p>Returns the value of a named attribute as a {@link JsAttr} node.</p>
494      * <p>Note that this {@link JsAttr} node can also be obtained through the 
495      * {@link JsNode#attributes} property inherited from {@link JsNode}.</p>
496      * @param name The name of the desired attribute.
497      * @return A {@link JsAttr} node that represents the value of the named attribute, 
498      * or <tt>null</tt> if this element has no such attribute.
499      * @since 1.0
500      * @see #getAttributeNode(String)
501      * @see #getAttributeNodeNS(String, String)
502      * @javascript Re-compilers must convert the instance invocation of this method directly
503      * into a JavaScript invocation on its current object instance without changing the 
504      * method name, but expanding variable arguments, if any, into comma-separated values. 
505      */
506     public final JsAttr getAttributeNode(StringLike name) {
507         return getAttributeNode(Js.valueOf(name));
508     }
509     /**
510      * <p>Returns the string value of an attribute specified by local name and name space URI.</p> 
511      * <p>This method is useful only with XML documents that use name spaces and works 
512      * just like the {@link #getAttribute(String)} method, except that the attribute is 
513      * specified by a combination of name space URI and local name within that name 
514      * space.</p>
515      * @param namespaceURI The URI that uniquely identifies the name space of this 
516      * attribute or <tt>null</tt> for no name space.
517      * @param localName The identifier that specifies the name of the attribute within 
518      * its name space.
519      * @return The value of the named attribute, as a string. If the attribute is not 
520      * defined, this method is supposed to return an empty string, but some implementations 
521      * return <tt>null</tt> instead.
522      * @since 1.0
523      * @see #getAttribute(String)
524      * @see #getAttributeNodeNS(String, String)
525      * @javascript Re-compilers must convert the instance invocation of this method directly
526      * into a JavaScript invocation on its current object instance without changing the 
527      * method name, but expanding variable arguments, if any, into comma-separated values. 
528      */
529     public final String getAttributeNS(String namespaceURI, String localName) {
530         return call(getAttributeNS, new Vars<Object>().add(namespaceURI).add(localName));
531     }
532     /**
533      * <p>Returns the {@link JsAttr} node of an attribute specified by local name and 
534      * name space URI.</p>
535      * <p>This method is useful only with XML documents that use name spaces and works 
536      * just like {@link #getAttributeNode(String)} method, except that the attribute is 
537      * specified by the combination of a name space URI and a local name defined within 
538      * that name space.</p>
539      * @param namespaceURI The URI that uniquely identifies the name space of this 
540      * attribute or <tt>null</tt> for no name space.
541      * @param localName The identifier that specifies the name of the attribute within 
542      * its name space.
543      * @return The {@link JsAttr} node that represents the value of the specified 
544      * attribute, or <tt>null</tt> if this element has no such attribute.
545      * @since 1.0
546      * @see #getAttributeNode(String)
547      * @see #getAttributeNS(String, String)
548      * @javascript Re-compilers must convert the instance invocation of this method directly
549      * into a JavaScript invocation on its current object instance without changing the 
550      * method name, but expanding variable arguments, if any, into comma-separated values. 
551      */
552     public final JsAttr getAttributeNodeNS(String namespaceURI, String localName) {
553         return new JsAttr(call(getAttributeNodeNS, new Vars<Object>().add(namespaceURI).add(localName)));
554     }
555     /**
556      * <p>Returns an array, technically a {@link JsNodeList} object, of all {@link JsElement} 
557      * nodes in the current document that have the specified tag name by traversing all 
558      * descendants of this element. The {@link JsElement} nodes appear in the returned 
559      * array in the same order in which they appear in the document source.</p>
560      * <p>Note that the {@link JsDocument#getElementsByTagName(String)} method works 
561      * just like this one but that traverses the entire document, rather than just the 
562      * descendants of a single element. Do not confuse this method with {@link JsHTMLDocument#getElementsByName(String)}, 
563      * which searches for elements based on the value of their <tt>name</tt> attributes 
564      * rather than by their tag names.</p>
565      * @param name The tag name of the desired elements, or the value "*" to specify 
566      * that all descendant elements should be returned, regardless of their tag names.
567      * @return An read-only array, technically a {@link JsNodeList} object, of 
568      * {@link JsElement} nodes that are descendants of this element and have the 
569      * specified tag name.
570      * @since 1.0
571      * @see #getElementsByTagName(StringLike)
572      * @see JsDocument#getElementsByTagName(String)
573      * @see JsDocument#getElementById(String)
574      * @see JsHTMLDocument#getElementsByName(String)
575      * @javascript Re-compilers must convert the instance invocation of this method directly
576      * into a JavaScript invocation on its current object instance without changing the 
577      * method name, but expanding variable arguments, if any, into comma-separated values. 
578      */
579     public final JsNodeList<? extends JsElement> getElementsByTagName(String name) {
580         return new JsNodeList<JsElement>(call(getElementsByTagName, name));
581     }
582     /**
583      * <p>Returns an array, technically a {@link JsNodeList} object, of all {@link JsElement} 
584      * nodes in the current document that have the specified tag name by traversing all 
585      * descendants of this element. The {@link JsElement} nodes appear in the returned 
586      * array in the same order in which they appear in the document source.</p>
587      * <p>Note that the {@link JsDocument#getElementsByTagName(StringLike)} method works 
588      * just like this one but that traverses the entire document, rather than just the 
589      * descendants of a single element. Do not confuse this method with {@link JsHTMLDocument#getElementsByName(StringLike)}, 
590      * which searches for elements based on the value of their <tt>name</tt> attributes 
591      * rather than by their tag names.</p>
592      * @param name The tag name of the desired elements, or the value "*" to specify 
593      * that all descendant elements should be returned, regardless of their tag names.
594      * @return An read-only array, technically a {@link JsNodeList} object, of 
595      * {@link JsElement} nodes that are descendants of this element and have the 
596      * specified tag name.
597      * @since 1.0
598      * @see #getElementsByTagName(String)
599      * @see JsDocument#getElementsByTagName(StringLike)
600      * @see JsDocument#getElementById(StringLike)
601      * @see JsHTMLDocument#getElementsByName(StringLike)
602      * @javascript Re-compilers must convert the instance invocation of this method directly
603      * into a JavaScript invocation on its current object instance without changing the 
604      * method name, but expanding variable arguments, if any, into comma-separated values. 
605      */
606     public final JsNodeList<? extends JsElement> getElementsByTagName(StringLike name) {
607         return getElementsByTagName(Js.valueOf(name));
608     }
609     /**
610      * <p>Returns an array of all {@link JsElement} nodes in the current document that 
611      * have the specified tag name and name-space by traversing all descendants of this 
612      * element.</p>
613      * <p>This method works like {@link #getElementsByTagName(String)}, except that the 
614      * tag name of the desired elements is specified as a combination of a name space 
615      * URI and a local name defined within that name space. This method is useful only 
616      * with XML documents that use name spaces.</p>
617      * @param namespaceURI The URI that uniquely identifies the name space of the 
618      * desired elements.
619      * @param localName The identifier that specifies the name of the desired elements 
620      * within its name space.
621      * @return A read-only array, technically a {@link JsNodeList} object, of all {@link JsElement} 
622      * nodes in the current document that have the specified name and name space.
623      * @since 1.0
624      * @see JsDocument#getElementsByTagNameNS(String, String)
625      * @javascript Re-compilers must convert the instance invocation of this method directly
626      * into a JavaScript invocation on its current object instance without changing the 
627      * method name, but expanding variable arguments, if any, into comma-separated values. 
628      */
629     public final JsNodeList<? extends JsElement> getElementsByTagNameNS(String namespaceURI, String localName) {
630         return new JsNodeList<JsElement>(call(getElementsByTagNameNS, new Vars<Object>().add(namespaceURI).add(localName)));
631     }
632     /**
633      * <p>Determines whether this element has an attribute with the specified name.</p>
634      * <p>Note that this method does not return the value of that attribute but returns 
635      * <tt>true</tt> if the named attribute is explicitly specified in the document and 
636      * also if the named attribute has a default value specified by the internal subset 
637      * of the document type.</p>
638      * @param name The name of the desired attribute.
639      * @return <tt>true</tt> if this element has a specified or default value for the 
640      * named attribute, or <tt>false</tt> otherwise.
641      * @since 1.0
642      * @see #hasAttribute(StringLike)
643      * @see #getAttribute(String)
644      * @see #setAttribute(String, Object)
645      * @javascript Re-compilers must convert the instance invocation of this method directly
646      * into a JavaScript invocation on its current object instance without changing the 
647      * method name, but expanding variable arguments, if any, into comma-separated values. 
648      */
649     public final Boolean hasAttribute(String name) {
650         return call(hasAttribute, name);
651     }
652     /**
653      * <p>Determines whether this element has an attribute with the specified name.</p>
654      * <p>Note that this method does not return the value of that attribute but returns 
655      * <tt>true</tt> if the named attribute is explicitly specified in the document and 
656      * also if the named attribute has a default value specified by the internal subset 
657      * of the document type.</p>
658      * @param name The name of the desired attribute.
659      * @return <tt>true</tt> if this element has a specified or default value for the 
660      * named attribute, or <tt>false</tt> otherwise.
661      * @since 1.0
662      * @see #hasAttribute(String)
663      * @see #getAttribute(StringLike)
664      * @see #setAttribute(String, Object)
665      * @javascript Re-compilers must convert the instance invocation of this method directly
666      * into a JavaScript invocation on its current object instance without changing the 
667      * method name, but expanding variable arguments, if any, into comma-separated values. 
668      */
669     public final Boolean hasAttribute(StringLike name) {
670         return hasAttribute(Js.valueOf(name));
671     }
672     /**
673      * <p>Determines whether this element has an attribute with the specified a combination of 
674      * local name and name space URI.</p>
675      * <p>This method is useful only with XML documents that use name spaces and works 
676      * just like {@link #hasAttribute(String)} method, except that the attribute to 
677      * be checked for is specified by the combination of a name space URI and a local 
678      * name defined within that name space.</p>
679      * @param namespaceURI The unique name space identifier for the attribute, or <tt>null</tt> 
680      * for no name space.
681      * @param localName The name of the attribute within the specified name space. 
682      * @return <tt>true</tt> if this element has a specified or default value for the 
683      * named attribute, or <tt>false</tt> otherwise.
684      * @since 1.0
685      * @see #hasAttribute(String)
686      * @see #getAttributeNS(String, String)
687      * @see #setAttributeNS(String, String, String)
688      * @javascript Re-compilers must convert the instance invocation of this method directly
689      * into a JavaScript invocation on its current object instance without changing the 
690      * method name, but expanding variable arguments, if any, into comma-separated values. 
691      */
692     public final Boolean hasAttributeNS(String namespaceURI, String localName) {
693         return call(hasAttributeNS, new Vars<Object>().add(namespaceURI).add(localName));
694     }
695     /**
696      * <p>Removes the named attribute from this element.</p>
697      * <p>This method deletes a named attribute from this element. If the named attribute 
698      * has a default value specified by the document type, subsequent calls to this method 
699      * return that default value. Attempts to remove nonexistent attributes or attributes 
700      * that are not specified but have a default value are silently ignored.</p>
701      * @param name The name of the desired attribute.
702      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
703      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
704      * if this element is read-only and does not allow its attributes to be removed. See 
705      * {@link Js#err(Object)} for JS Simulation.
706      * @since 1.0
707      * @see #removeAttribute(StringLike)
708      * @see #getAttribute(String)
709      * @see #setAttribute(String, Object)
710      * @javascript Re-compilers must convert the instance invocation of this method directly
711      * into a JavaScript invocation on its current object instance without changing the 
712      * method name, but expanding variable arguments, if any, into comma-separated values. 
713      */
714     public final void removeAttribute(String name) {
715         call(removeAttribute, name);
716     }
717     /**
718      * <p>Removes the named attribute from this element.</p>
719      * <p>This method deletes a named attribute from this element. If the named attribute 
720      * has a default value specified by the document type, subsequent calls to this method 
721      * return that default value. Attempts to remove nonexistent attributes or attributes 
722      * that are not specified but have a default value are silently ignored.</p>
723      * @param name The name of the desired attribute.
724      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
725      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
726      * if this element is read-only and does not allow its attributes to be removed. See 
727      * {@link Js#err(Object)} for JS Simulation.
728      * @since 1.0
729      * @see #removeAttribute(String)
730      * @see #getAttribute(StringLike)
731      * @see #setAttribute(String, Object)
732      * @javascript Re-compilers must convert the instance invocation of this method directly
733      * into a JavaScript invocation on its current object instance without changing the 
734      * method name, but expanding variable arguments, if any, into comma-separated values. 
735      */
736     public final void removeAttribute(StringLike name) {
737         removeAttribute(Js.valueOf(name));
738     }
739     /**
740      * <p>Removes the specified {@link JsAttr} node from the list of attributes for 
741      * this element.</p>
742      * <p>This method removes and returns a {@link JsAttr} node from the set of attributes 
743      * of an element. If the removed attribute has a default value specified by the DTD, 
744      * a new {@link JsAttr} node is added representing this default value. It is often 
745      * simpler to use {@link #removeAttribute(String)} instead of this method.</p>
746      * @param attr The {@link JsAttr} node to be removed from the element.
747      * @return The {@link JsAttr} node that was removed.
748      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
749      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
750      * if this element is read-only and does not allow its attributes to be removed or the value 
751      * {@link JsDOMException#NOT_FOUND_ERR} if <tt>attr</tt>is not an attribute of this 
752      * element. See {@link Js#err(Object)} for JS Simulation.
753      * @since 1.0
754      * @see #removeAttribute(String)
755      * @javascript Re-compilers must convert the instance invocation of this method directly
756      * into a JavaScript invocation on its current object instance without changing the 
757      * method name, but expanding variable arguments, if any, into comma-separated values. 
758      */
759     public final JsAttr removeAttributeNode(JsAttr attr) {
760         return new JsAttr(call(removeAttributeNode, attr));
761     }
762     /**
763      * <p>Removes, from this element, an attribute with the specified a combination of 
764      * local name and name space URI.</p>
765      * <p>This method is useful only with XML documents that use name spaces and works 
766      * just like {@link #removeAttribute(String)} method, except that the attribute to 
767      * be removed is specified by the combination of a name space URI and a local name 
768      * defined within that name space.</p>
769      * @param namespaceURI The URI that uniquely identifies the name space of this 
770      * attribute or <tt>null</tt> for no name space.
771      * @param localName The identifier that specifies the name of the attribute within 
772      * its name space.
773      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
774      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
775      * if this element is read-only and does not allow its attributes to be removed. See 
776      * {@link Js#err(Object)} for JS Simulation.
777      * @since 1.0
778      * @see #getAttributeNS(String, String)
779      * @see #removeAttribute(String)
780      * @see #setAttributeNS(String, String, String)
781      * @javascript Re-compilers must convert the instance invocation of this method directly
782      * into a JavaScript invocation on its current object instance without changing the 
783      * method name, but expanding variable arguments, if any, into comma-separated values. 
784      */
785     public final void removeAttributeNS(String namespaceURI, String localName) {
786         call(removeAttributeNS, new Vars<Object>().add(namespaceURI).add(localName));
787     }
788     /**
789      * <p>Sets or adds the named attribute to the specified string value.</p>
790      * <p>This method sets the specified attribute to the specified value. If no 
791      * attribute by that name already exists, a new one is created.</p>
792      * <p>Note that {@link JsHTMLElement} objects of an HTML document define JavaScript 
793      * properties that correspond to all standard HTML attributes. Thus, you need to use 
794      * this method only if you want to set a nonstandard attribute.</p>
795      * @param name The name of the attribute to be created or modified.
796      * @param value The string value of the attribute.
797      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
798      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
799      * if this element is read-only and does not allow its attributes to be removed or 
800      * the value {@link JsDOMException#INVALID_CHARACTER_ERR} if the <tt>name</tt> argument 
801      * contains a character that is not allowed in HTML or XML attribute names. See 
802      * {@link Js#err(Object)} for JS Simulation.
803      * @since 1.0
804      * @see #getAttribute(String)
805      * @see #removeAttribute(String)
806      * @see #setAttributeNode(JsAttr)
807      * @javascript Re-compilers must convert the instance invocation of this method directly
808      * into a JavaScript invocation on its current object instance without changing the 
809      * method name, but expanding variable arguments, if any, into comma-separated values. 
810      */
811     public final void setAttribute(String name, Object value) {
812         call(setAttribute, new Vars<Object>().add(name).add(value));
813     }
814     /**
815      * <p>Sets or adds the specified {@link JsAttr} node to the list of attributes for 
816      * this element.</p>
817      * <p>If an attribute with the same name already exists for this element, <tt>attr</tt> 
818      * replaces that attribute, and the replaced {@link JsAttr} node is returned. If no 
819      * such attribute already exists, this method defines a new attribute for the 
820      * element.</p>
821      * <p>It is usually easier to use {@link #setAttribute(String, Object)} instead of 
822      * this method.</p>
823      * @param attr The {@link JsAttr} node that represents the attribute to be added or 
824      * whose value is to be modified.
825      * @return The {@link JsAttr} node that was replaced by <tt>attr</tt>, or <tt>null</tt> 
826      * if no attribute was replaced.
827      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
828      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
829      * if this element is read-only and does not allow its attributes to be removed, 
830      * the value {@link JsDOMException#INUSE_ATTRIBUTE_ERR} if <tt>attr</tt> is already 
831      * a member of the attribute set of some other {@link JsElement} node, or the value 
832      * {@link JsDOMException#WRONG_DOCUMENT_ERR} if <tt>attr</tt> has a different {@link JsNode#ownerDocument} 
833      * property than the {@link JsElement} node on which it is being set. See 
834      * {@link Js#err(Object)} for JS Simulation.
835      * @since 1.0
836      * @see #getAttribute(StringLike)
837      * @javascript Re-compilers must convert the instance invocation of this method directly
838      * into a JavaScript invocation on its current object instance without changing the 
839      * method name, but expanding variable arguments, if any, into comma-separated values. 
840      */
841     public final JsAttr setAttributeNode(JsAttr attr) {
842         return new JsAttr(call(setAttributeNode, attr));
843     }
844     /**
845      * <p>Sets or adds the specified {@link JsAttr} node to the list of attributes for 
846      * this element.</p>
847      * <p>This method is useful only with XML documents that use name spaces and works 
848      * just like {@link #setAttributeNodeNS(JsAttr)} method, except that it is designed 
849      * for use with {@link JsAttr} nodes that represent attributes specified by name 
850      * space and name.</p>
851      * @param attr The {@link JsAttr} node that represents the attribute to be added or 
852      * whose value is to be modified.
853      * @return The {@link JsAttr} node that was replaced by <tt>attr</tt>, or <tt>null</tt> 
854      * if no attribute was replaced.
855      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
856      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
857      * if this element is read-only and does not allow its attributes to be removed, 
858      * the value {@link JsDOMException#INUSE_ATTRIBUTE_ERR} if <tt>attr</tt> is already 
859      * a member of the attribute set of some other {@link JsElement} node, the value 
860      * {@link JsDOMException#WRONG_DOCUMENT_ERR} if <tt>attr</tt> has a different {@link JsNode#ownerDocument} 
861      * property than the {@link JsElement} node on which it is being set, or the value 
862      * {@link JsDOMException#NOT_SUPPORTED_ERR} if the DOM implementation of the browser 
863      * does not support XML documents. See {@link Js#err(Object)} for JS Simulation.
864      * @since 1.0
865      * @see JsDocument#createAttributeNS(String, String)
866      * @see #setAttributeNS(String, String, String)
867      * @see #setAttributeNode(JsAttr)
868      * @javascript Re-compilers must convert the instance invocation of this method directly
869      * into a JavaScript invocation on its current object instance without changing the 
870      * method name, but expanding variable arguments, if any, into comma-separated values. 
871      */
872     public final JsAttr setAttributeNodeNS(JsAttr attr) {
873         return new JsAttr(call(setAttributeNodeNS, attr));
874     }
875     /**
876      * <p>Sets or adds, to the list of attributes for this element, an attribute with 
877      * the specified a combination of local name and name space URI.</p>
878      * <p>This method is useful only with XML documents that use name spaces and works 
879      * just like {@link #setAttribute(String, Object)} method, except that the attribute 
880      * is specified by the combination of a name space URI and a local name defined 
881      * within that name space.</p>
882      * @param namespaceURI The URI that uniquely identifies the name space of the 
883      * attribute to be set or created, or <tt>null</tt> for no name space.
884      * @param qualifiedName The name of the attribute, specified as an optional name 
885      * space prefix and colon followed by the local name within the name space.
886      * @param value The new value of the attribute.
887      * @throws RuntimeException JavaScript throws a {@link JsDOMException} object with 
888      * the {@link JsDOMException#code} property of the value {@link JsDOMException#NO_MODIFICATION_ALLOWED_ERR} 
889      * if this element is read-only and does not allow its attributes to be removed, 
890      * the value {@link JsDOMException#INVALID_CHARACTER_ERR} if <tt>qualifiedName</tt> 
891      * argument contains a character that is not allowed in HTML or XML attribute names, 
892      * the value {@link JsDOMException#NAMESPACE_ERR} if <tt>qualifiedName</tt> is 
893      * malformed, or there is a mismatch between the name space prefix of <tt>qualifiedName</tt> 
894      * and the <tt>namespaceURI</tt> argument, or the value {@link JsDOMException#NOT_SUPPORTED_ERR} 
895      * if the DOM implementation of the browser does not support XML documents. See 
896      * {@link Js#err(Object)} for JS Simulation.
897      * @since 1.0
898      * @see #setAttribute(String, Object)
899      * @see #setAttributeNode(JsAttr)
900      * @javascript Re-compilers must convert the instance invocation of this method directly
901      * into a JavaScript invocation on its current object instance without changing the 
902      * method name, but expanding variable arguments, if any, into comma-separated values. 
903      */
904     public final void setAttributeNS(String namespaceURI, String qualifiedName, String value) {
905         call(setAttributeNS, new Vars<Object>().add(namespaceURI).add(qualifiedName).add(value));
906     }
907 }