View Javadoc
1   /*
2    * Copyright (c) 2002-2017 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package com.gargoylesoftware.htmlunit.javascript.host.html;
16  
17  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_COLOR_RESTRICT;
18  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_COLOR_TO_LOWER;
19  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ALIGN_ACCEPTS_ARBITRARY_VALUES;
20  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INNER_TEXT_VALUE_NULL;
21  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_OFFSET_PARENT_NULL_IF_FIXED;
22  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES;
23  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
24  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
25  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
26  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
27  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
28  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
29  
30  import java.io.IOException;
31  import java.lang.reflect.InvocationTargetException;
32  import java.lang.reflect.Method;
33  import java.net.MalformedURLException;
34  import java.net.URL;
35  import java.util.ArrayList;
36  import java.util.HashMap;
37  import java.util.HashSet;
38  import java.util.List;
39  import java.util.Locale;
40  import java.util.Map;
41  import java.util.Set;
42  import java.util.regex.Pattern;
43  
44  import org.apache.commons.lang3.ArrayUtils;
45  import org.apache.commons.logging.Log;
46  import org.apache.commons.logging.LogFactory;
47  import org.xml.sax.helpers.AttributesImpl;
48  
49  import com.gargoylesoftware.htmlunit.SgmlPage;
50  import com.gargoylesoftware.htmlunit.WebClient;
51  import com.gargoylesoftware.htmlunit.html.DomAttr;
52  import com.gargoylesoftware.htmlunit.html.DomElement;
53  import com.gargoylesoftware.htmlunit.html.DomNode;
54  import com.gargoylesoftware.htmlunit.html.DomText;
55  import com.gargoylesoftware.htmlunit.html.HtmlAbbreviated;
56  import com.gargoylesoftware.htmlunit.html.HtmlAcronym;
57  import com.gargoylesoftware.htmlunit.html.HtmlAddress;
58  import com.gargoylesoftware.htmlunit.html.HtmlArticle;
59  import com.gargoylesoftware.htmlunit.html.HtmlAside;
60  import com.gargoylesoftware.htmlunit.html.HtmlBaseFont;
61  import com.gargoylesoftware.htmlunit.html.HtmlBidirectionalIsolation;
62  import com.gargoylesoftware.htmlunit.html.HtmlBidirectionalOverride;
63  import com.gargoylesoftware.htmlunit.html.HtmlBig;
64  import com.gargoylesoftware.htmlunit.html.HtmlBody;
65  import com.gargoylesoftware.htmlunit.html.HtmlBold;
66  import com.gargoylesoftware.htmlunit.html.HtmlCenter;
67  import com.gargoylesoftware.htmlunit.html.HtmlCitation;
68  import com.gargoylesoftware.htmlunit.html.HtmlCode;
69  import com.gargoylesoftware.htmlunit.html.HtmlDefinition;
70  import com.gargoylesoftware.htmlunit.html.HtmlDefinitionDescription;
71  import com.gargoylesoftware.htmlunit.html.HtmlDefinitionTerm;
72  import com.gargoylesoftware.htmlunit.html.HtmlDivision;
73  import com.gargoylesoftware.htmlunit.html.HtmlElement;
74  import com.gargoylesoftware.htmlunit.html.HtmlEmphasis;
75  import com.gargoylesoftware.htmlunit.html.HtmlExample;
76  import com.gargoylesoftware.htmlunit.html.HtmlFigure;
77  import com.gargoylesoftware.htmlunit.html.HtmlFigureCaption;
78  import com.gargoylesoftware.htmlunit.html.HtmlFooter;
79  import com.gargoylesoftware.htmlunit.html.HtmlHeader;
80  import com.gargoylesoftware.htmlunit.html.HtmlItalic;
81  import com.gargoylesoftware.htmlunit.html.HtmlKeyboard;
82  import com.gargoylesoftware.htmlunit.html.HtmlLayer;
83  import com.gargoylesoftware.htmlunit.html.HtmlListing;
84  import com.gargoylesoftware.htmlunit.html.HtmlMain;
85  import com.gargoylesoftware.htmlunit.html.HtmlMark;
86  import com.gargoylesoftware.htmlunit.html.HtmlNav;
87  import com.gargoylesoftware.htmlunit.html.HtmlNoBreak;
88  import com.gargoylesoftware.htmlunit.html.HtmlNoEmbed;
89  import com.gargoylesoftware.htmlunit.html.HtmlNoFrames;
90  import com.gargoylesoftware.htmlunit.html.HtmlNoLayer;
91  import com.gargoylesoftware.htmlunit.html.HtmlNoScript;
92  import com.gargoylesoftware.htmlunit.html.HtmlPage;
93  import com.gargoylesoftware.htmlunit.html.HtmlPlainText;
94  import com.gargoylesoftware.htmlunit.html.HtmlRp;
95  import com.gargoylesoftware.htmlunit.html.HtmlRt;
96  import com.gargoylesoftware.htmlunit.html.HtmlRuby;
97  import com.gargoylesoftware.htmlunit.html.HtmlS;
98  import com.gargoylesoftware.htmlunit.html.HtmlSample;
99  import com.gargoylesoftware.htmlunit.html.HtmlSection;
100 import com.gargoylesoftware.htmlunit.html.HtmlSmall;
101 import com.gargoylesoftware.htmlunit.html.HtmlStrike;
102 import com.gargoylesoftware.htmlunit.html.HtmlStrong;
103 import com.gargoylesoftware.htmlunit.html.HtmlSubscript;
104 import com.gargoylesoftware.htmlunit.html.HtmlSummary;
105 import com.gargoylesoftware.htmlunit.html.HtmlSuperscript;
106 import com.gargoylesoftware.htmlunit.html.HtmlTable;
107 import com.gargoylesoftware.htmlunit.html.HtmlTableDataCell;
108 import com.gargoylesoftware.htmlunit.html.HtmlTeletype;
109 import com.gargoylesoftware.htmlunit.html.HtmlUnderlined;
110 import com.gargoylesoftware.htmlunit.html.HtmlVariable;
111 import com.gargoylesoftware.htmlunit.html.HtmlWordBreak;
112 import com.gargoylesoftware.htmlunit.html.SubmittableElement;
113 import com.gargoylesoftware.htmlunit.javascript.background.BackgroundJavaScriptFactory;
114 import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJob;
115 import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
116 import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
117 import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
118 import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
119 import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
120 import com.gargoylesoftware.htmlunit.javascript.host.ClientRect;
121 import com.gargoylesoftware.htmlunit.javascript.host.Element;
122 import com.gargoylesoftware.htmlunit.javascript.host.Window;
123 import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleDeclaration;
124 import com.gargoylesoftware.htmlunit.javascript.host.css.ComputedCSSStyleDeclaration;
125 import com.gargoylesoftware.htmlunit.javascript.host.css.StyleAttributes;
126 import com.gargoylesoftware.htmlunit.javascript.host.dom.DOMStringMap;
127 import com.gargoylesoftware.htmlunit.javascript.host.dom.DOMTokenList;
128 import com.gargoylesoftware.htmlunit.javascript.host.dom.Node;
129 import com.gargoylesoftware.htmlunit.javascript.host.dom.NodeList;
130 import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
131 import com.gargoylesoftware.htmlunit.javascript.host.event.EventHandler;
132 import com.gargoylesoftware.htmlunit.javascript.host.event.MouseEvent;
133 
134 import net.sourceforge.htmlunit.corejs.javascript.Context;
135 import net.sourceforge.htmlunit.corejs.javascript.Function;
136 import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
137 
138 /**
139  * The JavaScript object {@code HTMLElement} which is the base class for all HTML
140  * objects. This will typically wrap an instance of {@link HtmlElement}.
141  *
142  * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
143  * @author David K. Taylor
144  * @author Barnaby Court
145  * @author <a href="mailto:cse@dynabean.de">Christian Sell</a>
146  * @author Chris Erskine
147  * @author David D. Kilzer
148  * @author Daniel Gredler
149  * @author Marc Guillemot
150  * @author Hans Donner
151  * @author Bruce Faulkner
152  * @author Ahmed Ashour
153  * @author Sudhan Moghe
154  * @author Ronald Brill
155  * @author Frank Danek
156  */
157 @JsxClass(domClass = HtmlAbbreviated.class, value = {CHROME, FF})
158 @JsxClass(domClass = HtmlAcronym.class, value = {CHROME, FF})
159 @JsxClass(domClass = HtmlAddress.class, value = {CHROME, FF})
160 @JsxClass(domClass = HtmlArticle.class)
161 @JsxClass(domClass = HtmlAside.class)
162 @JsxClass(domClass = HtmlBaseFont.class, value = {CHROME, FF})
163 @JsxClass(domClass = HtmlBidirectionalIsolation.class, value = CHROME)
164 @JsxClass(domClass = HtmlBidirectionalOverride.class, value = {CHROME, FF})
165 @JsxClass(domClass = HtmlBig.class, value = {CHROME, FF})
166 @JsxClass(domClass = HtmlBold.class, value = {CHROME, FF})
167 @JsxClass(domClass = HtmlCenter.class, value = {CHROME, FF, EDGE})
168 @JsxClass(domClass = HtmlCitation.class, value = {CHROME, FF})
169 @JsxClass(domClass = HtmlCode.class, value = {CHROME, FF})
170 @JsxClass(domClass = HtmlDefinition.class, value = {CHROME, FF})
171 @JsxClass(domClass = HtmlDefinitionDescription.class, value = {CHROME, FF})
172 @JsxClass(domClass = HtmlDefinitionTerm.class, value = {CHROME, FF})
173 @JsxClass(domClass = HtmlElement.class, value = {FF, IE})
174 @JsxClass(domClass = HtmlEmphasis.class, value = {CHROME, FF})
175 @JsxClass(domClass = HtmlExample.class, value = FF45)
176 @JsxClass(domClass = HtmlFigure.class)
177 @JsxClass(domClass = HtmlFigureCaption.class)
178 @JsxClass(domClass = HtmlFooter.class)
179 @JsxClass(domClass = HtmlHeader.class)
180 @JsxClass(domClass = HtmlItalic.class, value = {CHROME, FF})
181 @JsxClass(domClass = HtmlKeyboard.class, value = {CHROME, FF})
182 @JsxClass(domClass = HtmlLayer.class, value = CHROME)
183 @JsxClass(domClass = HtmlListing.class, value = FF45)
184 @JsxClass(domClass = HtmlMark.class)
185 @JsxClass(domClass = HtmlNav.class)
186 @JsxClass(domClass = HtmlNoBreak.class, value = {CHROME, FF})
187 @JsxClass(domClass = HtmlNoEmbed.class)
188 @JsxClass(domClass = HtmlNoFrames.class)
189 @JsxClass(domClass = HtmlNoLayer.class, value = CHROME)
190 @JsxClass(domClass = HtmlNoScript.class)
191 @JsxClass(domClass = HtmlPlainText.class, value = {CHROME, FF})
192 @JsxClass(domClass = HtmlRuby.class, value = CHROME)
193 @JsxClass(domClass = HtmlRp.class, value = CHROME)
194 @JsxClass(domClass = HtmlRt.class, value = CHROME)
195 @JsxClass(domClass = HtmlS.class, value = {CHROME, FF})
196 @JsxClass(domClass = HtmlSample.class, value = {CHROME, FF})
197 @JsxClass(domClass = HtmlSection.class)
198 @JsxClass(domClass = HtmlSmall.class, value = {CHROME, FF})
199 @JsxClass(domClass = HtmlStrike.class, value = {CHROME, FF})
200 @JsxClass(domClass = HtmlStrong.class, value = {CHROME, FF})
201 @JsxClass(domClass = HtmlSubscript.class, value = {CHROME, FF})
202 @JsxClass(domClass = HtmlSummary.class, value = {CHROME, FF52})
203 @JsxClass(domClass = HtmlSuperscript.class, value = {CHROME, FF})
204 @JsxClass(domClass = HtmlTeletype.class, value = {CHROME, FF})
205 @JsxClass(domClass = HtmlUnderlined.class, value = {CHROME, FF})
206 @JsxClass(domClass = HtmlWordBreak.class)
207 @JsxClass(domClass = HtmlMain.class, value = {CHROME, FF})
208 @JsxClass(domClass = HtmlVariable.class, value = {CHROME, FF})
209 public class HTMLElement extends Element {
210 
211     private static final Class<?>[] METHOD_PARAMS_OBJECT = new Class[] {Object.class};
212     private static final Pattern PERCENT_VALUE = Pattern.compile("\\d+%");
213     /* http://msdn.microsoft.com/en-us/library/ie/aa358802.aspx */
214     private static final Map<String, String> COLORS_MAP_IE = new HashMap<>();
215 
216     private static final Log LOG = LogFactory.getLog(HTMLElement.class);
217 
218     private static final int BEHAVIOR_ID_UNKNOWN = -1;
219     /** BEHAVIOR_ID_CLIENT_CAPS. */
220     public static final int BEHAVIOR_ID_CLIENT_CAPS = 0;
221     /** BEHAVIOR_ID_HOMEPAGE. */
222     public static final int BEHAVIOR_ID_HOMEPAGE = 1;
223     /** BEHAVIOR_ID_DOWNLOAD. */
224     public static final int BEHAVIOR_ID_DOWNLOAD = 2;
225 
226     private static final String BEHAVIOR_CLIENT_CAPS = "#default#clientCaps";
227     private static final String BEHAVIOR_HOMEPAGE = "#default#homePage";
228     private static final String BEHAVIOR_DOWNLOAD = "#default#download";
229 
230     /**
231      * Static counter for {@link #uniqueID_}.
232      */
233     private static int UniqueID_Counter_ = 1;
234 
235     private final Set<String> behaviors_ = new HashSet<>();
236     private String uniqueID_;
237 
238     static {
239         COLORS_MAP_IE.put("AliceBlue", "#F0F8FF");
240         COLORS_MAP_IE.put("AntiqueWhite", "#FAEBD7");
241         COLORS_MAP_IE.put("Aqua", "#00FFFF");
242         COLORS_MAP_IE.put("Aquamarine", "#7FFFD4");
243         COLORS_MAP_IE.put("Azure", "#F0FFFF");
244         COLORS_MAP_IE.put("Beige", "#F5F5DC");
245         COLORS_MAP_IE.put("Bisque", "#FFE4C4");
246         COLORS_MAP_IE.put("Black", "#000000");
247         COLORS_MAP_IE.put("BlanchedAlmond", "#FFEBCD");
248         COLORS_MAP_IE.put("Blue", "#0000FF");
249         COLORS_MAP_IE.put("BlueViolet", "#8A2BE2");
250         COLORS_MAP_IE.put("Brown", "#A52A2A");
251         COLORS_MAP_IE.put("BurlyWood", "#DEB887");
252         COLORS_MAP_IE.put("CadetBlue", "#5F9EA0");
253         COLORS_MAP_IE.put("Chartreuse", "#7FFF00");
254         COLORS_MAP_IE.put("Chocolate", "#D2691E");
255         COLORS_MAP_IE.put("Coral", "#FF7F50");
256         COLORS_MAP_IE.put("CornflowerBlue", "#6495ED");
257         COLORS_MAP_IE.put("Cornsilk", "#FFF8DC");
258         COLORS_MAP_IE.put("Crimson", "#DC143C");
259         COLORS_MAP_IE.put("Cyan", "#00FFFF");
260         COLORS_MAP_IE.put("DarkBlue", "#00008B");
261         COLORS_MAP_IE.put("DarkCyan", "#008B8B");
262         COLORS_MAP_IE.put("DarkGoldenrod", "#B8860B");
263         COLORS_MAP_IE.put("DarkGray", "#A9A9A9");
264         COLORS_MAP_IE.put("DarkGrey", "#A9A9A9");
265         COLORS_MAP_IE.put("DarkGreen", "#006400");
266         COLORS_MAP_IE.put("DarkKhaki", "#BDB76B");
267         COLORS_MAP_IE.put("DarkMagenta", "#8B008B");
268         COLORS_MAP_IE.put("DarkOliveGreen", "#556B2F");
269         COLORS_MAP_IE.put("DarkOrange", "#FF8C00");
270         COLORS_MAP_IE.put("DarkOrchid", "#9932CC");
271         COLORS_MAP_IE.put("DarkRed", "#8B0000");
272         COLORS_MAP_IE.put("DarkSalmon", "#E9967A");
273         COLORS_MAP_IE.put("DarkSeaGreen", "#8FBC8F");
274         COLORS_MAP_IE.put("DarkSlateBlue", "#483D8B");
275         COLORS_MAP_IE.put("DarkSlateGray", "#2F4F4F");
276         COLORS_MAP_IE.put("DarkSlateGrey", "#2F4F4F");
277         COLORS_MAP_IE.put("DarkTurquoise", "#00CED1");
278         COLORS_MAP_IE.put("DarkViolet", "#9400D3");
279         COLORS_MAP_IE.put("DeepPink", "#FF1493");
280         COLORS_MAP_IE.put("DeepSkyBlue", "#00BFFF");
281         COLORS_MAP_IE.put("DimGray", "#696969");
282         COLORS_MAP_IE.put("DimGrey", "#696969");
283         COLORS_MAP_IE.put("DodgerBlue", "#1E90FF");
284         COLORS_MAP_IE.put("FireBrick", "#B22222");
285         COLORS_MAP_IE.put("FloralWhite", "#FFFAF0");
286         COLORS_MAP_IE.put("ForestGreen", "#228B22");
287         COLORS_MAP_IE.put("Fuchsia", "#FF00FF");
288         COLORS_MAP_IE.put("Gainsboro", "#DCDCDC");
289         COLORS_MAP_IE.put("GhostWhite", "#F8F8FF");
290         COLORS_MAP_IE.put("Gold", "#FFD700");
291         COLORS_MAP_IE.put("Goldenrod", "#DAA520");
292         COLORS_MAP_IE.put("Gray", "#808080");
293         COLORS_MAP_IE.put("Grey", "#808080");
294         COLORS_MAP_IE.put("Green", "#008000");
295         COLORS_MAP_IE.put("GreenYellow", "#ADFF2F");
296         COLORS_MAP_IE.put("Honeydew", "#F0FFF0");
297         COLORS_MAP_IE.put("HotPink", "#FF69B4");
298         COLORS_MAP_IE.put("IndianRed", "#CD5C5C");
299         COLORS_MAP_IE.put("Indigo", "#4B0082");
300         COLORS_MAP_IE.put("Ivory", "#FFFFF0");
301         COLORS_MAP_IE.put("Khaki", "#F0E68C");
302         COLORS_MAP_IE.put("Lavender", "#E6E6FA");
303         COLORS_MAP_IE.put("LavenderBlush", "#FFF0F5");
304         COLORS_MAP_IE.put("LawnGreen", "#7CFC00");
305         COLORS_MAP_IE.put("LemonChiffon", "#FFFACD");
306         COLORS_MAP_IE.put("LightBlue", "#ADD8E6");
307         COLORS_MAP_IE.put("LightCoral", "#F08080");
308         COLORS_MAP_IE.put("LightCyan", "#E0FFFF");
309         COLORS_MAP_IE.put("LightGoldenrodYellow", "#FAFAD2");
310         COLORS_MAP_IE.put("LightGreen", "#90EE90");
311         COLORS_MAP_IE.put("LightGray", "#D3D3D3");
312         COLORS_MAP_IE.put("LightGrey", "#D3D3D3");
313         COLORS_MAP_IE.put("LightPink", "#FFB6C1");
314         COLORS_MAP_IE.put("LightSalmon", "#FFA07A");
315         COLORS_MAP_IE.put("LightSeaGreen", "#20B2AA");
316         COLORS_MAP_IE.put("LightSkyBlue", "#87CEFA");
317         COLORS_MAP_IE.put("LightSlateGray", "#778899");
318         COLORS_MAP_IE.put("LightSlateGrey", "#778899");
319         COLORS_MAP_IE.put("LightSteelBlue", "#B0C4DE");
320         COLORS_MAP_IE.put("LightYellow", "#FFFFE0");
321         COLORS_MAP_IE.put("Lime", "#00FF00");
322         COLORS_MAP_IE.put("LimeGreen", "#32CD32");
323         COLORS_MAP_IE.put("Linen", "#FAF0E6");
324         COLORS_MAP_IE.put("Magenta", "#FF00FF");
325         COLORS_MAP_IE.put("Maroon", "#800000");
326         COLORS_MAP_IE.put("MediumAquamarine", "#66CDAA");
327         COLORS_MAP_IE.put("MediumBlue", "#0000CD");
328         COLORS_MAP_IE.put("MediumOrchid", "#BA55D3");
329         COLORS_MAP_IE.put("MediumPurple", "#9370DB");
330         COLORS_MAP_IE.put("MediumSeaGreen", "#3CB371");
331         COLORS_MAP_IE.put("MediumSlateBlue", "#7B68EE");
332         COLORS_MAP_IE.put("MediumSpringGreen", "#00FA9A");
333         COLORS_MAP_IE.put("MediumTurquoise", "#48D1CC");
334         COLORS_MAP_IE.put("MediumVioletRed", "#C71585");
335         COLORS_MAP_IE.put("MidnightBlue", "#191970");
336         COLORS_MAP_IE.put("MintCream", "#F5FFFA");
337         COLORS_MAP_IE.put("MistyRose", "#FFE4E1");
338         COLORS_MAP_IE.put("Moccasin", "#FFE4B5");
339         COLORS_MAP_IE.put("NavajoWhite", "#FFDEAD");
340         COLORS_MAP_IE.put("Navy", "#000080");
341         COLORS_MAP_IE.put("OldLace", "#FDF5E6");
342         COLORS_MAP_IE.put("Olive", "#808000");
343         COLORS_MAP_IE.put("OliveDrab", "#6B8E23");
344         COLORS_MAP_IE.put("Orange", "#FFA500");
345         COLORS_MAP_IE.put("OrangeRed", "#FF4500");
346         COLORS_MAP_IE.put("Orchid", "#DA70D6");
347         COLORS_MAP_IE.put("PaleGoldenrod", "#EEE8AA");
348         COLORS_MAP_IE.put("PaleGreen", "#98FB98");
349         COLORS_MAP_IE.put("PaleTurquoise", "#AFEEEE");
350         COLORS_MAP_IE.put("PaleVioletRed", "#DB7093");
351         COLORS_MAP_IE.put("PapayaWhip", "#FFEFD5");
352         COLORS_MAP_IE.put("PeachPuff", "#FFDAB9");
353         COLORS_MAP_IE.put("Peru", "#CD853F");
354         COLORS_MAP_IE.put("Pink", "#FFC0CB");
355         COLORS_MAP_IE.put("Plum", "#DDA0DD");
356         COLORS_MAP_IE.put("PowderBlue", "#B0E0E6");
357         COLORS_MAP_IE.put("Purple", "#800080");
358         COLORS_MAP_IE.put("Red", "#FF0000");
359         COLORS_MAP_IE.put("RosyBrown", "#BC8F8F");
360         COLORS_MAP_IE.put("RoyalBlue", "#4169E1");
361         COLORS_MAP_IE.put("SaddleBrown", "#8B4513");
362         COLORS_MAP_IE.put("Salmon", "#FA8072");
363         COLORS_MAP_IE.put("SandyBrown", "#F4A460");
364         COLORS_MAP_IE.put("SeaGreen", "#2E8B57");
365         COLORS_MAP_IE.put("Seashell", "#FFF5EE");
366         COLORS_MAP_IE.put("Sienna", "#A0522D");
367         COLORS_MAP_IE.put("Silver", "#C0C0C0");
368         COLORS_MAP_IE.put("SkyBlue", "#87CEEB");
369         COLORS_MAP_IE.put("SlateBlue", "#6A5ACD");
370         COLORS_MAP_IE.put("SlateGray", "#708090");
371         COLORS_MAP_IE.put("SlateGrey", "#708090");
372         COLORS_MAP_IE.put("Snow", "#FFFAFA");
373         COLORS_MAP_IE.put("SpringGreen", "#00FF7F");
374         COLORS_MAP_IE.put("SteelBlue", "#4682B4");
375         COLORS_MAP_IE.put("Tan", "#D2B48C");
376         COLORS_MAP_IE.put("Teal", "#008080");
377         COLORS_MAP_IE.put("Thistle", "#D8BFD8");
378         COLORS_MAP_IE.put("Tomato", "#FF6347");
379         COLORS_MAP_IE.put("Turquoise", "#40E0D0");
380         COLORS_MAP_IE.put("Violet", "#EE82EE");
381         COLORS_MAP_IE.put("Wheat", "#F5DEB3");
382         COLORS_MAP_IE.put("White", "#FFFFFF");
383         COLORS_MAP_IE.put("WhiteSmoke", "#F5F5F5");
384         COLORS_MAP_IE.put("Yellow", "#FFFF00");
385         COLORS_MAP_IE.put("YellowGreen", "#9ACD32");
386     }
387 
388     private boolean endTagForbidden_;
389 
390     /**
391      * Creates an instance.
392      */
393     @JsxConstructor({CHROME, FF, EDGE})
394     public HTMLElement() {
395     }
396 
397     /**
398      * Sets the DOM node that corresponds to this JavaScript object.
399      * @param domNode the DOM node
400      */
401     @Override
402     public void setDomNode(final DomNode domNode) {
403         super.setDomNode(domNode);
404 
405         final String name = domNode.getLocalName();
406         if ("wbr".equalsIgnoreCase(name)
407                 || "basefont".equalsIgnoreCase(name)
408                 || "keygen".equalsIgnoreCase(name)
409                 || "track".equalsIgnoreCase(name)) {
410             endTagForbidden_ = true;
411         }
412     }
413 
414     /**
415      * Returns the element title.
416      * @return the ID of this element
417      */
418     @JsxGetter
419     public String getTitle() {
420         return getDomNodeOrDie().getAttribute("title");
421     }
422 
423     /**
424      * Sets the title of this element.
425      * @param newTitle the new identifier of this element
426      */
427     @JsxSetter
428     public void setTitle(final String newTitle) {
429         getDomNodeOrDie().setAttribute("title", newTitle);
430     }
431 
432     /**
433      * Returns true if this element is disabled.
434      * @return true if this element is disabled
435      */
436     @JsxGetter(IE)
437     public boolean isDisabled() {
438         return getDomNodeOrDie().hasAttribute("disabled");
439     }
440 
441     /**
442      * Sets whether or not to disable this element.
443      * @param disabled True if this is to be disabled
444      */
445     @JsxSetter(IE)
446     public void setDisabled(final boolean disabled) {
447         final HtmlElement element = getDomNodeOrDie();
448         if (disabled) {
449             element.setAttribute("disabled", "disabled");
450         }
451         else {
452             element.removeAttribute("disabled");
453         }
454     }
455 
456     /**
457      * {@inheritDoc}
458      */
459     @Override
460     public String getLocalName() {
461         final DomNode domNode = getDomNodeOrDie();
462         if (domNode.getHtmlPageOrNull() != null) {
463             final String prefix = domNode.getPrefix();
464             if (prefix != null) {
465                 // create string builder only if needed (performance)
466                 final StringBuilder localName = new StringBuilder(prefix.toLowerCase(Locale.ROOT));
467                 localName.append(':');
468                 localName.append(domNode.getLocalName().toLowerCase(Locale.ROOT));
469                 return localName.toString();
470             }
471             return domNode.getLocalName().toLowerCase(Locale.ROOT);
472         }
473         return domNode.getLocalName();
474     }
475 
476     /**
477      * An IE-only method which clears all custom attributes.
478      */
479     @JsxFunction(IE)
480     public void clearAttributes() {
481         final HtmlElement node = getDomNodeOrDie();
482 
483         // Remove custom attributes defined directly in HTML.
484         final List<String> removals = new ArrayList<>();
485         for (final String attributeName : node.getAttributesMap().keySet()) {
486             // Quick hack to figure out what's a "custom" attribute, and what isn't.
487             // May not be 100% correct.
488             if (!ScriptableObject.hasProperty(getPrototype(), attributeName)) {
489                 removals.add(attributeName);
490             }
491         }
492         for (final String attributeName : removals) {
493             node.removeAttribute(attributeName);
494         }
495 
496         // Remove custom attributes defined at runtime via JavaScript.
497         for (final Object id : getAllIds()) {
498             if (id instanceof Integer) {
499                 final int i = ((Integer) id).intValue();
500                 delete(i);
501             }
502             else if (id instanceof String) {
503                 delete((String) id);
504             }
505         }
506     }
507 
508     /**
509      * An IE-only method which copies all custom attributes from the specified source element
510      * to this element.
511      * @param source the source element from which to copy the custom attributes
512      * @param preserveIdentity if {@code false}, the <tt>name</tt> and <tt>id</tt> attributes are not copied
513      */
514     @JsxFunction(IE)
515     public void mergeAttributes(final HTMLElement source, final Object preserveIdentity) {
516         final HtmlElement src = source.getDomNodeOrDie();
517         final HtmlElement target = getDomNodeOrDie();
518 
519         // Merge ID and name if we aren't preserving identity.
520         if (preserveIdentity instanceof Boolean && !((Boolean) preserveIdentity).booleanValue()) {
521             target.setId(src.getId());
522             target.setAttribute("name", src.getAttribute("name"));
523         }
524     }
525 
526     /**
527      * Sets an attribute.
528      * See also <a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-F68F082">
529      * the DOM reference</a>
530      *
531      * @param name Name of the attribute to set
532      * @param value Value to set the attribute to
533      */
534     @Override
535     public void setAttribute(String name, final String value) {
536         getDomNodeOrDie().setAttribute(name, value);
537 
538         // call corresponding event handler setOnxxx if found
539         if (!name.isEmpty()) {
540             name = name.toLowerCase(Locale.ROOT);
541             if (name.startsWith("on")) {
542                 try {
543                     name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
544                     final Method method = getClass().getMethod("set" + name, METHOD_PARAMS_OBJECT);
545                     method.invoke(this, new Object[] {new EventHandler(getDomNodeOrDie(), name.substring(2), value)});
546                 }
547                 catch (final NoSuchMethodException e) {
548                     //silently ignore
549                 }
550                 catch (final IllegalAccessException e) {
551                     //silently ignore
552                 }
553                 catch (final InvocationTargetException e) {
554                     throw new RuntimeException(e.getCause());
555                 }
556             }
557         }
558     }
559 
560     /**
561      * Gets the attributes of the element in the form of a {@link org.xml.sax.Attributes}.
562      * @param element the element to read the attributes from
563      * @return the attributes
564      */
565     protected AttributesImpl readAttributes(final HtmlElement element) {
566         final AttributesImpl attributes = new AttributesImpl();
567         for (final DomAttr entry : element.getAttributesMap().values()) {
568             final String name = entry.getName();
569             final String value = entry.getValue();
570             attributes.addAttribute(null, name, name, null, value);
571         }
572 
573         return attributes;
574     }
575 
576     /**
577      * Removes this object from the document hierarchy.
578      * @param removeChildren whether to remove children or no
579      * @return a reference to the object that is removed
580      */
581     @JsxFunction(IE)
582     public HTMLElement removeNode(final boolean removeChildren) {
583         final HTMLElement parent = (HTMLElement) getParentElement();
584         if (parent != null) {
585             parent.removeChild(this);
586             if (!removeChildren) {
587                 final NodeList collection = getChildNodes();
588                 final int length = collection.getLength();
589                 for (int i = 0; i < length; i++) {
590                     final Node object = (Node) collection.item(Integer.valueOf(0));
591                     parent.appendChild(object);
592                 }
593             }
594         }
595         return this;
596     }
597 
598     /**
599      * Gets the attribute node for the specified attribute.
600      * @param attributeName the name of the attribute to retrieve
601      * @return the attribute node for the specified attribute
602      */
603     @Override
604     public Object getAttributeNode(final String attributeName) {
605         return getAttributes().getNamedItem(attributeName);
606     }
607 
608     /**
609      * {@inheritDoc}
610      */
611     @Override
612     @JsxFunction(IE)
613     public HTMLCollection getElementsByClassName(final String className) {
614         return super.getElementsByClassName(className);
615     }
616 
617     /**
618      * {@inheritDoc}
619      */
620     @Override
621     @JsxGetter(propertyName = "className", value = IE)
622     public Object getClassName_js() {
623         return super.getClassName_js();
624     }
625 
626     /**
627      * {@inheritDoc}
628      */
629     @Override
630     @JsxGetter(IE)
631     public String getOuterHTML() {
632         return super.getOuterHTML();
633     }
634 
635     /**
636      * {@inheritDoc}
637      */
638     @Override
639     @JsxSetter(IE)
640     public void setOuterHTML(final Object value) {
641         super.setOuterHTML(value);
642     }
643 
644     /**
645      * {@inheritDoc}
646      */
647     @Override
648     @JsxGetter(IE)
649     public String getInnerHTML() {
650         return super.getInnerHTML();
651     }
652 
653     /**
654      * {@inheritDoc}
655      */
656     @Override
657     @JsxSetter(IE)
658     public void setInnerHTML(final Object value) {
659         super.setInnerHTML(value);
660     }
661 
662     /**
663      * {@inheritDoc}
664      */
665     @Override
666     @JsxSetter(propertyName = "className", value = IE)
667     public void setClassName_js(final String className) {
668         super.setClassName_js(className);
669     }
670 
671     /**
672      * {@inheritDoc}
673      */
674     @Override
675     @JsxFunction(IE)
676     public void insertAdjacentHTML(final String position, final String text) {
677         super.insertAdjacentHTML(position, text);
678     }
679 
680     /**
681      * {@inheritDoc}
682      */
683     @Override
684     @JsxFunction(IE)
685     public void insertAdjacentText(final String where, final String text) {
686         super.insertAdjacentText(where, text);
687     }
688 
689     /**
690      * {@inheritDoc}
691      */
692     @Override
693     @JsxFunction(IE)
694     public Object insertAdjacentElement(final String where, final Object insertedElement) {
695         return super.insertAdjacentElement(where, insertedElement);
696     }
697 
698     /**
699      * Gets the innerText attribute.
700      * @return the contents of this node as text
701      */
702     @JsxGetter
703     public String getInnerText() {
704         final StringBuilder buf = new StringBuilder();
705         // we can't rely on DomNode.asXml because it adds indentation and new lines
706         printChildren(buf, getDomNodeOrDie(), false);
707         return buf.toString();
708     }
709 
710     /**
711      * Replaces all child elements of this element with the supplied text value.
712      * @param value the new value for the contents of this element
713      */
714     @JsxSetter
715     public void setInnerText(final Object value) {
716         final String valueString;
717         if (value == null && getBrowserVersion().hasFeature(JS_INNER_TEXT_VALUE_NULL)) {
718             valueString = null;
719         }
720         else {
721             valueString = Context.toString(value);
722         }
723         setInnerTextImpl(valueString);
724     }
725 
726     /**
727      * The worker for setInnerText.
728      * @param value the new value for the contents of this node
729      */
730     protected void setInnerTextImpl(final String value) {
731         final DomNode domNode = getDomNodeOrDie();
732 
733         domNode.removeAllChildren();
734 
735         if (value != null && !value.isEmpty()) {
736             domNode.appendChild(new DomText(domNode.getPage(), value));
737         }
738     }
739 
740     /**
741      * Replaces all child elements of this element with the supplied text value.
742      * @param value the new value for the contents of this element
743      */
744     @Override
745     public void setTextContent(final Object value) {
746         setInnerTextImpl(value == null ? null : Context.toString(value));
747     }
748 
749     /**
750      * ProxyDomNode.
751      */
752     public static class ProxyDomNode extends HtmlDivision {
753 
754         private final DomNode target_;
755         private final boolean append_;
756 
757         /**
758          * Constructor.
759          * @param page the page
760          * @param target the target
761          * @param append append or no
762          */
763         public ProxyDomNode(final SgmlPage page, final DomNode target, final boolean append) {
764             super(HtmlDivision.TAG_NAME, page, null);
765             target_ = target;
766             append_ = append;
767         }
768 
769         /**
770          * {@inheritDoc}
771          */
772         @Override
773         public DomNode appendChild(final org.w3c.dom.Node node) {
774             final DomNode domNode = (DomNode) node;
775             if (append_) {
776                 return target_.appendChild(domNode);
777             }
778             target_.insertBefore(domNode);
779             return domNode;
780         }
781 
782         /**
783          * Gets wrapped DomNode.
784          * @return the node
785          */
786         public DomNode getDomNode() {
787             return target_;
788         }
789 
790         /**
791          * Returns append or not.
792          * @return append or not
793          */
794         public boolean isAppend() {
795             return append_;
796         }
797     }
798 
799     /**
800      * Adds the specified behavior to this HTML element. Currently only supports
801      * the following default IE behaviors:
802      * <ul>
803      *   <li>#default#clientCaps</li>
804      *   <li>#default#homePage</li>
805      *   <li>#default#download</li>
806      * </ul>
807      * @param behavior the URL of the behavior to add, or a default behavior name
808      * @return an identifier that can be user later to detach the behavior from the element
809      */
810     public int addBehavior(final String behavior) {
811         // if behavior already defined, then nothing to do
812         if (behaviors_.contains(behavior)) {
813             return 0;
814         }
815 
816         final Class<? extends HTMLElement> c = getClass();
817         if (BEHAVIOR_CLIENT_CAPS.equalsIgnoreCase(behavior)) {
818             defineProperty("availHeight", c, 0);
819             defineProperty("availWidth", c, 0);
820             defineProperty("bufferDepth", c, 0);
821             defineProperty("colorDepth", c, 0);
822             defineProperty("connectionType", c, 0);
823             defineProperty("cookieEnabled", c, 0);
824             defineProperty("cpuClass", c, 0);
825             defineProperty("height", c, 0);
826             defineProperty("javaEnabled", c, 0);
827             defineProperty("platform", c, 0);
828             defineProperty("systemLanguage", c, 0);
829             defineProperty("userLanguage", c, 0);
830             defineProperty("width", c, 0);
831             defineFunctionProperties(new String[] {"addComponentRequest"}, c, 0);
832             defineFunctionProperties(new String[] {"clearComponentRequest"}, c, 0);
833             defineFunctionProperties(new String[] {"compareVersions"}, c, 0);
834             defineFunctionProperties(new String[] {"doComponentRequest"}, c, 0);
835             defineFunctionProperties(new String[] {"getComponentVersion"}, c, 0);
836             defineFunctionProperties(new String[] {"isComponentInstalled"}, c, 0);
837             behaviors_.add(BEHAVIOR_CLIENT_CAPS);
838             return BEHAVIOR_ID_CLIENT_CAPS;
839         }
840         else if (BEHAVIOR_HOMEPAGE.equalsIgnoreCase(behavior)) {
841             defineFunctionProperties(new String[] {"isHomePage"}, c, 0);
842             defineFunctionProperties(new String[] {"setHomePage"}, c, 0);
843             defineFunctionProperties(new String[] {"navigateHomePage"}, c, 0);
844             behaviors_.add(BEHAVIOR_CLIENT_CAPS);
845             return BEHAVIOR_ID_HOMEPAGE;
846         }
847         else if (BEHAVIOR_DOWNLOAD.equalsIgnoreCase(behavior)) {
848             defineFunctionProperties(new String[] {"startDownload"}, c, 0);
849             behaviors_.add(BEHAVIOR_DOWNLOAD);
850             return BEHAVIOR_ID_DOWNLOAD;
851         }
852         else {
853             LOG.warn("Unimplemented behavior: " + behavior);
854             return BEHAVIOR_ID_UNKNOWN;
855         }
856     }
857 
858     /**
859      * Removes the behavior corresponding to the specified identifier from this element.
860      * @param id the identifier for the behavior to remove
861      */
862     public void removeBehavior(final int id) {
863         switch (id) {
864             case BEHAVIOR_ID_CLIENT_CAPS:
865                 delete("availHeight");
866                 delete("availWidth");
867                 delete("bufferDepth");
868                 delete("colorDepth");
869                 delete("connectionType");
870                 delete("cookieEnabled");
871                 delete("cpuClass");
872                 delete("height");
873                 delete("javaEnabled");
874                 delete("platform");
875                 delete("systemLanguage");
876                 delete("userLanguage");
877                 delete("width");
878                 delete("addComponentRequest");
879                 delete("clearComponentRequest");
880                 delete("compareVersions");
881                 delete("doComponentRequest");
882                 delete("getComponentVersion");
883                 delete("isComponentInstalled");
884                 behaviors_.remove(BEHAVIOR_CLIENT_CAPS);
885                 break;
886             case BEHAVIOR_ID_HOMEPAGE:
887                 delete("isHomePage");
888                 delete("setHomePage");
889                 delete("navigateHomePage");
890                 behaviors_.remove(BEHAVIOR_HOMEPAGE);
891                 break;
892             case BEHAVIOR_ID_DOWNLOAD:
893                 delete("startDownload");
894                 behaviors_.remove(BEHAVIOR_DOWNLOAD);
895                 break;
896             default:
897                 LOG.warn("Unexpected behavior id: " + id + ". Ignoring.");
898         }
899     }
900 
901     //----------------------- START #default#clientCaps BEHAVIOR -----------------------
902 
903     /**
904      * Returns the screen's available height. Part of the <tt>#default#clientCaps</tt>
905      * default IE behavior implementation.
906      * @return the screen's available height
907      */
908     public int getAvailHeight() {
909         return getWindow().getScreen().getAvailHeight();
910     }
911 
912     /**
913      * Returns the screen's available width. Part of the <tt>#default#clientCaps</tt>
914      * default IE behavior implementation.
915      * @return the screen's available width
916      */
917     public int getAvailWidth() {
918         return getWindow().getScreen().getAvailWidth();
919     }
920 
921     /**
922      * Returns the screen's buffer depth. Part of the <tt>#default#clientCaps</tt>
923      * default IE behavior implementation.
924      * @return the screen's buffer depth
925      */
926     public int getBufferDepth() {
927         return getWindow().getScreen().getBufferDepth();
928     }
929 
930     /**
931      * Returns the screen's color depth. Part of the <tt>#default#clientCaps</tt>
932      * default IE behavior implementation.
933      * @return the screen's color depth
934      */
935     public int getColorDepth() {
936         return getWindow().getScreen().getColorDepth();
937     }
938 
939     /**
940      * Returns the connection type being used. Part of the <tt>#default#clientCaps</tt>
941      * default IE behavior implementation.
942      * @return the connection type being used
943      * Current implementation always return "modem"
944      */
945     public String getConnectionType() {
946         return "modem";
947     }
948 
949     /**
950      * Returns {@code true} if cookies are enabled. Part of the <tt>#default#clientCaps</tt>
951      * default IE behavior implementation.
952      * @return whether or not cookies are enabled
953      */
954     public boolean isCookieEnabled() {
955         return getWindow().getNavigator().isCookieEnabled();
956     }
957 
958     /**
959      * Returns the type of CPU used. Part of the <tt>#default#clientCaps</tt>
960      * default IE behavior implementation.
961      * @return the type of CPU used
962      */
963     public String getCpuClass() {
964         return getWindow().getNavigator().getCpuClass();
965     }
966 
967     /**
968      * Returns the screen's height. Part of the <tt>#default#clientCaps</tt>
969      * default IE behavior implementation.
970      * @return the screen's height
971      */
972     public int getHeight() {
973         return getWindow().getScreen().getHeight();
974     }
975 
976     /**
977      * Returns {@code true} if Java is enabled. Part of the <tt>#default#clientCaps</tt>
978      * default IE behavior implementation.
979      * @return whether or not Java is enabled
980      */
981     public boolean isJavaEnabled() {
982         return getWindow().getNavigator().javaEnabled();
983     }
984 
985     /**
986      * Returns the platform used. Part of the <tt>#default#clientCaps</tt>
987      * default IE behavior implementation.
988      * @return the platform used
989      */
990     public String getPlatform() {
991         return getWindow().getNavigator().getPlatform();
992     }
993 
994     /**
995      * Returns the system language. Part of the <tt>#default#clientCaps</tt>
996      * default IE behavior implementation.
997      * @return the system language
998      */
999     public String getSystemLanguage() {
1000         return getWindow().getNavigator().getSystemLanguage();
1001     }
1002 
1003     /**
1004      * Returns the user language. Part of the <tt>#default#clientCaps</tt>
1005      * default IE behavior implementation.
1006      * @return the user language
1007      */
1008     public String getUserLanguage() {
1009         return getWindow().getNavigator().getUserLanguage();
1010     }
1011 
1012     /**
1013      * Returns the screen's width. Part of the <tt>#default#clientCaps</tt>
1014      * default IE behavior implementation.
1015      * @return the screen's width
1016      */
1017     public int getWidth() {
1018         return getWindow().getScreen().getWidth();
1019     }
1020 
1021     /**
1022      * Adds the specified component to the queue of components to be installed. Note
1023      * that no components ever get installed, and this call is always ignored. Part of
1024      * the <tt>#default#clientCaps</tt> default IE behavior implementation.
1025      * @param id the identifier for the component to install
1026      * @param idType the type of identifier specified
1027      * @param minVersion the minimum version of the component to install
1028      */
1029     public void addComponentRequest(final String id, final String idType, final String minVersion) {
1030         if (LOG.isDebugEnabled()) {
1031             LOG.debug("Call to addComponentRequest(" + id + ", " + idType + ", " + minVersion + ") ignored.");
1032         }
1033     }
1034 
1035     /**
1036      * Clears the component install queue of all component requests. Note that no components
1037      * ever get installed, and this call is always ignored. Part of the <tt>#default#clientCaps</tt>
1038      * default IE behavior implementation.
1039      */
1040     public void clearComponentRequest() {
1041         if (LOG.isDebugEnabled()) {
1042             LOG.debug("Call to clearComponentRequest() ignored.");
1043         }
1044     }
1045 
1046     /**
1047      * Compares the two specified version numbers. Part of the <tt>#default#clientCaps</tt>
1048      * default IE behavior implementation.
1049      * @param v1 the first of the two version numbers to compare
1050      * @param v2 the second of the two version numbers to compare
1051      * @return -1 if v1 is less than v2, 0 if v1 equals v2, and 1 if v1 is more than v2
1052      */
1053     public int compareVersions(final String v1, final String v2) {
1054         final int i = v1.compareTo(v2);
1055         if (i == 0) {
1056             return 0;
1057         }
1058         else if (i < 0) {
1059             return -1;
1060         }
1061         else {
1062             return 1;
1063         }
1064     }
1065 
1066     /**
1067      * Downloads all the components queued via {@link #addComponentRequest(String, String, String)}.
1068      * @return {@code true} if the components are downloaded successfully
1069      * Current implementation always return {@code false}
1070      */
1071     public boolean doComponentRequest() {
1072         return false;
1073     }
1074 
1075     /**
1076      * Returns the version of the specified component.
1077      * @param id the identifier for the component whose version is to be returned
1078      * @param idType the type of identifier specified
1079      * @return the version of the specified component
1080      */
1081     public String getComponentVersion(final String id, final String idType) {
1082         if ("{E5D12C4E-7B4F-11D3-B5C9-0050045C3C96}".equals(id)) {
1083             // Yahoo Messenger.
1084             return "";
1085         }
1086         // Everything else.
1087         return "1.0";
1088     }
1089 
1090     /**
1091      * Returns {@code true} if the specified component is installed.
1092      * @param id the identifier for the component to check for
1093      * @param idType the type of id specified
1094      * @param minVersion the minimum version to check for
1095      * @return {@code true} if the specified component is installed
1096      */
1097     public boolean isComponentInstalled(final String id, final String idType, final String minVersion) {
1098         return false;
1099     }
1100 
1101     //----------------------- START #default#download BEHAVIOR -----------------------
1102 
1103     /**
1104      * Implementation of the IE behavior #default#download.
1105      * @param uri the URI of the download source
1106      * @param callback the method which should be called when the download is finished
1107      * @see <a href="http://msdn.microsoft.com/en-us/library/ms531406.aspx">MSDN documentation</a>
1108      * @throws MalformedURLException if the URL cannot be created
1109      */
1110     public void startDownload(final String uri, final Function callback) throws MalformedURLException {
1111         final HtmlPage page = (HtmlPage) getWindow().getWebWindow().getEnclosedPage();
1112         final URL url = page.getFullyQualifiedUrl(uri);
1113         if (!page.getUrl().getHost().equals(url.getHost())) {
1114             throw Context.reportRuntimeError("Not authorized url: " + url);
1115         }
1116         final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
1117                 createDownloadBehaviorJob(url, callback, getWindow().getWebWindow().getWebClient());
1118         page.getEnclosingWindow().getJobManager().addJob(job, page);
1119     }
1120 
1121     //----------------------- END #default#download BEHAVIOR -----------------------
1122 
1123     //----------------------- START #default#homePage BEHAVIOR -----------------------
1124 
1125     /**
1126      * Returns {@code true} if the specified URL is the web client's current
1127      * homepage and the document calling the method is on the same domain as the
1128      * user's homepage. Part of the <tt>#default#homePage</tt> default IE behavior
1129      * implementation.
1130      * @param url the URL to check
1131      * @return {@code true} if the specified URL is the current homepage
1132      */
1133     public boolean isHomePage(final String url) {
1134         try {
1135             final URL newUrl = new URL(url);
1136             final URL currentUrl = getDomNodeOrDie().getPage().getUrl();
1137             final String home = getDomNodeOrDie().getPage().getEnclosingWindow()
1138                     .getWebClient().getOptions().getHomePage();
1139             final boolean sameDomains = newUrl.getHost().equalsIgnoreCase(currentUrl.getHost());
1140             final boolean isHomePage = home != null && home.equals(url);
1141             return sameDomains && isHomePage;
1142         }
1143         catch (final MalformedURLException e) {
1144             return false;
1145         }
1146     }
1147 
1148     /**
1149      * Sets the web client's current homepage. Part of the <tt>#default#homePage</tt>
1150      * default IE behavior implementation.
1151      * @param url the new homepage URL
1152      */
1153     public void setHomePage(final String url) {
1154         getDomNodeOrDie().getPage().getEnclosingWindow().getWebClient().getOptions().setHomePage(url);
1155     }
1156 
1157     /**
1158      * Causes the web client to navigate to the current home page. Part of the
1159      * <tt>#default#homePage</tt> default IE behavior implementation.
1160      * @throws IOException if loading home page fails
1161      */
1162     public void navigateHomePage() throws IOException {
1163         final WebClient webClient = getDomNodeOrDie().getPage().getEnclosingWindow().getWebClient();
1164         webClient.getPage(webClient.getOptions().getHomePage());
1165     }
1166 
1167     //----------------------- END #default#homePage BEHAVIOR -----------------------
1168 
1169     /**
1170      * Returns this element's <tt>offsetHeight</tt>, which is the element height plus the element's padding
1171      * plus the element's border. This method returns a dummy value compatible with mouse event coordinates
1172      * during mouse events.
1173      * @return this element's <tt>offsetHeight</tt>
1174      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534199.aspx">MSDN Documentation</a>
1175      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1176      */
1177     @JsxGetter
1178     public int getOffsetHeight() {
1179         if (isDisplayNone() || !getDomNodeOrDie().isAttachedToPage()) {
1180             return 0;
1181         }
1182         final MouseEvent event = MouseEvent.getCurrentMouseEvent();
1183         if (isAncestorOfEventTarget(event)) {
1184             // compute appropriate offset height to pretend mouse event was produced within this element
1185             return event.getClientY() - getPosY() + 50;
1186         }
1187         final ComputedCSSStyleDeclaration style = getWindow().getComputedStyle(this, null);
1188         return style.getCalculatedHeight(true, true);
1189     }
1190 
1191     /**
1192      * Returns this element's <tt>offsetWidth</tt>, which is the element width plus the element's padding
1193      * plus the element's border. This method returns a dummy value compatible with mouse event coordinates
1194      * during mouse events.
1195      * @return this element's <tt>offsetWidth</tt>
1196      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534304.aspx">MSDN Documentation</a>
1197      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1198      */
1199     @JsxGetter
1200     public int getOffsetWidth() {
1201         if (isDisplayNone() || !getDomNodeOrDie().isAttachedToPage()) {
1202             return 0;
1203         }
1204 
1205         final MouseEvent event = MouseEvent.getCurrentMouseEvent();
1206         if (isAncestorOfEventTarget(event)) {
1207             // compute appropriate offset width to pretend mouse event was produced within this element
1208             return event.getClientX() - getPosX() + 50;
1209         }
1210         final ComputedCSSStyleDeclaration style = getWindow().getComputedStyle(this, null);
1211         return style.getCalculatedWidth(true, true);
1212     }
1213 
1214     /**
1215      * Returns {@code true} if this element's node is an ancestor of the specified event's target node.
1216      * @param event the event whose target node is to be checked
1217      * @return {@code true} if this element's node is an ancestor of the specified event's target node
1218      */
1219     protected boolean isAncestorOfEventTarget(final MouseEvent event) {
1220         if (event == null) {
1221             return false;
1222         }
1223         else if (!(event.getSrcElement() instanceof HTMLElement)) {
1224             return false;
1225         }
1226         final HTMLElement srcElement = (HTMLElement) event.getSrcElement();
1227         return getDomNodeOrDie().isAncestorOf(srcElement.getDomNodeOrDie());
1228     }
1229 
1230     /**
1231      * {@inheritDoc}
1232      */
1233     @Override
1234     public String toString() {
1235         return "HTMLElement for " + getDomNodeOrNull();
1236     }
1237 
1238     /**
1239      * Sets the Uniform Resource Name (URN) specified in the namespace declaration.
1240      * @param tagUrn the Uniform Resource Name (URN) specified in the namespace declaration
1241      * @see <a href="http://msdn.microsoft.com/en-us/library/ms534658.aspx">MSDN documentation</a>
1242      */
1243     @JsxSetter(IE)
1244     public void setTagUrn(final String tagUrn) {
1245         throw Context.reportRuntimeError("Error trying to set tagUrn to '" + tagUrn + "'.");
1246     }
1247 
1248     /**
1249      * Gets the first ancestor instance of {@link HTMLElement}. It is mostly identical
1250      * to {@link #getParent()} except that it skips XML nodes.
1251      * @return the parent HTML element
1252      * @see #getParent()
1253      */
1254     public HTMLElement getParentHTMLElement() {
1255         Node parent = getParent();
1256         while (parent != null && !(parent instanceof HTMLElement)) {
1257             parent = parent.getParent();
1258         }
1259         return (HTMLElement) parent;
1260     }
1261 
1262     /**
1263      * {@inheritDoc}
1264      */
1265     @Override
1266     @JsxFunction(IE)
1267     public void scrollIntoView() { /* do nothing at the moment */ }
1268 
1269     /**
1270      * Retrieves an auto-generated, unique identifier for the object.
1271      * <b>Note</b> The unique ID generated is not guaranteed to be the same every time the page is loaded.
1272      * @return an auto-generated, unique identifier for the object
1273      */
1274     @JsxGetter(IE)
1275     public String getUniqueID() {
1276         if (uniqueID_ == null) {
1277             uniqueID_ = "ms__id" + UniqueID_Counter_++;
1278         }
1279         return uniqueID_;
1280     }
1281 
1282     /**
1283      * {@inheritDoc}
1284      */
1285     @Override
1286     public HtmlElement getDomNodeOrDie() {
1287         return (HtmlElement) super.getDomNodeOrDie();
1288     }
1289 
1290     /**
1291      * {@inheritDoc}
1292      */
1293     @Override
1294     public HtmlElement getDomNodeOrNull() {
1295         return (HtmlElement) super.getDomNodeOrNull();
1296     }
1297 
1298     /**
1299      * Remove focus from this element.
1300      */
1301     @JsxFunction
1302     public void blur() {
1303         getDomNodeOrDie().blur();
1304     }
1305 
1306     /**
1307      * Sets the focus to this element.
1308      */
1309     @JsxFunction
1310     public void focus() {
1311         final HtmlElement domNode = getDomNodeOrDie();
1312         if (domNode instanceof SubmittableElement) {
1313             domNode.focus();
1314         }
1315 
1316         // no action otherwise!
1317     }
1318 
1319     /**
1320      * Sets the object as active without setting focus to the object.
1321      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536738.aspx">MSDN documentation</a>
1322      */
1323     @JsxFunction(IE)
1324     public void setActive() {
1325         final Window window = getWindow();
1326         final HTMLDocument document = (HTMLDocument) window.getDocument();
1327         document.setActiveElement(this);
1328         if (window.getWebWindow() == window.getWebWindow().getWebClient().getCurrentWindow()) {
1329             final HtmlElement element = getDomNodeOrDie();
1330             ((HtmlPage) element.getPage()).setFocusedElement(element);
1331         }
1332     }
1333 
1334     /**
1335      * {@inheritDoc}
1336      */
1337     @Override
1338     public String getNodeName() {
1339         final DomNode domNode = getDomNodeOrDie();
1340         String nodeName = domNode.getNodeName();
1341         if (domNode.getHtmlPageOrNull() != null) {
1342             nodeName = nodeName.toUpperCase(Locale.ROOT);
1343         }
1344         return nodeName;
1345     }
1346 
1347     /**
1348      * {@inheritDoc}
1349      */
1350     @Override
1351     public String getPrefix() {
1352         return null;
1353     }
1354 
1355     /**
1356      * Click this element. This simulates the action of the user clicking with the mouse.
1357      * @throws IOException if this click triggers a page load that encounters problems
1358      */
1359     @JsxFunction
1360     public void click() throws IOException {
1361         // when triggered from js the visibility is ignored
1362         getDomNodeOrDie().click(false, false, false, true, true, false);
1363     }
1364 
1365     /**
1366      * Returns the {@code spellcheck} property.
1367      * @return the {@code spellcheck} property
1368      */
1369     @JsxGetter(FF)
1370     public boolean isSpellcheck() {
1371         return Context.toBoolean(getDomNodeOrDie().getAttribute("spellcheck"));
1372     }
1373 
1374     /**
1375      * Sets the {@code spellcheck} property.
1376      * @param spellcheck the {@code spellcheck} property
1377      */
1378     @JsxSetter(FF)
1379     public void setSpellcheck(final boolean spellcheck) {
1380         getDomNodeOrDie().setAttribute("spellcheck", Boolean.toString(spellcheck));
1381     }
1382 
1383     /**
1384      * Returns the {@code lang} property.
1385      * @return the {@code lang} property
1386      */
1387     @JsxGetter
1388     public String getLang() {
1389         return getDomNodeOrDie().getAttribute("lang");
1390     }
1391 
1392     /**
1393      * Sets the {@code lang} property.
1394      * @param lang the {@code lang} property
1395      */
1396     @JsxSetter
1397     public void setLang(final String lang) {
1398         getDomNodeOrDie().setAttribute("lang", lang);
1399     }
1400 
1401     /**
1402      * Returns the {@code language} property.
1403      * @return the {@code language} property
1404      */
1405     @JsxGetter(IE)
1406     public String getLanguage() {
1407         return getDomNodeOrDie().getAttribute("language");
1408     }
1409 
1410     /**
1411      * Sets the {@code language} property.
1412      * @param language the {@code language} property
1413      */
1414     @JsxSetter(IE)
1415     public void setLanguage(final String language) {
1416         getDomNodeOrDie().setAttribute("language", language);
1417     }
1418 
1419     /**
1420      * Returns the {@code dir} property.
1421      * @return the {@code dir} property
1422      */
1423     @JsxGetter
1424     public String getDir() {
1425         return getDomNodeOrDie().getAttribute("dir");
1426     }
1427 
1428     /**
1429      * Sets the {@code dir} property.
1430      * @param dir the {@code dir} property
1431      */
1432     @JsxSetter
1433     public void setDir(final String dir) {
1434         getDomNodeOrDie().setAttribute("dir", dir);
1435     }
1436 
1437     /**
1438      * Returns the value of the tabIndex attribute.
1439      * @return the value of the tabIndex attribute
1440      */
1441     @JsxGetter
1442     public int getTabIndex() {
1443         return (int) Context.toNumber(getDomNodeOrDie().getAttribute("tabindex"));
1444     }
1445 
1446     /**
1447      * Sets the {@code tabIndex} property.
1448      * @param tabIndex the {@code tabIndex} property
1449      */
1450     @JsxSetter
1451     public void setTabIndex(final int tabIndex) {
1452         getDomNodeOrDie().setAttribute("tabindex", Integer.toString(tabIndex));
1453     }
1454 
1455     /**
1456      * Returns the {@code accessKey} property.
1457      * @return the {@code accessKey} property
1458      */
1459     @JsxGetter
1460     public String getAccessKey() {
1461         return getDomNodeOrDie().getAttribute("accesskey");
1462     }
1463 
1464     /**
1465      * Sets the {@code accessKey} property.
1466      * @param accessKey the {@code accessKey} property
1467      */
1468     @JsxSetter
1469     public void setAccessKey(final String accessKey) {
1470         getDomNodeOrDie().setAttribute("accesskey", accessKey);
1471     }
1472 
1473     /**
1474      * Returns the value of the specified attribute (width or height).
1475      * @return the value of the specified attribute (width or height)
1476      * @param attributeName the name of the attribute to return (<tt>"width"</tt> or <tt>"height"</tt>)
1477      * @param returnNegativeValues if {@code true}, negative values are returned;
1478      *        if {@code false}, this method returns an empty string in lieu of negative values;
1479      *        if {@code null}, this method returns <tt>0</tt> in lieu of negative values
1480      */
1481     protected String getWidthOrHeight(final String attributeName, final Boolean returnNegativeValues) {
1482         String value = getDomNodeOrDie().getAttribute(attributeName);
1483         if (getBrowserVersion().hasFeature(JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES)) {
1484             return value;
1485         }
1486         if (!PERCENT_VALUE.matcher(value).matches()) {
1487             try {
1488                 final Float f = Float.valueOf(value);
1489                 final int i = f.intValue();
1490                 if (i < 0) {
1491                     if (returnNegativeValues == null) {
1492                         value = "0";
1493                     }
1494                     else if (!returnNegativeValues.booleanValue()) {
1495                         value = "";
1496                     }
1497                     else {
1498                         value = Integer.toString(i);
1499                     }
1500                 }
1501                 else {
1502                     value = Integer.toString(i);
1503                 }
1504             }
1505             catch (final NumberFormatException e) {
1506                 if (!getBrowserVersion().hasFeature(JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES)) {
1507                     value = "";
1508                 }
1509             }
1510         }
1511         return value;
1512     }
1513 
1514     /**
1515      * Sets the value of the specified attribute (width or height).
1516      * @param attributeName the name of the attribute to set (<tt>"width"</tt> or <tt>"height"</tt>)
1517      * @param value the value of the specified attribute (width or height)
1518      * @param allowNegativeValues if {@code true}, negative values will be stored;
1519      *        if {@code false}, negative values cause an exception to be thrown;<br>
1520      *        this check/conversion is only done if the feature JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES
1521      *        is set for the simulated browser
1522      */
1523     protected void setWidthOrHeight(final String attributeName, String value, final boolean allowNegativeValues) {
1524         if (!getBrowserVersion().hasFeature(JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES) && !value.isEmpty()) {
1525             if (value.endsWith("px")) {
1526                 value = value.substring(0, value.length() - 2);
1527             }
1528             boolean error = false;
1529             if (!PERCENT_VALUE.matcher(value).matches()) {
1530                 try {
1531                     final Float f = Float.valueOf(value);
1532                     final int i = f.intValue();
1533                     if (i < 0) {
1534                         if (!allowNegativeValues) {
1535                             error = true;
1536                         }
1537                     }
1538                 }
1539                 catch (final NumberFormatException e) {
1540                     error = true;
1541                 }
1542             }
1543             if (error) {
1544                 final Exception e = new Exception("Cannot set the '" + attributeName
1545                         + "' property to invalid value: '" + value + "'");
1546                 Context.throwAsScriptRuntimeEx(e);
1547             }
1548         }
1549         getDomNodeOrDie().setAttribute(attributeName, value);
1550     }
1551 
1552     /**
1553      * Sets the specified color attribute to the specified value.
1554      * @param name the color attribute's name
1555      * @param value the color attribute's value
1556      */
1557     protected void setColorAttribute(final String name, final String value) {
1558         String s = value;
1559         if (!s.isEmpty()) {
1560             final boolean restrict = getBrowserVersion().hasFeature(HTML_COLOR_RESTRICT);
1561 
1562             boolean isName = false;
1563             if (restrict) {
1564                 for (final String key : COLORS_MAP_IE.keySet()) {
1565                     if (key.equalsIgnoreCase(value)) {
1566                         isName = true;
1567                         break;
1568                     }
1569                 }
1570             }
1571             if (!isName) {
1572                 if (restrict) {
1573                     if (s.charAt(0) == '#') {
1574                         s = s.substring(1);
1575                     }
1576                     final StringBuilder builder = new StringBuilder(7);
1577                     for (int x = 0; x < 6 && x < s.length(); x++) {
1578                         final char ch = s.charAt(x);
1579                         if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
1580                             builder.append(ch);
1581                         }
1582                         else {
1583                             builder.append('0');
1584                         }
1585                     }
1586                     builder.insert(0, '#');
1587                     s = builder.toString();
1588                 }
1589             }
1590             if (getBrowserVersion().hasFeature(HTML_COLOR_TO_LOWER)) {
1591                 s = s.toLowerCase(Locale.ROOT);
1592             }
1593         }
1594         getDomNodeOrDie().setAttribute(name, s);
1595     }
1596 
1597     /**
1598      * Returns the value of the {@code align} property.
1599      * @param returnInvalidValues if {@code true}, this method will return any value, including technically
1600      *        invalid values; if {@code false}, this method will return an empty string instead of invalid values
1601      * @return the value of the {@code align} property
1602      */
1603     protected String getAlign(final boolean returnInvalidValues) {
1604         final boolean acceptArbitraryValues = getBrowserVersion().hasFeature(JS_ALIGN_ACCEPTS_ARBITRARY_VALUES);
1605 
1606         final String align = getDomNodeOrDie().getAttribute("align");
1607         if (returnInvalidValues || acceptArbitraryValues
1608             || "center".equals(align)
1609             || "justify".equals(align)
1610             || "left".equals(align)
1611             || "right".equals(align)) {
1612             return align;
1613         }
1614         return "";
1615     }
1616 
1617     /**
1618      * Sets the value of the {@code align} property.
1619      * @param align the value of the {@code align} property
1620      * @param ignoreIfNoError if {@code true}, the invocation will be a no-op if it does not trigger an error
1621      *        (i.e., it will not actually set the align attribute)
1622      */
1623     protected void setAlign(final String align, final boolean ignoreIfNoError) {
1624         final String alignLC = align.toLowerCase(Locale.ROOT);
1625         final boolean acceptArbitraryValues = getBrowserVersion().hasFeature(JS_ALIGN_ACCEPTS_ARBITRARY_VALUES);
1626         if (acceptArbitraryValues
1627                 || "center".equals(alignLC)
1628                 || "justify".equals(alignLC)
1629                 || "left".equals(alignLC)
1630                 || "right".equals(alignLC)
1631                 || "bottom".equals(alignLC)
1632                 || "middle".equals(alignLC)
1633                 || "top".equals(alignLC)) {
1634             if (!ignoreIfNoError) {
1635                 final String newValue = acceptArbitraryValues ? align : alignLC;
1636                 getDomNodeOrDie().setAttribute("align", newValue);
1637             }
1638             return;
1639         }
1640 
1641         throw Context.reportRuntimeError("Cannot set the align property to invalid value: '" + align + "'");
1642     }
1643 
1644     /**
1645      * Returns the value of the {@code vAlign} property.
1646      * @param valid the valid values; if {@code null}, any value is valid
1647      * @param defaultValue the default value to use, if necessary
1648      * @return the value of the {@code vAlign} property
1649      */
1650     protected String getVAlign(final String[] valid, final String defaultValue) {
1651         final String valign = getDomNodeOrDie().getAttribute("valign");
1652         if (valid == null || ArrayUtils.contains(valid, valign)) {
1653             return valign;
1654         }
1655         return defaultValue;
1656     }
1657 
1658     /**
1659      * Sets the value of the {@code vAlign} property.
1660      * @param vAlign the value of the {@code vAlign} property
1661      * @param valid the valid values; if {@code null}, any value is valid
1662      */
1663     protected void setVAlign(final Object vAlign, final String[] valid) {
1664         final String s = Context.toString(vAlign).toLowerCase(Locale.ROOT);
1665         if (valid == null || ArrayUtils.contains(valid, s)) {
1666             getDomNodeOrDie().setAttribute("valign", s);
1667         }
1668         else {
1669             throw Context.reportRuntimeError("Cannot set the vAlign property to invalid value: " + vAlign);
1670         }
1671     }
1672 
1673     /**
1674      * Returns the value of the {@code ch} property.
1675      * @return the value of the {@code ch} property
1676      */
1677     protected String getCh() {
1678         return getDomNodeOrDie().getAttribute("char");
1679     }
1680 
1681     /**
1682      * Sets the value of the {@code ch} property.
1683      * @param ch the value of the {@code ch} property
1684      */
1685     protected void setCh(final String ch) {
1686         getDomNodeOrDie().setAttribute("char", ch);
1687     }
1688 
1689     /**
1690      * Returns the value of the {@code chOff} property.
1691      * @return the value of the {@code chOff} property
1692      */
1693     protected String getChOff() {
1694         return getDomNodeOrDie().getAttribute("charOff");
1695     }
1696 
1697     /**
1698      * Sets the value of the {@code chOff} property.
1699      * @param chOff the value of the {@code chOff} property
1700      */
1701     protected void setChOff(String chOff) {
1702         try {
1703             final float f = Float.parseFloat(chOff);
1704             final int i = (int) f;
1705             if (i == f) {
1706                 chOff = Integer.toString(i);
1707             }
1708             else {
1709                 chOff = Float.toString(f);
1710             }
1711         }
1712         catch (final NumberFormatException e) {
1713             // Ignore.
1714         }
1715         getDomNodeOrDie().setAttribute("charOff", chOff);
1716     }
1717 
1718     /**
1719      * Returns this element's <tt>offsetLeft</tt>, which is the calculated left position of this
1720      * element relative to the <tt>offsetParent</tt>.
1721      *
1722      * @return this element's <tt>offsetLeft</tt>
1723      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534200.aspx">MSDN Documentation</a>
1724      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1725      * @see <a href="http://dump.testsuite.org/2006/dom/style/offset/spec">Reverse Engineering by Anne van Kesteren</a>
1726      */
1727     @JsxGetter
1728     public int getOffsetLeft() {
1729         if (this instanceof HTMLBodyElement) {
1730             return 0;
1731         }
1732 
1733         int left = 0;
1734         final HTMLElement offsetParent = getOffsetParent();
1735 
1736         // Add the offset for this node.
1737         DomNode node = getDomNodeOrDie();
1738         HTMLElement element = (HTMLElement) node.getScriptableObject();
1739         ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1740         left += style.getLeft(true, false, false);
1741 
1742         // If this node is absolutely positioned, we're done.
1743         final String position = style.getPositionWithInheritance();
1744         if ("absolute".equals(position)) {
1745             return left;
1746         }
1747 
1748         // Add the offset for the ancestor nodes.
1749         node = node.getParentNode();
1750         while (node != null && node.getScriptableObject() != offsetParent) {
1751             if (node.getScriptableObject() instanceof HTMLElement) {
1752                 element = (HTMLElement) node.getScriptableObject();
1753                 style = element.getWindow().getComputedStyle(element, null);
1754                 left += style.getLeft(true, true, true);
1755             }
1756             node = node.getParentNode();
1757         }
1758 
1759         if (offsetParent != null) {
1760             style = offsetParent.getWindow().getComputedStyle(offsetParent, null);
1761             left += style.getMarginLeftValue();
1762             left += style.getPaddingLeftValue();
1763         }
1764 
1765         return left;
1766     }
1767 
1768     /**
1769      * Returns this element's X position.
1770      * @return this element's X position
1771      */
1772     public int getPosX() {
1773         int cumulativeOffset = 0;
1774         HTMLElement element = this;
1775         while (element != null) {
1776             cumulativeOffset += element.getOffsetLeft();
1777             if (element != this) {
1778                 final ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1779                 cumulativeOffset += style.getBorderLeftValue();
1780             }
1781             element = element.getOffsetParent();
1782         }
1783         return cumulativeOffset;
1784     }
1785 
1786     /**
1787      * Returns this element's Y position.
1788      * @return this element's Y position
1789      */
1790     public int getPosY() {
1791         int cumulativeOffset = 0;
1792         HTMLElement element = this;
1793         while (element != null) {
1794             cumulativeOffset += element.getOffsetTop();
1795             if (element != this) {
1796                 final ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1797                 cumulativeOffset += style.getBorderTopValue();
1798             }
1799             element = element.getOffsetParent();
1800         }
1801         return cumulativeOffset;
1802     }
1803 
1804     /**
1805      * Gets the offset parent or {@code null} if this is not an {@link HTMLElement}.
1806      * @return the offset parent or {@code null}
1807      */
1808     private HTMLElement getOffsetParent() {
1809         final Object offsetParent = getOffsetParentInternal(false);
1810         if (offsetParent instanceof HTMLElement) {
1811             return (HTMLElement) offsetParent;
1812         }
1813         return null;
1814     }
1815 
1816     /**
1817      * Returns this element's {@code offsetTop}, which is the calculated top position of this
1818      * element relative to the {@code offsetParent}.
1819      *
1820      * @return this element's {@code offsetTop}
1821      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534303.aspx">MSDN Documentation</a>
1822      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1823      * @see <a href="http://dump.testsuite.org/2006/dom/style/offset/spec">Reverse Engineering by Anne van Kesteren</a>
1824      */
1825     @JsxGetter
1826     public int getOffsetTop() {
1827         if (this instanceof HTMLBodyElement) {
1828             return 0;
1829         }
1830 
1831         int top = 0;
1832         final HTMLElement offsetParent = getOffsetParent();
1833 
1834         // Add the offset for this node.
1835         DomNode node = getDomNodeOrDie();
1836         HTMLElement element = (HTMLElement) node.getScriptableObject();
1837         ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1838         top += style.getTop(true, false, false);
1839 
1840         // If this node is absolutely positioned, we're done.
1841         final String position = style.getPositionWithInheritance();
1842         if ("absolute".equals(position)) {
1843             return top;
1844         }
1845 
1846         // Add the offset for the ancestor nodes.
1847         node = node.getParentNode();
1848         while (node != null && node.getScriptableObject() != offsetParent) {
1849             if (node.getScriptableObject() instanceof HTMLElement) {
1850                 element = (HTMLElement) node.getScriptableObject();
1851                 style = element.getWindow().getComputedStyle(element, null);
1852                 top += style.getTop(false, true, true);
1853             }
1854             node = node.getParentNode();
1855         }
1856 
1857         if (offsetParent != null) {
1858             final HTMLElement thiz = (HTMLElement) getDomNodeOrDie().getScriptableObject();
1859             style = thiz.getWindow().getComputedStyle(thiz, null);
1860             final boolean thisElementHasTopMargin = style.getMarginTopValue() != 0;
1861 
1862             style = offsetParent.getWindow().getComputedStyle(offsetParent, null);
1863             if (!thisElementHasTopMargin) {
1864                 top += style.getMarginTopValue();
1865             }
1866             top += style.getPaddingTopValue();
1867         }
1868 
1869         return top;
1870     }
1871 
1872     /**
1873      * Returns this element's <tt>offsetParent</tt>. The <tt>offsetLeft</tt> and
1874      * <tt>offsetTop</tt> attributes are relative to the <tt>offsetParent</tt>.
1875      *
1876      * @return this element's <tt>offsetParent</tt>. This may be <code>undefined</code> when this node is
1877      * not attached or {@code null} for <code>body</code>.
1878      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534302.aspx">MSDN Documentation</a>
1879      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_el_ref20.html">Gecko DOM Reference</a>
1880      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1881      * @see <a href="http://www.w3.org/TR/REC-CSS2/box.html">Box Model</a>
1882      * @see <a href="http://dump.testsuite.org/2006/dom/style/offset/spec">Reverse Engineering by Anne van Kesteren</a>
1883      */
1884     @JsxGetter(propertyName = "offsetParent")
1885     public Object getOffsetParent_js() {
1886         return getOffsetParentInternal(getBrowserVersion().hasFeature(JS_OFFSET_PARENT_NULL_IF_FIXED));
1887     }
1888 
1889     private Object getOffsetParentInternal(final boolean returnNullIfFixed) {
1890         DomNode currentElement = getDomNodeOrDie();
1891 
1892         if (currentElement.getParentNode() == null) {
1893             return null;
1894         }
1895 
1896         Object offsetParent = null;
1897         final HTMLElement htmlElement = (HTMLElement) currentElement.getScriptableObject();
1898         if (returnNullIfFixed && "fixed".equals(htmlElement.getStyle().getStyleAttribute(
1899                 StyleAttributes.Definition.POSITION, true))) {
1900             return null;
1901         }
1902 
1903         final ComputedCSSStyleDeclaration style = htmlElement.getWindow().getComputedStyle(htmlElement, null);
1904         final String position = style.getPositionWithInheritance();
1905         final boolean staticPos = "static".equals(position);
1906 
1907         final boolean useTables = staticPos;
1908 
1909         while (currentElement != null) {
1910 
1911             final DomNode parentNode = currentElement.getParentNode();
1912             if (parentNode instanceof HtmlBody
1913                 || (useTables && parentNode instanceof HtmlTableDataCell)
1914                 || (useTables && parentNode instanceof HtmlTable)) {
1915                 offsetParent = parentNode.getScriptableObject();
1916                 break;
1917             }
1918 
1919             if (parentNode != null && parentNode.getScriptableObject() instanceof HTMLElement) {
1920                 final HTMLElement parentElement = (HTMLElement) parentNode.getScriptableObject();
1921                 final ComputedCSSStyleDeclaration parentStyle =
1922                             parentElement.getWindow().getComputedStyle(parentElement, null);
1923                 final String parentPosition = parentStyle.getPositionWithInheritance();
1924                 final boolean parentIsStatic = "static".equals(parentPosition);
1925                 if (!parentIsStatic) {
1926                     offsetParent = parentNode.getScriptableObject();
1927                     break;
1928                 }
1929             }
1930 
1931             currentElement = currentElement.getParentNode();
1932         }
1933 
1934         return offsetParent;
1935     }
1936 
1937     /**
1938      * {@inheritDoc}
1939      */
1940     @Override
1941     public ClientRect getBoundingClientRect() {
1942         final ClientRect textRectangle = super.getBoundingClientRect();
1943 
1944         int left = getPosX();
1945         int top = getPosY();
1946 
1947         // account for any scrolled ancestors
1948         Object parentNode = getOffsetParentInternal(false);
1949         while (parentNode != null
1950                 && (parentNode instanceof HTMLElement)
1951                 && !(parentNode instanceof HTMLBodyElement)) {
1952             final HTMLElement elem = (HTMLElement) parentNode;
1953             left -= elem.getScrollLeft();
1954             top -= elem.getScrollTop();
1955 
1956             parentNode = elem.getParentNode();
1957         }
1958 
1959         textRectangle.setBottom(top + getOffsetHeight());
1960         textRectangle.setLeft(left);
1961         textRectangle.setRight(left + getOffsetWidth());
1962         textRectangle.setTop(top);
1963 
1964         return textRectangle;
1965     }
1966 
1967     /**
1968      * Gets the token list of class attribute.
1969      * @return the token list of class attribute
1970      */
1971     @Override
1972     @JsxGetter
1973     public DOMTokenList getClassList() {
1974         return new DOMTokenList(this, "class");
1975     }
1976 
1977     /**
1978      * {@inheritDoc} Overridden to modify browser configurations.
1979      */
1980     @Override
1981     @JsxFunction
1982     public boolean hasAttribute(final String name) {
1983         return super.hasAttribute(name);
1984     }
1985 
1986     /**
1987      * {@inheritDoc} Overridden to modify browser configurations.
1988      */
1989     @Override
1990     @JsxGetter(IE)
1991     public HTMLCollection getChildren() {
1992         return super.getChildren();
1993     }
1994 
1995     /**
1996      * {@inheritDoc} Overridden to modify browser configurations.
1997      */
1998     @Override
1999     @JsxGetter
2000     public Element getParentElement() {
2001         return super.getParentElement();
2002     }
2003 
2004     /**
2005      * Returns the {@code dataset} attribute.
2006      * @return the {@code dataset} attribute
2007      */
2008     @JsxGetter({CHROME, FF,
2009         IE})
2010     public DOMStringMap getDataset() {
2011         return new DOMStringMap(this);
2012     }
2013 
2014     /**
2015      * {@inheritDoc}
2016      */
2017     @Override
2018     protected boolean isEndTagForbidden() {
2019         return endTagForbidden_;
2020     }
2021 
2022     /**
2023      * Returns whether the tag is lower case in .outerHTML/.innerHTML.
2024      * It seems to be a feature for HTML5 elements for IE.
2025      * @return whether the tag is lower case in .outerHTML/.innerHTML
2026      */
2027     protected boolean isLowerCaseInOuterHtml() {
2028         return false;
2029     }
2030 
2031     /**
2032      * Sets the {@code onchange} event handler for this element.
2033      * @param onchange the {@code onchange} event handler for this element
2034      */
2035     @JsxSetter
2036     public void setOnchange(final Object onchange) {
2037         setEventHandler(Event.TYPE_CHANGE, onchange);
2038     }
2039 
2040     /**
2041      * Returns the {@code onchange} event handler for this element.
2042      * @return the {@code onchange} event handler for this element
2043      */
2044     @JsxGetter
2045     public Function getOnchange() {
2046         return getEventHandler(Event.TYPE_CHANGE);
2047     }
2048 
2049     /**
2050      * Returns the {@code onsubmit} event handler for this element.
2051      * @return the {@code onsubmit} event handler for this element
2052      */
2053     @JsxGetter
2054     public Object getOnsubmit() {
2055         return getEventHandler(Event.TYPE_SUBMIT);
2056     }
2057 
2058     /**
2059      * Sets the {@code onsubmit} event handler for this element.
2060      * @param onsubmit the {@code onsubmit} event handler for this element
2061      */
2062     @JsxSetter
2063     public void setOnsubmit(final Object onsubmit) {
2064         setEventHandler(Event.TYPE_SUBMIT, onsubmit);
2065     }
2066 
2067     /**
2068      * Mock for the moment.
2069      * @param retargetToElement if true, all events are targeted directly to this element;
2070      * if false, events can also fire at descendants of this element
2071      */
2072     @JsxFunction({FF, IE})
2073     public void setCapture(final boolean retargetToElement) {
2074         // empty
2075     }
2076 
2077     /**
2078      * Mock for the moment.
2079      * @return true for success
2080      */
2081     @JsxFunction({FF, IE})
2082     public boolean releaseCapture() {
2083         return true;
2084     }
2085 
2086     /**
2087      * Returns the {@code contentEditable} property.
2088      * @return the {@code contentEditable} property
2089      */
2090     @JsxGetter
2091     public String getContentEditable() {
2092         final String attribute = getDomNodeOrDie().getAttribute("contentEditable");
2093         if (attribute == DomElement.ATTRIBUTE_NOT_DEFINED) {
2094             return "inherit";
2095         }
2096         if (attribute == DomElement.ATTRIBUTE_VALUE_EMPTY) {
2097             return "true";
2098         }
2099         return attribute;
2100     }
2101 
2102     /**
2103      * Sets the {@code contentEditable} property.
2104      * @param contentEditable the {@code contentEditable} property to set
2105      */
2106     @JsxSetter
2107     public void setContentEditable(final String contentEditable) {
2108         getDomNodeOrDie().setAttribute("contentEditable", contentEditable);
2109     }
2110 
2111     /**
2112      * Returns the {@code isContentEditable} property.
2113      * @return the {@code isContentEditable} property
2114      */
2115     @JsxGetter
2116     public boolean isIsContentEditable() {
2117         final String attribute = getContentEditable();
2118         if ("true".equals(attribute)) {
2119             return true;
2120         }
2121         else if ("inherit".equals(attribute)) {
2122             final DomNode parent = getDomNodeOrDie().getParentNode();
2123             if (parent != null) {
2124                 final Object parentScriptable = parent.getScriptableObject();
2125                 if (parentScriptable instanceof HTMLElement) {
2126                     return ((HTMLElement) parentScriptable).isIsContentEditable();
2127                 }
2128             }
2129         }
2130         return false;
2131     }
2132 
2133     /**
2134      * {@inheritDoc}
2135      */
2136     @Override
2137     @JsxGetter
2138     public CSSStyleDeclaration getStyle() {
2139         return super.getStyle();
2140     }
2141 
2142     /**
2143      * {@inheritDoc}
2144      */
2145     @Override
2146     @JsxSetter
2147     public void setStyle(final String style) {
2148         super.setStyle(style);
2149     }
2150 
2151     /**
2152      * Returns the runtime style object for this element.
2153      * @return the runtime style object for this element
2154      */
2155     @JsxGetter(IE)
2156     public CSSStyleDeclaration getRuntimeStyle() {
2157         return super.getStyle();
2158     }
2159 
2160     /**
2161      * Returns the current (calculated) style object for this element.
2162      * @return the current (calculated) style object for this element
2163      */
2164     @JsxGetter(IE)
2165     public ComputedCSSStyleDeclaration getCurrentStyle() {
2166         if (!getDomNodeOrDie().isAttachedToPage()) {
2167             return null;
2168         }
2169         return getWindow().getComputedStyle(this, null);
2170     }
2171 
2172     /**
2173      * Sets the {@code onclick} event handler for this element.
2174      * @param handler the {@code onclick} event handler for this element
2175      */
2176     @JsxSetter
2177     public void setOnclick(final Object handler) {
2178         setEventHandler(MouseEvent.TYPE_CLICK, handler);
2179     }
2180 
2181     /**
2182      * Returns the {@code onclick} event handler for this element.
2183      * @return the {@code onclick} event handler for this element
2184      */
2185     @JsxGetter
2186     public Object getOnclick() {
2187         return getEventHandler(MouseEvent.TYPE_CLICK);
2188     }
2189 
2190     /**
2191      * Sets the {@code ondblclick} event handler for this element.
2192      * @param handler the {@code ondblclick} event handler for this element
2193      */
2194     @JsxSetter
2195     public void setOndblclick(final Object handler) {
2196         setEventHandler(MouseEvent.TYPE_DBL_CLICK, handler);
2197     }
2198 
2199     /**
2200      * Returns the {@code ondblclick} event handler for this element.
2201      * @return the {@code ondblclick} event handler for this element
2202      */
2203     @JsxGetter
2204     public Object getOndblclick() {
2205         return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
2206     }
2207 
2208     /**
2209      * Sets the {@code onblur} event handler for this element.
2210      * @param handler the {@code onblur} event handler for this element
2211      */
2212     @JsxSetter
2213     public void setOnblur(final Object handler) {
2214         setEventHandler(Event.TYPE_BLUR, handler);
2215     }
2216 
2217     /**
2218      * Returns the {@code onblur} event handler for this element.
2219      * @return the {@code onblur} event handler for this element
2220      */
2221     @JsxGetter
2222     public Object getOnblur() {
2223         return getEventHandler(Event.TYPE_BLUR);
2224     }
2225 
2226     /**
2227      * Sets the {@code onfocus} event handler for this element.
2228      * @param handler the {@code onfocus} event handler for this element
2229      */
2230     @JsxSetter
2231     public void setOnfocus(final Object handler) {
2232         setEventHandler(Event.TYPE_FOCUS, handler);
2233     }
2234 
2235     /**
2236      * Returns the {@code onfocus} event handler for this element.
2237      * @return the {@code onfocus} event handler for this element
2238      */
2239     @JsxGetter
2240     public Object getOnfocus() {
2241         return getEventHandler(Event.TYPE_FOCUS);
2242     }
2243 
2244     /**
2245      * Sets the {@code onfocusin} event handler for this element.
2246      * @param handler the {@code onfocusin} event handler for this element
2247      */
2248     @JsxSetter(IE)
2249     public void setOnfocusin(final Object handler) {
2250         setEventHandler(Event.TYPE_FOCUS_IN, handler);
2251     }
2252 
2253     /**
2254      * Returns the {@code onfocusin} event handler for this element.
2255      * @return the {@code onfocusin} event handler for this element
2256      */
2257     @JsxGetter(IE)
2258     public Object getOnfocusin() {
2259         return getEventHandler(Event.TYPE_FOCUS_IN);
2260     }
2261 
2262     /**
2263      * Sets the {@code onfocusout} event handler for this element.
2264      * @param handler the {@code onfocusout} event handler for this element
2265      */
2266     @JsxSetter(IE)
2267     public void setOnfocusout(final Object handler) {
2268         setEventHandler(Event.TYPE_FOCUS_OUT, handler);
2269     }
2270 
2271     /**
2272      * Returns the {@code onfocusout} event handler for this element.
2273      * @return the {@code onfocusout} event handler for this element
2274      */
2275     @JsxGetter(IE)
2276     public Object getOnfocusout() {
2277         return getEventHandler(Event.TYPE_FOCUS_OUT);
2278     }
2279 
2280     /**
2281      * Sets the {@code onkeydown} event handler for this element.
2282      * @param handler the {@code onkeydown} event handler for this element
2283      */
2284     @JsxSetter
2285     public void setOnkeydown(final Object handler) {
2286         setEventHandler(Event.TYPE_KEY_DOWN, handler);
2287     }
2288 
2289     /**
2290      * Returns the {@code onkeydown} event handler for this element.
2291      * @return the {@code onkeydown} event handler for this element
2292      */
2293     @JsxGetter
2294     public Object getOnkeydown() {
2295         return getEventHandler(Event.TYPE_KEY_DOWN);
2296     }
2297 
2298     /**
2299      * Sets the {@code onkeypress} event handler for this element.
2300      * @param handler the {@code onkeypress} event handler for this element
2301      */
2302     @JsxSetter
2303     public void setOnkeypress(final Object handler) {
2304         setEventHandler(Event.TYPE_KEY_PRESS, handler);
2305     }
2306 
2307     /**
2308      * Returns the {@code onkeypress} event handler for this element.
2309      * @return the {@code onkeypress} event handler for this element
2310      */
2311     @JsxGetter
2312     public Object getOnkeypress() {
2313         return getEventHandler(Event.TYPE_KEY_PRESS);
2314     }
2315 
2316     /**
2317      * Sets the {@code onkeyup} event handler for this element.
2318      * @param handler the {@code onkeyup} event handler for this element
2319      */
2320     @JsxSetter
2321     public void setOnkeyup(final Object handler) {
2322         setEventHandler(Event.TYPE_KEY_UP, handler);
2323     }
2324 
2325     /**
2326      * Returns the {@code onkeyup} event handler for this element.
2327      * @return the {@code onkeyup} event handler for this element
2328      */
2329     @JsxGetter
2330     public Object getOnkeyup() {
2331         return getEventHandler(Event.TYPE_KEY_UP);
2332     }
2333 
2334     /**
2335      * Sets the {@code onmousedown} event handler for this element.
2336      * @param handler the {@code onmousedown} event handler for this element
2337      */
2338     @JsxSetter
2339     public void setOnmousedown(final Object handler) {
2340         setEventHandler(MouseEvent.TYPE_MOUSE_DOWN, handler);
2341     }
2342 
2343     /**
2344      * Returns the {@code onmousedown} event handler for this element.
2345      * @return the {@code onmousedown} event handler for this element
2346      */
2347     @JsxGetter
2348     public Object getOnmousedown() {
2349         return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
2350     }
2351 
2352     /**
2353      * Sets the {@code onmousemove} event handler for this element.
2354      * @param handler the {@code onmousemove} event handler for this element
2355      */
2356     @JsxSetter
2357     public void setOnmousemove(final Object handler) {
2358         setEventHandler(MouseEvent.TYPE_MOUSE_MOVE, handler);
2359     }
2360 
2361     /**
2362      * Returns the {@code onmousemove} event handler for this element.
2363      * @return the {@code onmousemove} event handler for this element
2364      */
2365     @JsxGetter
2366     public Object getOnmousemove() {
2367         return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
2368     }
2369 
2370     /**
2371      * Sets the {@code onmouseout} event handler for this element.
2372      * @param handler the {@code onmouseout} event handler for this element
2373      */
2374     @JsxSetter
2375     public void setOnmouseout(final Object handler) {
2376         setEventHandler(MouseEvent.TYPE_MOUSE_OUT, handler);
2377     }
2378 
2379     /**
2380      * Returns the {@code onmouseout} event handler for this element.
2381      * @return the {@code onmouseout} event handler for this element
2382      */
2383     @JsxGetter
2384     public Object getOnmouseout() {
2385         return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
2386     }
2387 
2388     /**
2389      * Sets the {@code onmouseover} event handler for this element.
2390      * @param handler the {@code onmouseover} event handler for this element
2391      */
2392     @JsxSetter
2393     public void setOnmouseover(final Object handler) {
2394         setEventHandler(MouseEvent.TYPE_MOUSE_OVER, handler);
2395     }
2396 
2397     /**
2398      * Returns the {@code onmouseover} event handler for this element.
2399      * @return the {@code onmouseover} event handler for this element
2400      */
2401     @JsxGetter
2402     public Object getOnmouseover() {
2403         return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
2404     }
2405 
2406     /**
2407      * Sets the {@code onmouseup} event handler for this element.
2408      * @param handler the {@code onmouseup} event handler for this element
2409      */
2410     @JsxSetter
2411     public void setOnmouseup(final Object handler) {
2412         setEventHandler(MouseEvent.TYPE_MOUSE_UP, handler);
2413     }
2414 
2415     /**
2416      * Returns the {@code onmouseup} event handler for this element.
2417      * @return the {@code onmouseup} event handler for this element
2418      */
2419     @JsxGetter
2420     public Object getOnmouseup() {
2421         return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
2422     }
2423 
2424     /**
2425      * Sets the {@code oncontextmenu} event handler for this element.
2426      * @param handler the {@code oncontextmenu} event handler for this element
2427      */
2428     @JsxSetter
2429     public void setOncontextmenu(final Object handler) {
2430         setEventHandler(MouseEvent.TYPE_CONTEXT_MENU, handler);
2431     }
2432 
2433     /**
2434      * Returns the {@code oncontextmenu} event handler for this element.
2435      * @return the {@code oncontextmenu} event handler for this element
2436      */
2437     @JsxGetter
2438     public Object getOncontextmenu() {
2439         return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
2440     }
2441 
2442     /**
2443      * Sets the {@code onresize} event handler for this element.
2444      * @param handler the {@code onresize} event handler for this element
2445      */
2446     @JsxSetter({CHROME, FF})
2447     public void setOnresize(final Object handler) {
2448         setEventHandler("resize", handler);
2449     }
2450 
2451     /**
2452      * Returns the {@code onresize} event handler for this element.
2453      * @return the {@code onresize} event handler for this element
2454      */
2455     @JsxGetter({CHROME, FF})
2456     public Function getOnresize() {
2457         return getEventHandler("resize");
2458     }
2459 
2460     /**
2461      * Sets the {@code onerror} event handler for this element.
2462      * @param handler the {@code onerror} event handler for this element
2463      */
2464     @JsxSetter
2465     public void setOnerror(final Object handler) {
2466         setEventHandler(Event.TYPE_ERROR, handler);
2467     }
2468 
2469     /**
2470      * Returns the {@code onerror} event handler for this element.
2471      * @return the {@code onerror} event handler for this element
2472      */
2473     @JsxGetter
2474     public Object getOnerror() {
2475         return getEventHandler(Event.TYPE_ERROR);
2476     }
2477 
2478     /**
2479      * Returns the {@code oninput} event handler for this element.
2480      * @return the {@code oninput} event handler for this element
2481      */
2482     @JsxGetter
2483     public Function getOninput() {
2484         return getEventHandler(Event.TYPE_INPUT);
2485     }
2486 
2487     /**
2488      * Sets the {@code oninput} event handler for this element.
2489      * @param oninput the {@code oninput} event handler for this element
2490      */
2491     @JsxSetter
2492     public void setOninput(final Object oninput) {
2493         setEventHandler(Event.TYPE_INPUT, oninput);
2494     }
2495 
2496     /**
2497      * {@inheritDoc}
2498      */
2499     @Override
2500     @JsxFunction(IE)
2501     public boolean contains(final Object element) {
2502         return super.contains(element);
2503     }
2504 
2505     /**
2506      * Returns the {@code hidden} property.
2507      * @return the {@code hidden} property
2508      */
2509     @JsxGetter
2510     public boolean isHidden() {
2511         return getDomNodeOrDie().hasAttribute("hidden");
2512     }
2513 
2514     /**
2515      * Sets the {@code hidden} property.
2516      * @param hidden the {@code hidden} value
2517      */
2518     @JsxSetter
2519     public void setHidden(final boolean hidden) {
2520         if (hidden) {
2521             getDomNodeOrDie().setAttribute("hidden", "hidden");
2522         }
2523         else {
2524             getDomNodeOrDie().removeAttribute("hidden");
2525         }
2526     }
2527 
2528     /**
2529      * {@inheritDoc}
2530      */
2531     @Override
2532     @JsxGetter(IE)
2533     public String getId() {
2534         return super.getId();
2535     }
2536 
2537     /**
2538      * {@inheritDoc}
2539      */
2540     @Override
2541     @JsxSetter(IE)
2542     public void setId(final String newId) {
2543         super.setId(newId);
2544     }
2545 
2546     /**
2547      * Returns the {@code onabort} event handler for this element.
2548      * @return the {@code onabort} event handler for this element
2549      */
2550     @JsxGetter
2551     public Function getOnabort() {
2552         return getEventHandler("abort");
2553     }
2554 
2555     /**
2556      * Sets the {@code onabort} event handler for this element.
2557      * @param onabort the {@code onabort} event handler for this element
2558      */
2559     @JsxSetter
2560     public void setOnabort(final Object onabort) {
2561         setEventHandler("abort", onabort);
2562     }
2563 
2564     /**
2565      * Returns the {@code onauxclick} event handler for this element.
2566      * @return the {@code onauxclick} event handler for this element
2567      */
2568     @JsxGetter(CHROME)
2569     public Function getOnauxclick() {
2570         return getEventHandler("auxclick");
2571     }
2572 
2573     /**
2574      * Sets the {@code onauxclick} event handler for this element.
2575      * @param onauxclick the {@code onauxclick} event handler for this element
2576      */
2577     @JsxSetter(CHROME)
2578     public void setOnauxclick(final Object onauxclick) {
2579         setEventHandler("auxclick", onauxclick);
2580     }
2581 
2582     /**
2583      * Returns the {@code oncancel} event handler for this element.
2584      * @return the {@code oncancel} event handler for this element
2585      */
2586     @JsxGetter(CHROME)
2587     public Function getOncancel() {
2588         return getEventHandler("cancel");
2589     }
2590 
2591     /**
2592      * Sets the {@code oncancel} event handler for this element.
2593      * @param oncancel the {@code oncancel} event handler for this element
2594      */
2595     @JsxSetter(CHROME)
2596     public void setOncancel(final Object oncancel) {
2597         setEventHandler("cancel", oncancel);
2598     }
2599 
2600     /**
2601      * Returns the {@code oncanplay} event handler for this element.
2602      * @return the {@code oncanplay} event handler for this element
2603      */
2604     @JsxGetter
2605     public Function getOncanplay() {
2606         return getEventHandler("canplay");
2607     }
2608 
2609     /**
2610      * Sets the {@code oncanplay} event handler for this element.
2611      * @param oncanplay the {@code oncanplay} event handler for this element
2612      */
2613     @JsxSetter
2614     public void setOncanplay(final Object oncanplay) {
2615         setEventHandler("canplay", oncanplay);
2616     }
2617 
2618     /**
2619      * Returns the {@code oncanplaythrough} event handler for this element.
2620      * @return the {@code oncanplaythrough} event handler for this element
2621      */
2622     @JsxGetter
2623     public Function getOncanplaythrough() {
2624         return getEventHandler("canplaythrough");
2625     }
2626 
2627     /**
2628      * Sets the {@code oncanplaythrough} event handler for this element.
2629      * @param oncanplaythrough the {@code oncanplaythrough} event handler for this element
2630      */
2631     @JsxSetter
2632     public void setOncanplaythrough(final Object oncanplaythrough) {
2633         setEventHandler("canplaythrough", oncanplaythrough);
2634     }
2635 
2636     /**
2637      * Returns the {@code onclose} event handler for this element.
2638      * @return the {@code onclose} event handler for this element
2639      */
2640     @JsxGetter(CHROME)
2641     public Function getOnclose() {
2642         return getEventHandler(Event.TYPE_CLOSE);
2643     }
2644 
2645     /**
2646      * Sets the {@code onclose} event handler for this element.
2647      * @param onclose the {@code onclose} event handler for this element
2648      */
2649     @JsxSetter(CHROME)
2650     public void setOnclose(final Object onclose) {
2651         setEventHandler(Event.TYPE_CLOSE, onclose);
2652     }
2653 
2654     /**
2655      * Returns the {@code oncuechange} event handler for this element.
2656      * @return the {@code oncuechange} event handler for this element
2657      */
2658     @JsxGetter({CHROME, IE})
2659     public Function getOncuechange() {
2660         return getEventHandler("cuechange");
2661     }
2662 
2663     /**
2664      * Sets the {@code oncuechange} event handler for this element.
2665      * @param oncuechange the {@code oncuechange} event handler for this element
2666      */
2667     @JsxSetter({CHROME, IE})
2668     public void setOncuechange(final Object oncuechange) {
2669         setEventHandler("cuechange", oncuechange);
2670     }
2671 
2672     /**
2673      * Returns the {@code ondrag} event handler for this element.
2674      * @return the {@code ondrag} event handler for this element
2675      */
2676     @JsxGetter
2677     public Function getOndrag() {
2678         return getEventHandler("drag");
2679     }
2680 
2681     /**
2682      * Sets the {@code ondrag} event handler for this element.
2683      * @param ondrag the {@code ondrag} event handler for this element
2684      */
2685     @JsxSetter
2686     public void setOndrag(final Object ondrag) {
2687         setEventHandler("drag", ondrag);
2688     }
2689 
2690     /**
2691      * Returns the {@code ondragend} event handler for this element.
2692      * @return the {@code ondragend} event handler for this element
2693      */
2694     @JsxGetter
2695     public Function getOndragend() {
2696         return getEventHandler("dragend");
2697     }
2698 
2699     /**
2700      * Sets the {@code ondragend} event handler for this element.
2701      * @param ondragend the {@code ondragend} event handler for this element
2702      */
2703     @JsxSetter
2704     public void setOndragend(final Object ondragend) {
2705         setEventHandler("dragend", ondragend);
2706     }
2707 
2708     /**
2709      * Returns the {@code ondragenter} event handler for this element.
2710      * @return the {@code ondragenter} event handler for this element
2711      */
2712     @JsxGetter
2713     public Function getOndragenter() {
2714         return getEventHandler("dragenter");
2715     }
2716 
2717     /**
2718      * Sets the {@code ondragenter} event handler for this element.
2719      * @param ondragenter the {@code ondragenter} event handler for this element
2720      */
2721     @JsxSetter
2722     public void setOndragenter(final Object ondragenter) {
2723         setEventHandler("dragenter", ondragenter);
2724     }
2725 
2726     /**
2727      * Returns the {@code ondragleave} event handler for this element.
2728      * @return the {@code ondragleave} event handler for this element
2729      */
2730     @JsxGetter
2731     public Function getOndragleave() {
2732         return getEventHandler("dragleave");
2733     }
2734 
2735     /**
2736      * Sets the {@code ondragleave} event handler for this element.
2737      * @param ondragleave the {@code ondragleave} event handler for this element
2738      */
2739     @JsxSetter
2740     public void setOndragleave(final Object ondragleave) {
2741         setEventHandler("dragleave", ondragleave);
2742     }
2743 
2744     /**
2745      * Returns the {@code ondragover} event handler for this element.
2746      * @return the {@code ondragover} event handler for this element
2747      */
2748     @JsxGetter
2749     public Function getOndragover() {
2750         return getEventHandler("dragover");
2751     }
2752 
2753     /**
2754      * Sets the {@code ondragover} event handler for this element.
2755      * @param ondragover the {@code ondragover} event handler for this element
2756      */
2757     @JsxSetter
2758     public void setOndragover(final Object ondragover) {
2759         setEventHandler("dragover", ondragover);
2760     }
2761 
2762     /**
2763      * Returns the {@code ondragstart} event handler for this element.
2764      * @return the {@code ondragstart} event handler for this element
2765      */
2766     @JsxGetter
2767     public Function getOndragstart() {
2768         return getEventHandler("dragstart");
2769     }
2770 
2771     /**
2772      * Sets the {@code ondragstart} event handler for this element.
2773      * @param ondragstart the {@code ondragstart} event handler for this element
2774      */
2775     @JsxSetter
2776     public void setOndragstart(final Object ondragstart) {
2777         setEventHandler("dragstart", ondragstart);
2778     }
2779 
2780     /**
2781      * Returns the {@code ondrop} event handler for this element.
2782      * @return the {@code ondrop} event handler for this element
2783      */
2784     @JsxGetter
2785     public Function getOndrop() {
2786         return getEventHandler("drop");
2787     }
2788 
2789     /**
2790      * Sets the {@code ondrop} event handler for this element.
2791      * @param ondrop the {@code ondrop} event handler for this element
2792      */
2793     @JsxSetter
2794     public void setOndrop(final Object ondrop) {
2795         setEventHandler("drop", ondrop);
2796     }
2797 
2798     /**
2799      * Returns the {@code ondurationchange} event handler for this element.
2800      * @return the {@code ondurationchange} event handler for this element
2801      */
2802     @JsxGetter
2803     public Function getOndurationchange() {
2804         return getEventHandler("durationchange");
2805     }
2806 
2807     /**
2808      * Sets the {@code ondurationchange} event handler for this element.
2809      * @param ondurationchange the {@code ondurationchange} event handler for this element
2810      */
2811     @JsxSetter
2812     public void setOndurationchange(final Object ondurationchange) {
2813         setEventHandler("durationchange", ondurationchange);
2814     }
2815 
2816     /**
2817      * Returns the {@code onemptied} event handler for this element.
2818      * @return the {@code onemptied} event handler for this element
2819      */
2820     @JsxGetter
2821     public Function getOnemptied() {
2822         return getEventHandler("emptied");
2823     }
2824 
2825     /**
2826      * Sets the {@code onemptied} event handler for this element.
2827      * @param onemptied the {@code onemptied} event handler for this element
2828      */
2829     @JsxSetter
2830     public void setOnemptied(final Object onemptied) {
2831         setEventHandler("emptied", onemptied);
2832     }
2833 
2834     /**
2835      * Returns the {@code onended} event handler for this element.
2836      * @return the {@code onended} event handler for this element
2837      */
2838     @JsxGetter
2839     public Function getOnended() {
2840         return getEventHandler("ended");
2841     }
2842 
2843     /**
2844      * Sets the {@code onended} event handler for this element.
2845      * @param onended the {@code onended} event handler for this element
2846      */
2847     @JsxSetter
2848     public void setOnended(final Object onended) {
2849         setEventHandler("ended", onended);
2850     }
2851 
2852     /**
2853      * Returns the {@code ongotpointercapture} event handler for this element.
2854      * @return the {@code ongotpointercapture} event handler for this element
2855      */
2856     @Override
2857     @JsxGetter(CHROME)
2858     public Function getOngotpointercapture() {
2859         return getEventHandler("gotpointercapture");
2860     }
2861 
2862     /**
2863      * Sets the {@code ongotpointercapture} event handler for this element.
2864      * @param ongotpointercapture the {@code ongotpointercapture} event handler for this element
2865      */
2866     @Override
2867     @JsxSetter(CHROME)
2868     public void setOngotpointercapture(final Object ongotpointercapture) {
2869         setEventHandler("gotpointercapture", ongotpointercapture);
2870     }
2871 
2872     /**
2873      * Returns the {@code oninvalid} event handler for this element.
2874      * @return the {@code oninvalid} event handler for this element
2875      */
2876     @JsxGetter({CHROME, FF})
2877     public Function getOninvalid() {
2878         return getEventHandler("invalid");
2879     }
2880 
2881     /**
2882      * Sets the {@code oninvalid} event handler for this element.
2883      * @param oninvalid the {@code oninvalid} event handler for this element
2884      */
2885     @JsxSetter({CHROME, FF})
2886     public void setOninvalid(final Object oninvalid) {
2887         setEventHandler("invalid", oninvalid);
2888     }
2889 
2890     /**
2891      * Returns the {@code onload} event handler for this element.
2892      * @return the {@code onload} event handler for this element
2893      */
2894     @JsxGetter
2895     public Function getOnload() {
2896         return getEventHandler(Event.TYPE_LOAD);
2897     }
2898 
2899     /**
2900      * Sets the {@code onload} event handler for this element.
2901      * @param onload the {@code onload} event handler for this element
2902      */
2903     @JsxSetter
2904     public void setOnload(final Object onload) {
2905         setEventHandler(Event.TYPE_LOAD, onload);
2906     }
2907 
2908     /**
2909      * Returns the {@code onloadeddata} event handler for this element.
2910      * @return the {@code onloadeddata} event handler for this element
2911      */
2912     @JsxGetter
2913     public Function getOnloadeddata() {
2914         return getEventHandler("loadeddata");
2915     }
2916 
2917     /**
2918      * Sets the {@code onloadeddata} event handler for this element.
2919      * @param onloadeddata the {@code onloadeddata} event handler for this element
2920      */
2921     @JsxSetter
2922     public void setOnloadeddata(final Object onloadeddata) {
2923         setEventHandler("loadeddata", onloadeddata);
2924     }
2925 
2926     /**
2927      * Returns the {@code onloadedmetadata} event handler for this element.
2928      * @return the {@code onloadedmetadata} event handler for this element
2929      */
2930     @JsxGetter
2931     public Function getOnloadedmetadata() {
2932         return getEventHandler("loadedmetadata");
2933     }
2934 
2935     /**
2936      * Sets the {@code onloadedmetadata} event handler for this element.
2937      * @param onloadedmetadata the {@code onloadedmetadata} event handler for this element
2938      */
2939     @JsxSetter
2940     public void setOnloadedmetadata(final Object onloadedmetadata) {
2941         setEventHandler("loadedmetadata", onloadedmetadata);
2942     }
2943 
2944     /**
2945      * Returns the {@code onloadstart} event handler for this element.
2946      * @return the {@code onloadstart} event handler for this element
2947      */
2948     @JsxGetter
2949     public Function getOnloadstart() {
2950         return getEventHandler("loadstart");
2951     }
2952 
2953     /**
2954      * Sets the {@code onloadstart} event handler for this element.
2955      * @param onloadstart the {@code onloadstart} event handler for this element
2956      */
2957     @JsxSetter
2958     public void setOnloadstart(final Object onloadstart) {
2959         setEventHandler("loadstart", onloadstart);
2960     }
2961 
2962     /**
2963      * Returns the {@code onlostpointercapture} event handler for this element.
2964      * @return the {@code onlostpointercapture} event handler for this element
2965      */
2966     @Override
2967     @JsxGetter(CHROME)
2968     public Function getOnlostpointercapture() {
2969         return getEventHandler("lostpointercapture");
2970     }
2971 
2972     /**
2973      * Sets the {@code onlostpointercapture} event handler for this element.
2974      * @param onlostpointercapture the {@code onlostpointercapture} event handler for this element
2975      */
2976     @Override
2977     @JsxSetter(CHROME)
2978     public void setOnlostpointercapture(final Object onlostpointercapture) {
2979         setEventHandler("lostpointercapture", onlostpointercapture);
2980     }
2981 
2982     /**
2983      * Returns the {@code onmouseenter} event handler for this element.
2984      * @return the {@code onmouseenter} event handler for this element
2985      */
2986     @JsxGetter
2987     public Function getOnmouseenter() {
2988         return getEventHandler("mouseenter");
2989     }
2990 
2991     /**
2992      * Sets the {@code onmouseenter} event handler for this element.
2993      * @param onmouseenter the {@code onmouseenter} event handler for this element
2994      */
2995     @JsxSetter
2996     public void setOnmouseenter(final Object onmouseenter) {
2997         setEventHandler("mouseenter", onmouseenter);
2998     }
2999 
3000     /**
3001      * Returns the {@code onmouseleave} event handler for this element.
3002      * @return the {@code onmouseleave} event handler for this element
3003      */
3004     @JsxGetter
3005     public Function getOnmouseleave() {
3006         return getEventHandler("mouseleave");
3007     }
3008 
3009     /**
3010      * Sets the {@code onmouseleave} event handler for this element.
3011      * @param onmouseleave the {@code onmouseleave} event handler for this element
3012      */
3013     @JsxSetter
3014     public void setOnmouseleave(final Object onmouseleave) {
3015         setEventHandler("mouseleave", onmouseleave);
3016     }
3017 
3018     /**
3019      * Returns the {@code onmousewheel} event handler for this element.
3020      * @return the {@code onmousewheel} event handler for this element
3021      */
3022     @JsxGetter({CHROME, IE})
3023     public Function getOnmousewheel() {
3024         return getEventHandler("mousewheel");
3025     }
3026 
3027     /**
3028      * Sets the {@code onmousewheel} event handler for this element.
3029      * @param onmousewheel the {@code onmousewheel} event handler for this element
3030      */
3031     @JsxSetter({CHROME, IE})
3032     public void setOnmousewheel(final Object onmousewheel) {
3033         setEventHandler("mousewheel", onmousewheel);
3034     }
3035 
3036     /**
3037      * Returns the {@code onpause} event handler for this element.
3038      * @return the {@code onpause} event handler for this element
3039      */
3040     @JsxGetter
3041     public Function getOnpause() {
3042         return getEventHandler("pause");
3043     }
3044 
3045     /**
3046      * Sets the {@code onpause} event handler for this element.
3047      * @param onpause the {@code onpause} event handler for this element
3048      */
3049     @JsxSetter
3050     public void setOnpause(final Object onpause) {
3051         setEventHandler("pause", onpause);
3052     }
3053 
3054     /**
3055      * Returns the {@code onplay} event handler for this element.
3056      * @return the {@code onplay} event handler for this element
3057      */
3058     @JsxGetter
3059     public Function getOnplay() {
3060         return getEventHandler("play");
3061     }
3062 
3063     /**
3064      * Sets the {@code onplay} event handler for this element.
3065      * @param onplay the {@code onplay} event handler for this element
3066      */
3067     @JsxSetter
3068     public void setOnplay(final Object onplay) {
3069         setEventHandler("play", onplay);
3070     }
3071 
3072     /**
3073      * Returns the {@code onplaying} event handler for this element.
3074      * @return the {@code onplaying} event handler for this element
3075      */
3076     @JsxGetter
3077     public Function getOnplaying() {
3078         return getEventHandler("playing");
3079     }
3080 
3081     /**
3082      * Sets the {@code onplaying} event handler for this element.
3083      * @param onplaying the {@code onplaying} event handler for this element
3084      */
3085     @JsxSetter
3086     public void setOnplaying(final Object onplaying) {
3087         setEventHandler("playing", onplaying);
3088     }
3089 
3090     /**
3091      * Returns the {@code onpointercancel} event handler for this element.
3092      * @return the {@code onpointercancel} event handler for this element
3093      */
3094     @Override
3095     @JsxGetter(CHROME)
3096     public Function getOnpointercancel() {
3097         return getEventHandler("pointercancel");
3098     }
3099 
3100     /**
3101      * Sets the {@code onpointercancel} event handler for this element.
3102      * @param onpointercancel the {@code onpointercancel} event handler for this element
3103      */
3104     @Override
3105     @JsxSetter(CHROME)
3106     public void setOnpointercancel(final Object onpointercancel) {
3107         setEventHandler("pointercancel", onpointercancel);
3108     }
3109 
3110     /**
3111      * Returns the {@code onpointerdown} event handler for this element.
3112      * @return the {@code onpointerdown} event handler for this element
3113      */
3114     @Override
3115     @JsxGetter(CHROME)
3116     public Function getOnpointerdown() {
3117         return getEventHandler("pointerdown");
3118     }
3119 
3120     /**
3121      * Sets the {@code onpointerdown} event handler for this element.
3122      * @param onpointerdown the {@code onpointerdown} event handler for this element
3123      */
3124     @Override
3125     @JsxSetter(CHROME)
3126     public void setOnpointerdown(final Object onpointerdown) {
3127         setEventHandler("pointerdown", onpointerdown);
3128     }
3129 
3130     /**
3131      * Returns the {@code onpointerenter} event handler for this element.
3132      * @return the {@code onpointerenter} event handler for this element
3133      */
3134     @Override
3135     @JsxGetter(CHROME)
3136     public Function getOnpointerenter() {
3137         return getEventHandler("pointerenter");
3138     }
3139 
3140     /**
3141      * Sets the {@code onpointerenter} event handler for this element.
3142      * @param onpointerenter the {@code onpointerenter} event handler for this element
3143      */
3144     @Override
3145     @JsxSetter(CHROME)
3146     public void setOnpointerenter(final Object onpointerenter) {
3147         setEventHandler("pointerenter", onpointerenter);
3148     }
3149 
3150     /**
3151      * Returns the {@code onpointerleave} event handler for this element.
3152      * @return the {@code onpointerleave} event handler for this element
3153      */
3154     @Override
3155     @JsxGetter(CHROME)
3156     public Function getOnpointerleave() {
3157         return getEventHandler("pointerleave");
3158     }
3159 
3160     /**
3161      * Sets the {@code onpointerleave} event handler for this element.
3162      * @param onpointerleave the {@code onpointerleave} event handler for this element
3163      */
3164     @Override
3165     @JsxSetter(CHROME)
3166     public void setOnpointerleave(final Object onpointerleave) {
3167         setEventHandler("pointerleave", onpointerleave);
3168     }
3169 
3170     /**
3171      * Returns the {@code onpointermove} event handler for this element.
3172      * @return the {@code onpointermove} event handler for this element
3173      */
3174     @Override
3175     @JsxGetter(CHROME)
3176     public Function getOnpointermove() {
3177         return getEventHandler("pointermove");
3178     }
3179 
3180     /**
3181      * Sets the {@code onpointermove} event handler for this element.
3182      * @param onpointermove the {@code onpointermove} event handler for this element
3183      */
3184     @Override
3185     @JsxSetter(CHROME)
3186     public void setOnpointermove(final Object onpointermove) {
3187         setEventHandler("pointermove", onpointermove);
3188     }
3189 
3190     /**
3191      * Returns the {@code onpointerout} event handler for this element.
3192      * @return the {@code onpointerout} event handler for this element
3193      */
3194     @Override
3195     @JsxGetter(CHROME)
3196     public Function getOnpointerout() {
3197         return getEventHandler("pointerout");
3198     }
3199 
3200     /**
3201      * Sets the {@code onpointerout} event handler for this element.
3202      * @param onpointerout the {@code onpointerout} event handler for this element
3203      */
3204     @Override
3205     @JsxSetter(CHROME)
3206     public void setOnpointerout(final Object onpointerout) {
3207         setEventHandler("pointerout", onpointerout);
3208     }
3209 
3210     /**
3211      * Returns the {@code onpointerover} event handler for this element.
3212      * @return the {@code onpointerover} event handler for this element
3213      */
3214     @Override
3215     @JsxGetter(CHROME)
3216     public Function getOnpointerover() {
3217         return getEventHandler("pointerover");
3218     }
3219 
3220     /**
3221      * Sets the {@code onpointerover} event handler for this element.
3222      * @param onpointerover the {@code onpointerover} event handler for this element
3223      */
3224     @Override
3225     @JsxSetter(CHROME)
3226     public void setOnpointerover(final Object onpointerover) {
3227         setEventHandler("pointerover", onpointerover);
3228     }
3229 
3230     /**
3231      * Returns the {@code onpointerup} event handler for this element.
3232      * @return the {@code onpointerup} event handler for this element
3233      */
3234     @Override
3235     @JsxGetter(CHROME)
3236     public Function getOnpointerup() {
3237         return getEventHandler("pointerup");
3238     }
3239 
3240     /**
3241      * Sets the {@code onpointerup} event handler for this element.
3242      * @param onpointerup the {@code onpointerup} event handler for this element
3243      */
3244     @Override
3245     @JsxSetter(CHROME)
3246     public void setOnpointerup(final Object onpointerup) {
3247         setEventHandler("pointerup", onpointerup);
3248     }
3249 
3250     /**
3251      * Returns the {@code onprogress} event handler for this element.
3252      * @return the {@code onprogress} event handler for this element
3253      */
3254     @JsxGetter
3255     public Function getOnprogress() {
3256         return getEventHandler("progress");
3257     }
3258 
3259     /**
3260      * Sets the {@code onprogress} event handler for this element.
3261      * @param onprogress the {@code onprogress} event handler for this element
3262      */
3263     @JsxSetter
3264     public void setOnprogress(final Object onprogress) {
3265         setEventHandler("progress", onprogress);
3266     }
3267 
3268     /**
3269      * Returns the {@code onratechange} event handler for this element.
3270      * @return the {@code onratechange} event handler for this element
3271      */
3272     @JsxGetter
3273     public Function getOnratechange() {
3274         return getEventHandler("ratechange");
3275     }
3276 
3277     /**
3278      * Sets the {@code onratechange} event handler for this element.
3279      * @param onratechange the {@code onratechange} event handler for this element
3280      */
3281     @JsxSetter
3282     public void setOnratechange(final Object onratechange) {
3283         setEventHandler("ratechange", onratechange);
3284     }
3285 
3286     /**
3287      * Returns the {@code onreset} event handler for this element.
3288      * @return the {@code onreset} event handler for this element
3289      */
3290     @JsxGetter
3291     public Function getOnreset() {
3292         return getEventHandler(Event.TYPE_RESET);
3293     }
3294 
3295     /**
3296      * Sets the {@code onreset} event handler for this element.
3297      * @param onreset the {@code onreset} event handler for this element
3298      */
3299     @JsxSetter
3300     public void setOnreset(final Object onreset) {
3301         setEventHandler(Event.TYPE_RESET, onreset);
3302     }
3303 
3304     /**
3305      * Returns the {@code onscroll} event handler for this element.
3306      * @return the {@code onscroll} event handler for this element
3307      */
3308     @JsxGetter
3309     public Function getOnscroll() {
3310         return getEventHandler("scroll");
3311     }
3312 
3313     /**
3314      * Sets the {@code onscroll} event handler for this element.
3315      * @param onscroll the {@code onscroll} event handler for this element
3316      */
3317     @JsxSetter
3318     public void setOnscroll(final Object onscroll) {
3319         setEventHandler("scroll", onscroll);
3320     }
3321 
3322     /**
3323      * Returns the {@code onseeked} event handler for this element.
3324      * @return the {@code onseeked} event handler for this element
3325      */
3326     @JsxGetter
3327     public Function getOnseeked() {
3328         return getEventHandler("seeked");
3329     }
3330 
3331     /**
3332      * Sets the {@code onseeked} event handler for this element.
3333      * @param onseeked the {@code onseeked} event handler for this element
3334      */
3335     @JsxSetter
3336     public void setOnseeked(final Object onseeked) {
3337         setEventHandler("seeked", onseeked);
3338     }
3339 
3340     /**
3341      * Returns the {@code onseeking} event handler for this element.
3342      * @return the {@code onseeking} event handler for this element
3343      */
3344     @JsxGetter
3345     public Function getOnseeking() {
3346         return getEventHandler("seeking");
3347     }
3348 
3349     /**
3350      * Sets the {@code onseeking} event handler for this element.
3351      * @param onseeking the {@code onseeking} event handler for this element
3352      */
3353     @JsxSetter
3354     public void setOnseeking(final Object onseeking) {
3355         setEventHandler("seeking", onseeking);
3356     }
3357 
3358     /**
3359      * Returns the {@code onselect} event handler for this element.
3360      * @return the {@code onselect} event handler for this element
3361      */
3362     @JsxGetter
3363     public Function getOnselect() {
3364         return getEventHandler("select");
3365     }
3366 
3367     /**
3368      * Sets the {@code onselect} event handler for this element.
3369      * @param onselect the {@code onselect} event handler for this element
3370      */
3371     @JsxSetter
3372     public void setOnselect(final Object onselect) {
3373         setEventHandler("select", onselect);
3374     }
3375 
3376     /**
3377      * Returns the {@code onshow} event handler for this element.
3378      * @return the {@code onshow} event handler for this element
3379      */
3380     @JsxGetter({CHROME, FF})
3381     public Function getOnshow() {
3382         return getEventHandler("show");
3383     }
3384 
3385     /**
3386      * Sets the {@code onshow} event handler for this element.
3387      * @param onshow the {@code onshow} event handler for this element
3388      */
3389     @JsxSetter({CHROME, FF})
3390     public void setOnshow(final Object onshow) {
3391         setEventHandler("show", onshow);
3392     }
3393 
3394     /**
3395      * Returns the {@code onstalled} event handler for this element.
3396      * @return the {@code onstalled} event handler for this element
3397      */
3398     @JsxGetter
3399     public Function getOnstalled() {
3400         return getEventHandler("stalled");
3401     }
3402 
3403     /**
3404      * Sets the {@code onstalled} event handler for this element.
3405      * @param onstalled the {@code onstalled} event handler for this element
3406      */
3407     @JsxSetter
3408     public void setOnstalled(final Object onstalled) {
3409         setEventHandler("stalled", onstalled);
3410     }
3411 
3412     /**
3413      * Returns the {@code onsuspend} event handler for this element.
3414      * @return the {@code onsuspend} event handler for this element
3415      */
3416     @JsxGetter
3417     public Function getOnsuspend() {
3418         return getEventHandler("suspend");
3419     }
3420 
3421     /**
3422      * Sets the {@code onsuspend} event handler for this element.
3423      * @param onsuspend the {@code onsuspend} event handler for this element
3424      */
3425     @JsxSetter
3426     public void setOnsuspend(final Object onsuspend) {
3427         setEventHandler("suspend", onsuspend);
3428     }
3429 
3430     /**
3431      * Returns the {@code ontimeupdate} event handler for this element.
3432      * @return the {@code ontimeupdate} event handler for this element
3433      */
3434     @JsxGetter
3435     public Function getOntimeupdate() {
3436         return getEventHandler("timeupdate");
3437     }
3438 
3439     /**
3440      * Sets the {@code ontimeupdate} event handler for this element.
3441      * @param ontimeupdate the {@code ontimeupdate} event handler for this element
3442      */
3443     @JsxSetter
3444     public void setOntimeupdate(final Object ontimeupdate) {
3445         setEventHandler("timeupdate", ontimeupdate);
3446     }
3447 
3448     /**
3449      * Returns the {@code ontoggle} event handler for this element.
3450      * @return the {@code ontoggle} event handler for this element
3451      */
3452     @JsxGetter({CHROME, FF52})
3453     public Function getOntoggle() {
3454         return getEventHandler("toggle");
3455     }
3456 
3457     /**
3458      * Sets the {@code ontoggle} event handler for this element.
3459      * @param ontoggle the {@code ontoggle} event handler for this element
3460      */
3461     @JsxSetter({CHROME, FF52})
3462     public void setOntoggle(final Object ontoggle) {
3463         setEventHandler("toggle", ontoggle);
3464     }
3465 
3466     /**
3467      * Returns the {@code onvolumechange} event handler for this element.
3468      * @return the {@code onvolumechange} event handler for this element
3469      */
3470     @JsxGetter
3471     public Function getOnvolumechange() {
3472         return getEventHandler("volumechange");
3473     }
3474 
3475     /**
3476      * Sets the {@code onvolumechange} event handler for this element.
3477      * @param onvolumechange the {@code onvolumechange} event handler for this element
3478      */
3479     @JsxSetter
3480     public void setOnvolumechange(final Object onvolumechange) {
3481         setEventHandler("volumechange", onvolumechange);
3482     }
3483 
3484     /**
3485      * Returns the {@code onwaiting} event handler for this element.
3486      * @return the {@code onwaiting} event handler for this element
3487      */
3488     @JsxGetter
3489     public Function getOnwaiting() {
3490         return getEventHandler("waiting");
3491     }
3492 
3493     /**
3494      * Sets the {@code onwaiting} event handler for this element.
3495      * @param onwaiting the {@code onwaiting} event handler for this element
3496      */
3497     @JsxSetter
3498     public void setOnwaiting(final Object onwaiting) {
3499         setEventHandler("waiting", onwaiting);
3500     }
3501 
3502     /**
3503      * Returns the {@code oncopy} event handler for this element.
3504      * @return the {@code oncopy} event handler for this element
3505      */
3506     @Override
3507     @JsxGetter({FF, IE})
3508     public Function getOncopy() {
3509         return getEventHandler("copy");
3510     }
3511 
3512     /**
3513      * Sets the {@code oncopy} event handler for this element.
3514      * @param oncopy the {@code oncopy} event handler for this element
3515      */
3516     @Override
3517     @JsxSetter({FF, IE})
3518     public void setOncopy(final Object oncopy) {
3519         setEventHandler("copy", oncopy);
3520     }
3521 
3522     /**
3523      * Returns the {@code oncut} event handler for this element.
3524      * @return the {@code oncut} event handler for this element
3525      */
3526     @Override
3527     @JsxGetter({FF, IE})
3528     public Function getOncut() {
3529         return getEventHandler("cut");
3530     }
3531 
3532     /**
3533      * Sets the {@code oncut} event handler for this element.
3534      * @param oncut the {@code oncut} event handler for this element
3535      */
3536     @Override
3537     @JsxSetter({FF, IE})
3538     public void setOncut(final Object oncut) {
3539         setEventHandler("cut", oncut);
3540     }
3541 
3542     /**
3543      * Returns the {@code onpaste} event handler for this element.
3544      * @return the {@code onpaste} event handler for this element
3545      */
3546     @Override
3547     @JsxGetter({FF, IE})
3548     public Function getOnpaste() {
3549         return getEventHandler("paste");
3550     }
3551 
3552     /**
3553      * Sets the {@code onpaste} event handler for this element.
3554      * @param onpaste the {@code onpaste} event handler for this element
3555      */
3556     @Override
3557     @JsxSetter({FF, IE})
3558     public void setOnpaste(final Object onpaste) {
3559         setEventHandler("paste", onpaste);
3560     }
3561 
3562     /**
3563      * Returns the {@code onmozfullscreenchange} event handler for this element.
3564      * @return the {@code onmozfullscreenchange} event handler for this element
3565      */
3566     @JsxGetter(FF)
3567     public Function getOnmozfullscreenchange() {
3568         return getEventHandler("mozfullscreenchange");
3569     }
3570 
3571     /**
3572      * Sets the {@code onmozfullscreenchange} event handler for this element.
3573      * @param onmozfullscreenchange the {@code onmozfullscreenchange} event handler for this element
3574      */
3575     @JsxSetter(FF)
3576     public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
3577         setEventHandler("mozfullscreenchange", onmozfullscreenchange);
3578     }
3579 
3580     /**
3581      * Returns the {@code onmozfullscreenerror} event handler for this element.
3582      * @return the {@code onmozfullscreenerror} event handler for this element
3583      */
3584     @JsxGetter(FF)
3585     public Function getOnmozfullscreenerror() {
3586         return getEventHandler("mozfullscreenerror");
3587     }
3588 
3589     /**
3590      * Sets the {@code onmozfullscreenerror} event handler for this element.
3591      * @param onmozfullscreenerror the {@code onmozfullscreenerror} event handler for this element
3592      */
3593     @JsxSetter(FF)
3594     public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
3595         setEventHandler("mozfullscreenerror", onmozfullscreenerror);
3596     }
3597 
3598     /**
3599      * Returns the {@code onmozpointerlockchange} event handler for this element.
3600      * @return the {@code onmozpointerlockchange} event handler for this element
3601      */
3602     @JsxGetter(FF45)
3603     public Function getOnmozpointerlockchange() {
3604         return getEventHandler("mozpointerlockchange");
3605     }
3606 
3607     /**
3608      * Sets the {@code onmozpointerlockchange} event handler for this element.
3609      * @param onmozpointerlockchange the {@code onmozpointerlockchange} event handler for this element
3610      */
3611     @JsxSetter(FF45)
3612     public void setOnmozpointerlockchange(final Object onmozpointerlockchange) {
3613         setEventHandler("mozpointerlockchange", onmozpointerlockchange);
3614     }
3615 
3616     /**
3617      * Returns the {@code onmozpointerlockerror} event handler for this element.
3618      * @return the {@code onmozpointerlockerror} event handler for this element
3619      */
3620     @JsxGetter(FF45)
3621     public Function getOnmozpointerlockerror() {
3622         return getEventHandler("mozpointerlockerror");
3623     }
3624 
3625     /**
3626      * Sets the {@code onmozpointerlockerror} event handler for this element.
3627      * @param onmozpointerlockerror the {@code onmozpointerlockerror} event handler for this element
3628      */
3629     @JsxSetter(FF45)
3630     public void setOnmozpointerlockerror(final Object onmozpointerlockerror) {
3631         setEventHandler("mozpointerlockerror", onmozpointerlockerror);
3632     }
3633 
3634     /**
3635      * Returns the {@code onactivate} event handler for this element.
3636      * @return the {@code onactivate} event handler for this element
3637      */
3638     @JsxGetter(IE)
3639     public Function getOnactivate() {
3640         return getEventHandler("activate");
3641     }
3642 
3643     /**
3644      * Sets the {@code onactivate} event handler for this element.
3645      * @param onactivate the {@code onactivate} event handler for this element
3646      */
3647     @JsxSetter(IE)
3648     public void setOnactivate(final Object onactivate) {
3649         setEventHandler("activate", onactivate);
3650     }
3651 
3652     /**
3653      * Returns the {@code onbeforeactivate} event handler for this element.
3654      * @return the {@code onbeforeactivate} event handler for this element
3655      */
3656     @JsxGetter(IE)
3657     public Function getOnbeforeactivate() {
3658         return getEventHandler("beforeactivate");
3659     }
3660 
3661     /**
3662      * Sets the {@code onbeforeactivate} event handler for this element.
3663      * @param onbeforeactivate the {@code onbeforeactivate} event handler for this element
3664      */
3665     @JsxSetter(IE)
3666     public void setOnbeforeactivate(final Object onbeforeactivate) {
3667         setEventHandler("beforeactivate", onbeforeactivate);
3668     }
3669 
3670     /**
3671      * Returns the {@code onbeforecopy} event handler for this element.
3672      * @return the {@code onbeforecopy} event handler for this element
3673      */
3674     @Override
3675     @JsxGetter(IE)
3676     public Function getOnbeforecopy() {
3677         return getEventHandler("beforecopy");
3678     }
3679 
3680     /**
3681      * Sets the {@code onbeforecopy} event handler for this element.
3682      * @param onbeforecopy the {@code onbeforecopy} event handler for this element
3683      */
3684     @Override
3685     @JsxSetter(IE)
3686     public void setOnbeforecopy(final Object onbeforecopy) {
3687         setEventHandler("beforecopy", onbeforecopy);
3688     }
3689 
3690     /**
3691      * Returns the {@code onbeforecut} event handler for this element.
3692      * @return the {@code onbeforecut} event handler for this element
3693      */
3694     @Override
3695     @JsxGetter(IE)
3696     public Function getOnbeforecut() {
3697         return getEventHandler("beforecut");
3698     }
3699 
3700     /**
3701      * Sets the {@code onbeforecut} event handler for this element.
3702      * @param onbeforecut the {@code onbeforecut} event handler for this element
3703      */
3704     @Override
3705     @JsxSetter(IE)
3706     public void setOnbeforecut(final Object onbeforecut) {
3707         setEventHandler("beforecut", onbeforecut);
3708     }
3709 
3710     /**
3711      * Returns the {@code onbeforedeactivate} event handler for this element.
3712      * @return the {@code onbeforedeactivate} event handler for this element
3713      */
3714     @JsxGetter(IE)
3715     public Function getOnbeforedeactivate() {
3716         return getEventHandler("beforedeactivate");
3717     }
3718 
3719     /**
3720      * Sets the {@code onbeforedeactivate} event handler for this element.
3721      * @param onbeforedeactivate the {@code onbeforedeactivate} event handler for this element
3722      */
3723     @JsxSetter(IE)
3724     public void setOnbeforedeactivate(final Object onbeforedeactivate) {
3725         setEventHandler("beforedeactivate", onbeforedeactivate);
3726     }
3727 
3728     /**
3729      * Returns the {@code onbeforepaste} event handler for this element.
3730      * @return the {@code onbeforepaste} event handler for this element
3731      */
3732     @Override
3733     @JsxGetter(IE)
3734     public Function getOnbeforepaste() {
3735         return getEventHandler("beforepaste");
3736     }
3737 
3738     /**
3739      * Sets the {@code onbeforepaste} event handler for this element.
3740      * @param onbeforepaste the {@code onbeforepaste} event handler for this element
3741      */
3742     @Override
3743     @JsxSetter(IE)
3744     public void setOnbeforepaste(final Object onbeforepaste) {
3745         setEventHandler("beforepaste", onbeforepaste);
3746     }
3747 
3748     /**
3749      * Returns the {@code ondeactivate} event handler for this element.
3750      * @return the {@code ondeactivate} event handler for this element
3751      */
3752     @JsxGetter(IE)
3753     public Function getOndeactivate() {
3754         return getEventHandler("deactivate");
3755     }
3756 
3757     /**
3758      * Sets the {@code ondeactivate} event handler for this element.
3759      * @param ondeactivate the {@code ondeactivate} event handler for this element
3760      */
3761     @JsxSetter(IE)
3762     public void setOndeactivate(final Object ondeactivate) {
3763         setEventHandler("deactivate", ondeactivate);
3764     }
3765 
3766     /**
3767      * Returns the {@code onhelp} event handler for this element.
3768      * @return the {@code onhelp} event handler for this element
3769      */
3770     @JsxGetter(IE)
3771     public Function getOnhelp() {
3772         return getEventHandler("help");
3773     }
3774 
3775     /**
3776      * Sets the {@code onhelp} event handler for this element.
3777      * @param onhelp the {@code onhelp} event handler for this element
3778      */
3779     @JsxSetter(IE)
3780     public void setOnhelp(final Object onhelp) {
3781         setEventHandler("help", onhelp);
3782     }
3783 
3784     /**
3785      * Returns the {@code onmscontentzoom} event handler for this element.
3786      * @return the {@code onmscontentzoom} event handler for this element
3787      */
3788     @JsxGetter(IE)
3789     public Function getOnmscontentzoom() {
3790         return getEventHandler("mscontentzoom");
3791     }
3792 
3793     /**
3794      * Sets the {@code onmscontentzoom} event handler for this element.
3795      * @param onmscontentzoom the {@code onmscontentzoom} event handler for this element
3796      */
3797     @JsxSetter(IE)
3798     public void setOnmscontentzoom(final Object onmscontentzoom) {
3799         setEventHandler("mscontentzoom", onmscontentzoom);
3800     }
3801 
3802     /**
3803      * Returns the {@code onmsmanipulationstatechanged} event handler for this element.
3804      * @return the {@code onmsmanipulationstatechanged} event handler for this element
3805      */
3806     @JsxGetter(IE)
3807     public Function getOnmsmanipulationstatechanged() {
3808         return getEventHandler("msmanipulationstatechanged");
3809     }
3810 
3811     /**
3812      * Sets the {@code onmsmanipulationstatechanged} event handler for this element.
3813      * @param onmsmanipulationstatechanged the {@code onmsmanipulationstatechanged} event handler for this element
3814      */
3815     @JsxSetter(IE)
3816     public void setOnmsmanipulationstatechanged(final Object onmsmanipulationstatechanged) {
3817         setEventHandler("msmanipulationstatechanged", onmsmanipulationstatechanged);
3818     }
3819 
3820     /**
3821      * Returns the {@code onselectstart} event handler for this element.
3822      * @return the {@code onselectstart} event handler for this element
3823      */
3824     @Override
3825     @JsxGetter({IE, FF52})
3826     public Function getOnselectstart() {
3827         return getEventHandler("selectstart");
3828     }
3829 
3830     /**
3831      * Sets the {@code onselectstart} event handler for this element.
3832      * @param onselectstart the {@code onselectstart} event handler for this element
3833      */
3834     @Override
3835     @JsxSetter({IE, FF52})
3836     public void setOnselectstart(final Object onselectstart) {
3837         setEventHandler("selectstart", onselectstart);
3838     }
3839 
3840     /**
3841      * Returns the {@code onanimationend} event handler.
3842      * @return the {@code onanimationend} event handler
3843      */
3844     @JsxGetter(FF52)
3845     public Function getOnanimationend() {
3846         return getEventHandler("animationend");
3847     }
3848 
3849     /**
3850      * Sets the {@code onanimationend} event handler.
3851      * @param animationend the {@code onanimationend} event handler
3852      */
3853     @JsxSetter(FF52)
3854     public void setOnanimationend(final Object animationend) {
3855         setEventHandler("animationend", animationend);
3856     }
3857 
3858     /**
3859      * Returns the {@code onanimationiteration} event handler.
3860      * @return the {@code onanimationiteration} event handler
3861      */
3862     @JsxGetter(FF52)
3863     public Function getOnanimationiteration() {
3864         return getEventHandler("animationiteration");
3865     }
3866 
3867     /**
3868      * Sets the {@code onanimationiteration} event handler.
3869      * @param animationiteration the {@code onanimationiteration} event handler
3870      */
3871     @JsxSetter(FF52)
3872     public void setOnanimationiteration(final Object animationiteration) {
3873         setEventHandler("animationiteration", animationiteration);
3874     }
3875 
3876     /**
3877      * Returns the {@code onanimationstart} event handler.
3878      * @return the {@code onanimationstart} event handler
3879      */
3880     @JsxGetter(FF52)
3881     public Function getOnanimationstart() {
3882         return getEventHandler("animationstart");
3883     }
3884 
3885     /**
3886      * Sets the {@code onanimationstart} event handler.
3887      * @param animationstart the {@code onanimationstart} event handler
3888      */
3889     @JsxSetter(FF52)
3890     public void setOnanimationstart(final Object animationstart) {
3891         setEventHandler("animationstart", animationstart);
3892     }
3893 
3894     /**
3895      * Returns the {@code ondragexit} event handler.
3896      * @return the {@code ondragexit} event handler
3897      */
3898     @JsxGetter(FF52)
3899     public Function getOndragexit() {
3900         return getEventHandler("dragexit");
3901     }
3902 
3903     /**
3904      * Sets the {@code ondragexit} event handler.
3905      * @param dragexit the {@code ondragexit} event handler
3906      */
3907     @JsxSetter(FF52)
3908     public void setOndragexit(final Object dragexit) {
3909         setEventHandler("dragexit", dragexit);
3910     }
3911 
3912     /**
3913      * Returns the {@code onloadend} event handler.
3914      * @return the {@code onloadend} event handler
3915      */
3916     @JsxGetter(FF52)
3917     public Function getOnloadend() {
3918         return getEventHandler("loadend");
3919     }
3920 
3921     /**
3922      * Sets the {@code onloadend} event handler.
3923      * @param loadend the {@code onloadend} event handler
3924      */
3925     @JsxSetter(FF52)
3926     public void setOnloadend(final Object loadend) {
3927         setEventHandler("loadend", loadend);
3928     }
3929 
3930     /**
3931      * Returns the {@code ontransitionend} event handler.
3932      * @return the {@code ontransitionend} event handler
3933      */
3934     @JsxGetter(FF52)
3935     public Function getOntransitionend() {
3936         return getEventHandler("transitionend");
3937     }
3938 
3939     /**
3940      * Sets the {@code ontransitionend} event handler.
3941      * @param transitionend the {@code ontransitionend} event handler
3942      */
3943     @JsxSetter(FF52)
3944     public void setOntransitionend(final Object transitionend) {
3945         setEventHandler("transitionend", transitionend);
3946     }
3947 
3948     /**
3949      * Returns the {@code onwebkitanimationend} event handler.
3950      * @return the {@code onwebkitanimationend} event handler
3951      */
3952     @JsxGetter(FF52)
3953     public Function getOnwebkitanimationend() {
3954         return getEventHandler("webkitanimationend");
3955     }
3956 
3957     /**
3958      * Sets the {@code onwebkitanimationend} event handler.
3959      * @param webkitanimationend the {@code onwebkitanimationend} event handler
3960      */
3961     @JsxSetter(FF52)
3962     public void setOnwebkitanimationend(final Object webkitanimationend) {
3963         setEventHandler("webkitanimationend", webkitanimationend);
3964     }
3965 
3966     /**
3967      * Returns the {@code onwebkitanimationiteration} event handler.
3968      * @return the {@code onwebkitanimationiteration} event handler
3969      */
3970     @JsxGetter(FF52)
3971     public Function getOnwebkitanimationiteration() {
3972         return getEventHandler("webkitanimationiteration");
3973     }
3974 
3975     /**
3976      * Sets the {@code onwebkitanimationiteration} event handler.
3977      * @param webkitanimationiteration the {@code onwebkitanimationiteration} event handler
3978      */
3979     @JsxSetter(FF52)
3980     public void setOnwebkitanimationiteration(final Object webkitanimationiteration) {
3981         setEventHandler("webkitanimationiteration", webkitanimationiteration);
3982     }
3983 
3984     /**
3985      * Returns the {@code onwebkitanimationstart} event handler.
3986      * @return the {@code onwebkitanimationstart} event handler
3987      */
3988     @JsxGetter(FF52)
3989     public Function getOnwebkitanimationstart() {
3990         return getEventHandler("webkitanimationstart");
3991     }
3992 
3993     /**
3994      * Sets the {@code onwebkitanimationstart} event handler.
3995      * @param webkitanimationstart the {@code onwebkitanimationstart} event handler
3996      */
3997     @JsxSetter(FF52)
3998     public void setOnwebkitanimationstart(final Object webkitanimationstart) {
3999         setEventHandler("webkitanimationstart", webkitanimationstart);
4000     }
4001 
4002     /**
4003      * Returns the {@code onwebkittransitionend} event handler.
4004      * @return the {@code onwebkittransitionend} event handler
4005      */
4006     @JsxGetter(FF52)
4007     public Function getOnwebkittransitionend() {
4008         return getEventHandler("webkittransitionend");
4009     }
4010 
4011     /**
4012      * Sets the {@code onwebkittransitionend} event handler.
4013      * @param webkittransitionend the {@code onwebkittransitionend} event handler
4014      */
4015     @JsxSetter(FF52)
4016     public void setOnwebkittransitionend(final Object webkittransitionend) {
4017         setEventHandler("webkittransitionend", webkittransitionend);
4018     }
4019 
4020 }