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         getDomNodeOrDie().click();
1362     }
1363 
1364     /**
1365      * Returns the {@code spellcheck} property.
1366      * @return the {@code spellcheck} property
1367      */
1368     @JsxGetter(FF)
1369     public boolean isSpellcheck() {
1370         return Context.toBoolean(getDomNodeOrDie().getAttribute("spellcheck"));
1371     }
1372 
1373     /**
1374      * Sets the {@code spellcheck} property.
1375      * @param spellcheck the {@code spellcheck} property
1376      */
1377     @JsxSetter(FF)
1378     public void setSpellcheck(final boolean spellcheck) {
1379         getDomNodeOrDie().setAttribute("spellcheck", Boolean.toString(spellcheck));
1380     }
1381 
1382     /**
1383      * Returns the {@code lang} property.
1384      * @return the {@code lang} property
1385      */
1386     @JsxGetter
1387     public String getLang() {
1388         return getDomNodeOrDie().getAttribute("lang");
1389     }
1390 
1391     /**
1392      * Sets the {@code lang} property.
1393      * @param lang the {@code lang} property
1394      */
1395     @JsxSetter
1396     public void setLang(final String lang) {
1397         getDomNodeOrDie().setAttribute("lang", lang);
1398     }
1399 
1400     /**
1401      * Returns the {@code language} property.
1402      * @return the {@code language} property
1403      */
1404     @JsxGetter(IE)
1405     public String getLanguage() {
1406         return getDomNodeOrDie().getAttribute("language");
1407     }
1408 
1409     /**
1410      * Sets the {@code language} property.
1411      * @param language the {@code language} property
1412      */
1413     @JsxSetter(IE)
1414     public void setLanguage(final String language) {
1415         getDomNodeOrDie().setAttribute("language", language);
1416     }
1417 
1418     /**
1419      * Returns the {@code dir} property.
1420      * @return the {@code dir} property
1421      */
1422     @JsxGetter
1423     public String getDir() {
1424         return getDomNodeOrDie().getAttribute("dir");
1425     }
1426 
1427     /**
1428      * Sets the {@code dir} property.
1429      * @param dir the {@code dir} property
1430      */
1431     @JsxSetter
1432     public void setDir(final String dir) {
1433         getDomNodeOrDie().setAttribute("dir", dir);
1434     }
1435 
1436     /**
1437      * Returns the value of the tabIndex attribute.
1438      * @return the value of the tabIndex attribute
1439      */
1440     @JsxGetter
1441     public int getTabIndex() {
1442         return (int) Context.toNumber(getDomNodeOrDie().getAttribute("tabindex"));
1443     }
1444 
1445     /**
1446      * Sets the {@code tabIndex} property.
1447      * @param tabIndex the {@code tabIndex} property
1448      */
1449     @JsxSetter
1450     public void setTabIndex(final int tabIndex) {
1451         getDomNodeOrDie().setAttribute("tabindex", Integer.toString(tabIndex));
1452     }
1453 
1454     /**
1455      * Returns the {@code accessKey} property.
1456      * @return the {@code accessKey} property
1457      */
1458     @JsxGetter
1459     public String getAccessKey() {
1460         return getDomNodeOrDie().getAttribute("accesskey");
1461     }
1462 
1463     /**
1464      * Sets the {@code accessKey} property.
1465      * @param accessKey the {@code accessKey} property
1466      */
1467     @JsxSetter
1468     public void setAccessKey(final String accessKey) {
1469         getDomNodeOrDie().setAttribute("accesskey", accessKey);
1470     }
1471 
1472     /**
1473      * Returns the value of the specified attribute (width or height).
1474      * @return the value of the specified attribute (width or height)
1475      * @param attributeName the name of the attribute to return (<tt>"width"</tt> or <tt>"height"</tt>)
1476      * @param returnNegativeValues if {@code true}, negative values are returned;
1477      *        if {@code false}, this method returns an empty string in lieu of negative values;
1478      *        if {@code null}, this method returns <tt>0</tt> in lieu of negative values
1479      */
1480     protected String getWidthOrHeight(final String attributeName, final Boolean returnNegativeValues) {
1481         String value = getDomNodeOrDie().getAttribute(attributeName);
1482         if (getBrowserVersion().hasFeature(JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES)) {
1483             return value;
1484         }
1485         if (!PERCENT_VALUE.matcher(value).matches()) {
1486             try {
1487                 final Float f = Float.valueOf(value);
1488                 final int i = f.intValue();
1489                 if (i < 0) {
1490                     if (returnNegativeValues == null) {
1491                         value = "0";
1492                     }
1493                     else if (!returnNegativeValues.booleanValue()) {
1494                         value = "";
1495                     }
1496                     else {
1497                         value = Integer.toString(i);
1498                     }
1499                 }
1500                 else {
1501                     value = Integer.toString(i);
1502                 }
1503             }
1504             catch (final NumberFormatException e) {
1505                 if (!getBrowserVersion().hasFeature(JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES)) {
1506                     value = "";
1507                 }
1508             }
1509         }
1510         return value;
1511     }
1512 
1513     /**
1514      * Sets the value of the specified attribute (width or height).
1515      * @param attributeName the name of the attribute to set (<tt>"width"</tt> or <tt>"height"</tt>)
1516      * @param value the value of the specified attribute (width or height)
1517      * @param allowNegativeValues if {@code true}, negative values will be stored;
1518      *        if {@code false}, negative values cause an exception to be thrown;<br>
1519      *        this check/conversion is only done if the feature JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES
1520      *        is set for the simulated browser
1521      */
1522     protected void setWidthOrHeight(final String attributeName, String value, final boolean allowNegativeValues) {
1523         if (!getBrowserVersion().hasFeature(JS_WIDTH_HEIGHT_ACCEPTS_ARBITRARY_VALUES) && !value.isEmpty()) {
1524             if (value.endsWith("px")) {
1525                 value = value.substring(0, value.length() - 2);
1526             }
1527             boolean error = false;
1528             if (!PERCENT_VALUE.matcher(value).matches()) {
1529                 try {
1530                     final Float f = Float.valueOf(value);
1531                     final int i = f.intValue();
1532                     if (i < 0) {
1533                         if (!allowNegativeValues) {
1534                             error = true;
1535                         }
1536                     }
1537                 }
1538                 catch (final NumberFormatException e) {
1539                     error = true;
1540                 }
1541             }
1542             if (error) {
1543                 final Exception e = new Exception("Cannot set the '" + attributeName
1544                         + "' property to invalid value: '" + value + "'");
1545                 Context.throwAsScriptRuntimeEx(e);
1546             }
1547         }
1548         getDomNodeOrDie().setAttribute(attributeName, value);
1549     }
1550 
1551     /**
1552      * Sets the specified color attribute to the specified value.
1553      * @param name the color attribute's name
1554      * @param value the color attribute's value
1555      */
1556     protected void setColorAttribute(final String name, final String value) {
1557         String s = value;
1558         if (!s.isEmpty()) {
1559             final boolean restrict = getBrowserVersion().hasFeature(HTML_COLOR_RESTRICT);
1560 
1561             boolean isName = false;
1562             if (restrict) {
1563                 for (final String key : COLORS_MAP_IE.keySet()) {
1564                     if (key.equalsIgnoreCase(value)) {
1565                         isName = true;
1566                         break;
1567                     }
1568                 }
1569             }
1570             if (!isName) {
1571                 if (restrict) {
1572                     if (s.charAt(0) == '#') {
1573                         s = s.substring(1);
1574                     }
1575                     final StringBuilder builder = new StringBuilder(7);
1576                     for (int x = 0; x < 6 && x < s.length(); x++) {
1577                         final char ch = s.charAt(x);
1578                         if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
1579                             builder.append(ch);
1580                         }
1581                         else {
1582                             builder.append('0');
1583                         }
1584                     }
1585                     builder.insert(0, '#');
1586                     s = builder.toString();
1587                 }
1588             }
1589             if (getBrowserVersion().hasFeature(HTML_COLOR_TO_LOWER)) {
1590                 s = s.toLowerCase(Locale.ROOT);
1591             }
1592         }
1593         getDomNodeOrDie().setAttribute(name, s);
1594     }
1595 
1596     /**
1597      * Returns the value of the {@code align} property.
1598      * @param returnInvalidValues if {@code true}, this method will return any value, including technically
1599      *        invalid values; if {@code false}, this method will return an empty string instead of invalid values
1600      * @return the value of the {@code align} property
1601      */
1602     protected String getAlign(final boolean returnInvalidValues) {
1603         final boolean acceptArbitraryValues = getBrowserVersion().hasFeature(JS_ALIGN_ACCEPTS_ARBITRARY_VALUES);
1604 
1605         final String align = getDomNodeOrDie().getAttribute("align");
1606         if (returnInvalidValues || acceptArbitraryValues
1607             || "center".equals(align)
1608             || "justify".equals(align)
1609             || "left".equals(align)
1610             || "right".equals(align)) {
1611             return align;
1612         }
1613         return "";
1614     }
1615 
1616     /**
1617      * Sets the value of the {@code align} property.
1618      * @param align the value of the {@code align} property
1619      * @param ignoreIfNoError if {@code true}, the invocation will be a no-op if it does not trigger an error
1620      *        (i.e., it will not actually set the align attribute)
1621      */
1622     protected void setAlign(final String align, final boolean ignoreIfNoError) {
1623         final String alignLC = align.toLowerCase(Locale.ROOT);
1624         final boolean acceptArbitraryValues = getBrowserVersion().hasFeature(JS_ALIGN_ACCEPTS_ARBITRARY_VALUES);
1625         if (acceptArbitraryValues
1626                 || "center".equals(alignLC)
1627                 || "justify".equals(alignLC)
1628                 || "left".equals(alignLC)
1629                 || "right".equals(alignLC)
1630                 || "bottom".equals(alignLC)
1631                 || "middle".equals(alignLC)
1632                 || "top".equals(alignLC)) {
1633             if (!ignoreIfNoError) {
1634                 final String newValue = acceptArbitraryValues ? align : alignLC;
1635                 getDomNodeOrDie().setAttribute("align", newValue);
1636             }
1637             return;
1638         }
1639 
1640         throw Context.reportRuntimeError("Cannot set the align property to invalid value: '" + align + "'");
1641     }
1642 
1643     /**
1644      * Returns the value of the {@code vAlign} property.
1645      * @param valid the valid values; if {@code null}, any value is valid
1646      * @param defaultValue the default value to use, if necessary
1647      * @return the value of the {@code vAlign} property
1648      */
1649     protected String getVAlign(final String[] valid, final String defaultValue) {
1650         final String valign = getDomNodeOrDie().getAttribute("valign");
1651         if (valid == null || ArrayUtils.contains(valid, valign)) {
1652             return valign;
1653         }
1654         return defaultValue;
1655     }
1656 
1657     /**
1658      * Sets the value of the {@code vAlign} property.
1659      * @param vAlign the value of the {@code vAlign} property
1660      * @param valid the valid values; if {@code null}, any value is valid
1661      */
1662     protected void setVAlign(final Object vAlign, final String[] valid) {
1663         final String s = Context.toString(vAlign).toLowerCase(Locale.ROOT);
1664         if (valid == null || ArrayUtils.contains(valid, s)) {
1665             getDomNodeOrDie().setAttribute("valign", s);
1666         }
1667         else {
1668             throw Context.reportRuntimeError("Cannot set the vAlign property to invalid value: " + vAlign);
1669         }
1670     }
1671 
1672     /**
1673      * Returns the value of the {@code ch} property.
1674      * @return the value of the {@code ch} property
1675      */
1676     protected String getCh() {
1677         return getDomNodeOrDie().getAttribute("char");
1678     }
1679 
1680     /**
1681      * Sets the value of the {@code ch} property.
1682      * @param ch the value of the {@code ch} property
1683      */
1684     protected void setCh(final String ch) {
1685         getDomNodeOrDie().setAttribute("char", ch);
1686     }
1687 
1688     /**
1689      * Returns the value of the {@code chOff} property.
1690      * @return the value of the {@code chOff} property
1691      */
1692     protected String getChOff() {
1693         return getDomNodeOrDie().getAttribute("charOff");
1694     }
1695 
1696     /**
1697      * Sets the value of the {@code chOff} property.
1698      * @param chOff the value of the {@code chOff} property
1699      */
1700     protected void setChOff(String chOff) {
1701         try {
1702             final float f = Float.parseFloat(chOff);
1703             final int i = (int) f;
1704             if (i == f) {
1705                 chOff = Integer.toString(i);
1706             }
1707             else {
1708                 chOff = Float.toString(f);
1709             }
1710         }
1711         catch (final NumberFormatException e) {
1712             // Ignore.
1713         }
1714         getDomNodeOrDie().setAttribute("charOff", chOff);
1715     }
1716 
1717     /**
1718      * Returns this element's <tt>offsetLeft</tt>, which is the calculated left position of this
1719      * element relative to the <tt>offsetParent</tt>.
1720      *
1721      * @return this element's <tt>offsetLeft</tt>
1722      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534200.aspx">MSDN Documentation</a>
1723      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1724      * @see <a href="http://dump.testsuite.org/2006/dom/style/offset/spec">Reverse Engineering by Anne van Kesteren</a>
1725      */
1726     @JsxGetter
1727     public int getOffsetLeft() {
1728         if (this instanceof HTMLBodyElement) {
1729             return 0;
1730         }
1731 
1732         int left = 0;
1733         final HTMLElement offsetParent = getOffsetParent();
1734 
1735         // Add the offset for this node.
1736         DomNode node = getDomNodeOrDie();
1737         HTMLElement element = (HTMLElement) node.getScriptableObject();
1738         ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1739         left += style.getLeft(true, false, false);
1740 
1741         // If this node is absolutely positioned, we're done.
1742         final String position = style.getPositionWithInheritance();
1743         if ("absolute".equals(position)) {
1744             return left;
1745         }
1746 
1747         // Add the offset for the ancestor nodes.
1748         node = node.getParentNode();
1749         while (node != null && node.getScriptableObject() != offsetParent) {
1750             if (node.getScriptableObject() instanceof HTMLElement) {
1751                 element = (HTMLElement) node.getScriptableObject();
1752                 style = element.getWindow().getComputedStyle(element, null);
1753                 left += style.getLeft(true, true, true);
1754             }
1755             node = node.getParentNode();
1756         }
1757 
1758         if (offsetParent != null) {
1759             style = offsetParent.getWindow().getComputedStyle(offsetParent, null);
1760             left += style.getMarginLeftValue();
1761             left += style.getPaddingLeftValue();
1762         }
1763 
1764         return left;
1765     }
1766 
1767     /**
1768      * Returns this element's X position.
1769      * @return this element's X position
1770      */
1771     public int getPosX() {
1772         int cumulativeOffset = 0;
1773         HTMLElement element = this;
1774         while (element != null) {
1775             cumulativeOffset += element.getOffsetLeft();
1776             if (element != this) {
1777                 final ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1778                 cumulativeOffset += style.getBorderLeftValue();
1779             }
1780             element = element.getOffsetParent();
1781         }
1782         return cumulativeOffset;
1783     }
1784 
1785     /**
1786      * Returns this element's Y position.
1787      * @return this element's Y position
1788      */
1789     public int getPosY() {
1790         int cumulativeOffset = 0;
1791         HTMLElement element = this;
1792         while (element != null) {
1793             cumulativeOffset += element.getOffsetTop();
1794             if (element != this) {
1795                 final ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1796                 cumulativeOffset += style.getBorderTopValue();
1797             }
1798             element = element.getOffsetParent();
1799         }
1800         return cumulativeOffset;
1801     }
1802 
1803     /**
1804      * Gets the offset parent or {@code null} if this is not an {@link HTMLElement}.
1805      * @return the offset parent or {@code null}
1806      */
1807     private HTMLElement getOffsetParent() {
1808         final Object offsetParent = getOffsetParentInternal(false);
1809         if (offsetParent instanceof HTMLElement) {
1810             return (HTMLElement) offsetParent;
1811         }
1812         return null;
1813     }
1814 
1815     /**
1816      * Returns this element's {@code offsetTop}, which is the calculated top position of this
1817      * element relative to the {@code offsetParent}.
1818      *
1819      * @return this element's {@code offsetTop}
1820      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534303.aspx">MSDN Documentation</a>
1821      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1822      * @see <a href="http://dump.testsuite.org/2006/dom/style/offset/spec">Reverse Engineering by Anne van Kesteren</a>
1823      */
1824     @JsxGetter
1825     public int getOffsetTop() {
1826         if (this instanceof HTMLBodyElement) {
1827             return 0;
1828         }
1829 
1830         int top = 0;
1831         final HTMLElement offsetParent = getOffsetParent();
1832 
1833         // Add the offset for this node.
1834         DomNode node = getDomNodeOrDie();
1835         HTMLElement element = (HTMLElement) node.getScriptableObject();
1836         ComputedCSSStyleDeclaration style = element.getWindow().getComputedStyle(element, null);
1837         top += style.getTop(true, false, false);
1838 
1839         // If this node is absolutely positioned, we're done.
1840         final String position = style.getPositionWithInheritance();
1841         if ("absolute".equals(position)) {
1842             return top;
1843         }
1844 
1845         // Add the offset for the ancestor nodes.
1846         node = node.getParentNode();
1847         while (node != null && node.getScriptableObject() != offsetParent) {
1848             if (node.getScriptableObject() instanceof HTMLElement) {
1849                 element = (HTMLElement) node.getScriptableObject();
1850                 style = element.getWindow().getComputedStyle(element, null);
1851                 top += style.getTop(false, true, true);
1852             }
1853             node = node.getParentNode();
1854         }
1855 
1856         if (offsetParent != null) {
1857             final HTMLElement thiz = (HTMLElement) getDomNodeOrDie().getScriptableObject();
1858             style = thiz.getWindow().getComputedStyle(thiz, null);
1859             final boolean thisElementHasTopMargin = style.getMarginTopValue() != 0;
1860 
1861             style = offsetParent.getWindow().getComputedStyle(offsetParent, null);
1862             if (!thisElementHasTopMargin) {
1863                 top += style.getMarginTopValue();
1864             }
1865             top += style.getPaddingTopValue();
1866         }
1867 
1868         return top;
1869     }
1870 
1871     /**
1872      * Returns this element's <tt>offsetParent</tt>. The <tt>offsetLeft</tt> and
1873      * <tt>offsetTop</tt> attributes are relative to the <tt>offsetParent</tt>.
1874      *
1875      * @return this element's <tt>offsetParent</tt>. This may be <code>undefined</code> when this node is
1876      * not attached or {@code null} for <code>body</code>.
1877      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms534302.aspx">MSDN Documentation</a>
1878      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_el_ref20.html">Gecko DOM Reference</a>
1879      * @see <a href="http://www.quirksmode.org/js/elementdimensions.html">Element Dimensions</a>
1880      * @see <a href="http://www.w3.org/TR/REC-CSS2/box.html">Box Model</a>
1881      * @see <a href="http://dump.testsuite.org/2006/dom/style/offset/spec">Reverse Engineering by Anne van Kesteren</a>
1882      */
1883     @JsxGetter(propertyName = "offsetParent")
1884     public Object getOffsetParent_js() {
1885         return getOffsetParentInternal(getBrowserVersion().hasFeature(JS_OFFSET_PARENT_NULL_IF_FIXED));
1886     }
1887 
1888     private Object getOffsetParentInternal(final boolean returnNullIfFixed) {
1889         DomNode currentElement = getDomNodeOrDie();
1890 
1891         if (currentElement.getParentNode() == null) {
1892             return null;
1893         }
1894 
1895         Object offsetParent = null;
1896         final HTMLElement htmlElement = (HTMLElement) currentElement.getScriptableObject();
1897         if (returnNullIfFixed && "fixed".equals(htmlElement.getStyle().getStyleAttribute(
1898                 StyleAttributes.Definition.POSITION, true))) {
1899             return null;
1900         }
1901 
1902         final ComputedCSSStyleDeclaration style = htmlElement.getWindow().getComputedStyle(htmlElement, null);
1903         final String position = style.getPositionWithInheritance();
1904         final boolean staticPos = "static".equals(position);
1905 
1906         final boolean useTables = staticPos;
1907 
1908         while (currentElement != null) {
1909 
1910             final DomNode parentNode = currentElement.getParentNode();
1911             if (parentNode instanceof HtmlBody
1912                 || (useTables && parentNode instanceof HtmlTableDataCell)
1913                 || (useTables && parentNode instanceof HtmlTable)) {
1914                 offsetParent = parentNode.getScriptableObject();
1915                 break;
1916             }
1917 
1918             if (parentNode != null && parentNode.getScriptableObject() instanceof HTMLElement) {
1919                 final HTMLElement parentElement = (HTMLElement) parentNode.getScriptableObject();
1920                 final ComputedCSSStyleDeclaration parentStyle =
1921                             parentElement.getWindow().getComputedStyle(parentElement, null);
1922                 final String parentPosition = parentStyle.getPositionWithInheritance();
1923                 final boolean parentIsStatic = "static".equals(parentPosition);
1924                 if (!parentIsStatic) {
1925                     offsetParent = parentNode.getScriptableObject();
1926                     break;
1927                 }
1928             }
1929 
1930             currentElement = currentElement.getParentNode();
1931         }
1932 
1933         return offsetParent;
1934     }
1935 
1936     /**
1937      * {@inheritDoc}
1938      */
1939     @Override
1940     public ClientRect getBoundingClientRect() {
1941         final ClientRect textRectangle = super.getBoundingClientRect();
1942 
1943         int left = getPosX();
1944         int top = getPosY();
1945 
1946         // account for any scrolled ancestors
1947         Object parentNode = getOffsetParentInternal(false);
1948         while (parentNode != null
1949                 && (parentNode instanceof HTMLElement)
1950                 && !(parentNode instanceof HTMLBodyElement)) {
1951             final HTMLElement elem = (HTMLElement) parentNode;
1952             left -= elem.getScrollLeft();
1953             top -= elem.getScrollTop();
1954 
1955             parentNode = elem.getParentNode();
1956         }
1957 
1958         textRectangle.setBottom(top + getOffsetHeight());
1959         textRectangle.setLeft(left);
1960         textRectangle.setRight(left + getOffsetWidth());
1961         textRectangle.setTop(top);
1962 
1963         return textRectangle;
1964     }
1965 
1966     /**
1967      * Gets the token list of class attribute.
1968      * @return the token list of class attribute
1969      */
1970     @Override
1971     @JsxGetter
1972     public DOMTokenList getClassList() {
1973         return new DOMTokenList(this, "class");
1974     }
1975 
1976     /**
1977      * {@inheritDoc} Overridden to modify browser configurations.
1978      */
1979     @Override
1980     @JsxFunction
1981     public boolean hasAttribute(final String name) {
1982         return super.hasAttribute(name);
1983     }
1984 
1985     /**
1986      * {@inheritDoc} Overridden to modify browser configurations.
1987      */
1988     @Override
1989     @JsxGetter(IE)
1990     public HTMLCollection getChildren() {
1991         return super.getChildren();
1992     }
1993 
1994     /**
1995      * {@inheritDoc} Overridden to modify browser configurations.
1996      */
1997     @Override
1998     @JsxGetter
1999     public Element getParentElement() {
2000         return super.getParentElement();
2001     }
2002 
2003     /**
2004      * Returns the {@code dataset} attribute.
2005      * @return the {@code dataset} attribute
2006      */
2007     @JsxGetter({CHROME, FF,
2008         IE})
2009     public DOMStringMap getDataset() {
2010         return new DOMStringMap(this);
2011     }
2012 
2013     /**
2014      * {@inheritDoc}
2015      */
2016     @Override
2017     protected boolean isEndTagForbidden() {
2018         return endTagForbidden_;
2019     }
2020 
2021     /**
2022      * Returns whether the tag is lower case in .outerHTML/.innerHTML.
2023      * It seems to be a feature for HTML5 elements for IE.
2024      * @return whether the tag is lower case in .outerHTML/.innerHTML
2025      */
2026     protected boolean isLowerCaseInOuterHtml() {
2027         return false;
2028     }
2029 
2030     /**
2031      * Sets the {@code onchange} event handler for this element.
2032      * @param onchange the {@code onchange} event handler for this element
2033      */
2034     @JsxSetter
2035     public void setOnchange(final Object onchange) {
2036         setEventHandler(Event.TYPE_CHANGE, onchange);
2037     }
2038 
2039     /**
2040      * Returns the {@code onchange} event handler for this element.
2041      * @return the {@code onchange} event handler for this element
2042      */
2043     @JsxGetter
2044     public Function getOnchange() {
2045         return getEventHandler(Event.TYPE_CHANGE);
2046     }
2047 
2048     /**
2049      * Returns the {@code onsubmit} event handler for this element.
2050      * @return the {@code onsubmit} event handler for this element
2051      */
2052     @JsxGetter
2053     public Object getOnsubmit() {
2054         return getEventHandler(Event.TYPE_SUBMIT);
2055     }
2056 
2057     /**
2058      * Sets the {@code onsubmit} event handler for this element.
2059      * @param onsubmit the {@code onsubmit} event handler for this element
2060      */
2061     @JsxSetter
2062     public void setOnsubmit(final Object onsubmit) {
2063         setEventHandler(Event.TYPE_SUBMIT, onsubmit);
2064     }
2065 
2066     /**
2067      * Mock for the moment.
2068      * @param retargetToElement if true, all events are targeted directly to this element;
2069      * if false, events can also fire at descendants of this element
2070      */
2071     @JsxFunction({FF, IE})
2072     public void setCapture(final boolean retargetToElement) {
2073         // empty
2074     }
2075 
2076     /**
2077      * Mock for the moment.
2078      * @return true for success
2079      */
2080     @JsxFunction({FF, IE})
2081     public boolean releaseCapture() {
2082         return true;
2083     }
2084 
2085     /**
2086      * Returns the {@code contentEditable} property.
2087      * @return the {@code contentEditable} property
2088      */
2089     @JsxGetter
2090     public String getContentEditable() {
2091         final String attribute = getDomNodeOrDie().getAttribute("contentEditable");
2092         if (attribute == DomElement.ATTRIBUTE_NOT_DEFINED) {
2093             return "inherit";
2094         }
2095         if (attribute == DomElement.ATTRIBUTE_VALUE_EMPTY) {
2096             return "true";
2097         }
2098         return attribute;
2099     }
2100 
2101     /**
2102      * Sets the {@code contentEditable} property.
2103      * @param contentEditable the {@code contentEditable} property to set
2104      */
2105     @JsxSetter
2106     public void setContentEditable(final String contentEditable) {
2107         getDomNodeOrDie().setAttribute("contentEditable", contentEditable);
2108     }
2109 
2110     /**
2111      * Returns the {@code isContentEditable} property.
2112      * @return the {@code isContentEditable} property
2113      */
2114     @JsxGetter
2115     public boolean isIsContentEditable() {
2116         final String attribute = getContentEditable();
2117         if ("true".equals(attribute)) {
2118             return true;
2119         }
2120         else if ("inherit".equals(attribute)) {
2121             final DomNode parent = getDomNodeOrDie().getParentNode();
2122             if (parent != null) {
2123                 final Object parentScriptable = parent.getScriptableObject();
2124                 if (parentScriptable instanceof HTMLElement) {
2125                     return ((HTMLElement) parentScriptable).isIsContentEditable();
2126                 }
2127             }
2128         }
2129         return false;
2130     }
2131 
2132     /**
2133      * {@inheritDoc}
2134      */
2135     @Override
2136     @JsxGetter
2137     public CSSStyleDeclaration getStyle() {
2138         return super.getStyle();
2139     }
2140 
2141     /**
2142      * {@inheritDoc}
2143      */
2144     @Override
2145     @JsxSetter
2146     public void setStyle(final String style) {
2147         super.setStyle(style);
2148     }
2149 
2150     /**
2151      * Returns the runtime style object for this element.
2152      * @return the runtime style object for this element
2153      */
2154     @JsxGetter(IE)
2155     public CSSStyleDeclaration getRuntimeStyle() {
2156         return super.getStyle();
2157     }
2158 
2159     /**
2160      * Returns the current (calculated) style object for this element.
2161      * @return the current (calculated) style object for this element
2162      */
2163     @JsxGetter(IE)
2164     public ComputedCSSStyleDeclaration getCurrentStyle() {
2165         if (!getDomNodeOrDie().isAttachedToPage()) {
2166             return null;
2167         }
2168         return getWindow().getComputedStyle(this, null);
2169     }
2170 
2171     /**
2172      * Sets the {@code onclick} event handler for this element.
2173      * @param handler the {@code onclick} event handler for this element
2174      */
2175     @JsxSetter
2176     public void setOnclick(final Object handler) {
2177         setEventHandler(MouseEvent.TYPE_CLICK, handler);
2178     }
2179 
2180     /**
2181      * Returns the {@code onclick} event handler for this element.
2182      * @return the {@code onclick} event handler for this element
2183      */
2184     @JsxGetter
2185     public Object getOnclick() {
2186         return getEventHandler(MouseEvent.TYPE_CLICK);
2187     }
2188 
2189     /**
2190      * Sets the {@code ondblclick} event handler for this element.
2191      * @param handler the {@code ondblclick} event handler for this element
2192      */
2193     @JsxSetter
2194     public void setOndblclick(final Object handler) {
2195         setEventHandler(MouseEvent.TYPE_DBL_CLICK, handler);
2196     }
2197 
2198     /**
2199      * Returns the {@code ondblclick} event handler for this element.
2200      * @return the {@code ondblclick} event handler for this element
2201      */
2202     @JsxGetter
2203     public Object getOndblclick() {
2204         return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
2205     }
2206 
2207     /**
2208      * Sets the {@code onblur} event handler for this element.
2209      * @param handler the {@code onblur} event handler for this element
2210      */
2211     @JsxSetter
2212     public void setOnblur(final Object handler) {
2213         setEventHandler(Event.TYPE_BLUR, handler);
2214     }
2215 
2216     /**
2217      * Returns the {@code onblur} event handler for this element.
2218      * @return the {@code onblur} event handler for this element
2219      */
2220     @JsxGetter
2221     public Object getOnblur() {
2222         return getEventHandler(Event.TYPE_BLUR);
2223     }
2224 
2225     /**
2226      * Sets the {@code onfocus} event handler for this element.
2227      * @param handler the {@code onfocus} event handler for this element
2228      */
2229     @JsxSetter
2230     public void setOnfocus(final Object handler) {
2231         setEventHandler(Event.TYPE_FOCUS, handler);
2232     }
2233 
2234     /**
2235      * Returns the {@code onfocus} event handler for this element.
2236      * @return the {@code onfocus} event handler for this element
2237      */
2238     @JsxGetter
2239     public Object getOnfocus() {
2240         return getEventHandler(Event.TYPE_FOCUS);
2241     }
2242 
2243     /**
2244      * Sets the {@code onfocusin} event handler for this element.
2245      * @param handler the {@code onfocusin} event handler for this element
2246      */
2247     @JsxSetter(IE)
2248     public void setOnfocusin(final Object handler) {
2249         setEventHandler(Event.TYPE_FOCUS_IN, handler);
2250     }
2251 
2252     /**
2253      * Returns the {@code onfocusin} event handler for this element.
2254      * @return the {@code onfocusin} event handler for this element
2255      */
2256     @JsxGetter(IE)
2257     public Object getOnfocusin() {
2258         return getEventHandler(Event.TYPE_FOCUS_IN);
2259     }
2260 
2261     /**
2262      * Sets the {@code onfocusout} event handler for this element.
2263      * @param handler the {@code onfocusout} event handler for this element
2264      */
2265     @JsxSetter(IE)
2266     public void setOnfocusout(final Object handler) {
2267         setEventHandler(Event.TYPE_FOCUS_OUT, handler);
2268     }
2269 
2270     /**
2271      * Returns the {@code onfocusout} event handler for this element.
2272      * @return the {@code onfocusout} event handler for this element
2273      */
2274     @JsxGetter(IE)
2275     public Object getOnfocusout() {
2276         return getEventHandler(Event.TYPE_FOCUS_OUT);
2277     }
2278 
2279     /**
2280      * Sets the {@code onkeydown} event handler for this element.
2281      * @param handler the {@code onkeydown} event handler for this element
2282      */
2283     @JsxSetter
2284     public void setOnkeydown(final Object handler) {
2285         setEventHandler(Event.TYPE_KEY_DOWN, handler);
2286     }
2287 
2288     /**
2289      * Returns the {@code onkeydown} event handler for this element.
2290      * @return the {@code onkeydown} event handler for this element
2291      */
2292     @JsxGetter
2293     public Object getOnkeydown() {
2294         return getEventHandler(Event.TYPE_KEY_DOWN);
2295     }
2296 
2297     /**
2298      * Sets the {@code onkeypress} event handler for this element.
2299      * @param handler the {@code onkeypress} event handler for this element
2300      */
2301     @JsxSetter
2302     public void setOnkeypress(final Object handler) {
2303         setEventHandler(Event.TYPE_KEY_PRESS, handler);
2304     }
2305 
2306     /**
2307      * Returns the {@code onkeypress} event handler for this element.
2308      * @return the {@code onkeypress} event handler for this element
2309      */
2310     @JsxGetter
2311     public Object getOnkeypress() {
2312         return getEventHandler(Event.TYPE_KEY_PRESS);
2313     }
2314 
2315     /**
2316      * Sets the {@code onkeyup} event handler for this element.
2317      * @param handler the {@code onkeyup} event handler for this element
2318      */
2319     @JsxSetter
2320     public void setOnkeyup(final Object handler) {
2321         setEventHandler(Event.TYPE_KEY_UP, handler);
2322     }
2323 
2324     /**
2325      * Returns the {@code onkeyup} event handler for this element.
2326      * @return the {@code onkeyup} event handler for this element
2327      */
2328     @JsxGetter
2329     public Object getOnkeyup() {
2330         return getEventHandler(Event.TYPE_KEY_UP);
2331     }
2332 
2333     /**
2334      * Sets the {@code onmousedown} event handler for this element.
2335      * @param handler the {@code onmousedown} event handler for this element
2336      */
2337     @JsxSetter
2338     public void setOnmousedown(final Object handler) {
2339         setEventHandler(MouseEvent.TYPE_MOUSE_DOWN, handler);
2340     }
2341 
2342     /**
2343      * Returns the {@code onmousedown} event handler for this element.
2344      * @return the {@code onmousedown} event handler for this element
2345      */
2346     @JsxGetter
2347     public Object getOnmousedown() {
2348         return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
2349     }
2350 
2351     /**
2352      * Sets the {@code onmousemove} event handler for this element.
2353      * @param handler the {@code onmousemove} event handler for this element
2354      */
2355     @JsxSetter
2356     public void setOnmousemove(final Object handler) {
2357         setEventHandler(MouseEvent.TYPE_MOUSE_MOVE, handler);
2358     }
2359 
2360     /**
2361      * Returns the {@code onmousemove} event handler for this element.
2362      * @return the {@code onmousemove} event handler for this element
2363      */
2364     @JsxGetter
2365     public Object getOnmousemove() {
2366         return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
2367     }
2368 
2369     /**
2370      * Sets the {@code onmouseout} event handler for this element.
2371      * @param handler the {@code onmouseout} event handler for this element
2372      */
2373     @JsxSetter
2374     public void setOnmouseout(final Object handler) {
2375         setEventHandler(MouseEvent.TYPE_MOUSE_OUT, handler);
2376     }
2377 
2378     /**
2379      * Returns the {@code onmouseout} event handler for this element.
2380      * @return the {@code onmouseout} event handler for this element
2381      */
2382     @JsxGetter
2383     public Object getOnmouseout() {
2384         return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
2385     }
2386 
2387     /**
2388      * Sets the {@code onmouseover} event handler for this element.
2389      * @param handler the {@code onmouseover} event handler for this element
2390      */
2391     @JsxSetter
2392     public void setOnmouseover(final Object handler) {
2393         setEventHandler(MouseEvent.TYPE_MOUSE_OVER, handler);
2394     }
2395 
2396     /**
2397      * Returns the {@code onmouseover} event handler for this element.
2398      * @return the {@code onmouseover} event handler for this element
2399      */
2400     @JsxGetter
2401     public Object getOnmouseover() {
2402         return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
2403     }
2404 
2405     /**
2406      * Sets the {@code onmouseup} event handler for this element.
2407      * @param handler the {@code onmouseup} event handler for this element
2408      */
2409     @JsxSetter
2410     public void setOnmouseup(final Object handler) {
2411         setEventHandler(MouseEvent.TYPE_MOUSE_UP, handler);
2412     }
2413 
2414     /**
2415      * Returns the {@code onmouseup} event handler for this element.
2416      * @return the {@code onmouseup} event handler for this element
2417      */
2418     @JsxGetter
2419     public Object getOnmouseup() {
2420         return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
2421     }
2422 
2423     /**
2424      * Sets the {@code oncontextmenu} event handler for this element.
2425      * @param handler the {@code oncontextmenu} event handler for this element
2426      */
2427     @JsxSetter
2428     public void setOncontextmenu(final Object handler) {
2429         setEventHandler(MouseEvent.TYPE_CONTEXT_MENU, handler);
2430     }
2431 
2432     /**
2433      * Returns the {@code oncontextmenu} event handler for this element.
2434      * @return the {@code oncontextmenu} event handler for this element
2435      */
2436     @JsxGetter
2437     public Object getOncontextmenu() {
2438         return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
2439     }
2440 
2441     /**
2442      * Sets the {@code onresize} event handler for this element.
2443      * @param handler the {@code onresize} event handler for this element
2444      */
2445     @JsxSetter({CHROME, FF})
2446     public void setOnresize(final Object handler) {
2447         setEventHandler("resize", handler);
2448     }
2449 
2450     /**
2451      * Returns the {@code onresize} event handler for this element.
2452      * @return the {@code onresize} event handler for this element
2453      */
2454     @JsxGetter({CHROME, FF})
2455     public Function getOnresize() {
2456         return getEventHandler("resize");
2457     }
2458 
2459     /**
2460      * Sets the {@code onerror} event handler for this element.
2461      * @param handler the {@code onerror} event handler for this element
2462      */
2463     @JsxSetter
2464     public void setOnerror(final Object handler) {
2465         setEventHandler(Event.TYPE_ERROR, handler);
2466     }
2467 
2468     /**
2469      * Returns the {@code onerror} event handler for this element.
2470      * @return the {@code onerror} event handler for this element
2471      */
2472     @JsxGetter
2473     public Object getOnerror() {
2474         return getEventHandler(Event.TYPE_ERROR);
2475     }
2476 
2477     /**
2478      * Returns the {@code oninput} event handler for this element.
2479      * @return the {@code oninput} event handler for this element
2480      */
2481     @JsxGetter
2482     public Function getOninput() {
2483         return getEventHandler(Event.TYPE_INPUT);
2484     }
2485 
2486     /**
2487      * Sets the {@code oninput} event handler for this element.
2488      * @param oninput the {@code oninput} event handler for this element
2489      */
2490     @JsxSetter
2491     public void setOninput(final Object oninput) {
2492         setEventHandler(Event.TYPE_INPUT, oninput);
2493     }
2494 
2495     /**
2496      * {@inheritDoc}
2497      */
2498     @Override
2499     @JsxFunction(IE)
2500     public boolean contains(final Object element) {
2501         return super.contains(element);
2502     }
2503 
2504     /**
2505      * Returns the {@code hidden} property.
2506      * @return the {@code hidden} property
2507      */
2508     @JsxGetter
2509     public boolean isHidden() {
2510         return getDomNodeOrDie().hasAttribute("hidden");
2511     }
2512 
2513     /**
2514      * Sets the {@code hidden} property.
2515      * @param hidden the {@code hidden} value
2516      */
2517     @JsxSetter
2518     public void setHidden(final boolean hidden) {
2519         if (hidden) {
2520             getDomNodeOrDie().setAttribute("hidden", "hidden");
2521         }
2522         else {
2523             getDomNodeOrDie().removeAttribute("hidden");
2524         }
2525     }
2526 
2527     /**
2528      * {@inheritDoc}
2529      */
2530     @Override
2531     @JsxGetter(IE)
2532     public String getId() {
2533         return super.getId();
2534     }
2535 
2536     /**
2537      * {@inheritDoc}
2538      */
2539     @Override
2540     @JsxSetter(IE)
2541     public void setId(final String newId) {
2542         super.setId(newId);
2543     }
2544 
2545     /**
2546      * Returns the {@code onabort} event handler for this element.
2547      * @return the {@code onabort} event handler for this element
2548      */
2549     @JsxGetter
2550     public Function getOnabort() {
2551         return getEventHandler("abort");
2552     }
2553 
2554     /**
2555      * Sets the {@code onabort} event handler for this element.
2556      * @param onabort the {@code onabort} event handler for this element
2557      */
2558     @JsxSetter
2559     public void setOnabort(final Object onabort) {
2560         setEventHandler("abort", onabort);
2561     }
2562 
2563     /**
2564      * Returns the {@code onauxclick} event handler for this element.
2565      * @return the {@code onauxclick} event handler for this element
2566      */
2567     @JsxGetter(CHROME)
2568     public Function getOnauxclick() {
2569         return getEventHandler("auxclick");
2570     }
2571 
2572     /**
2573      * Sets the {@code onauxclick} event handler for this element.
2574      * @param onauxclick the {@code onauxclick} event handler for this element
2575      */
2576     @JsxSetter(CHROME)
2577     public void setOnauxclick(final Object onauxclick) {
2578         setEventHandler("auxclick", onauxclick);
2579     }
2580 
2581     /**
2582      * Returns the {@code oncancel} event handler for this element.
2583      * @return the {@code oncancel} event handler for this element
2584      */
2585     @JsxGetter(CHROME)
2586     public Function getOncancel() {
2587         return getEventHandler("cancel");
2588     }
2589 
2590     /**
2591      * Sets the {@code oncancel} event handler for this element.
2592      * @param oncancel the {@code oncancel} event handler for this element
2593      */
2594     @JsxSetter(CHROME)
2595     public void setOncancel(final Object oncancel) {
2596         setEventHandler("cancel", oncancel);
2597     }
2598 
2599     /**
2600      * Returns the {@code oncanplay} event handler for this element.
2601      * @return the {@code oncanplay} event handler for this element
2602      */
2603     @JsxGetter
2604     public Function getOncanplay() {
2605         return getEventHandler("canplay");
2606     }
2607 
2608     /**
2609      * Sets the {@code oncanplay} event handler for this element.
2610      * @param oncanplay the {@code oncanplay} event handler for this element
2611      */
2612     @JsxSetter
2613     public void setOncanplay(final Object oncanplay) {
2614         setEventHandler("canplay", oncanplay);
2615     }
2616 
2617     /**
2618      * Returns the {@code oncanplaythrough} event handler for this element.
2619      * @return the {@code oncanplaythrough} event handler for this element
2620      */
2621     @JsxGetter
2622     public Function getOncanplaythrough() {
2623         return getEventHandler("canplaythrough");
2624     }
2625 
2626     /**
2627      * Sets the {@code oncanplaythrough} event handler for this element.
2628      * @param oncanplaythrough the {@code oncanplaythrough} event handler for this element
2629      */
2630     @JsxSetter
2631     public void setOncanplaythrough(final Object oncanplaythrough) {
2632         setEventHandler("canplaythrough", oncanplaythrough);
2633     }
2634 
2635     /**
2636      * Returns the {@code onclose} event handler for this element.
2637      * @return the {@code onclose} event handler for this element
2638      */
2639     @JsxGetter(CHROME)
2640     public Function getOnclose() {
2641         return getEventHandler(Event.TYPE_CLOSE);
2642     }
2643 
2644     /**
2645      * Sets the {@code onclose} event handler for this element.
2646      * @param onclose the {@code onclose} event handler for this element
2647      */
2648     @JsxSetter(CHROME)
2649     public void setOnclose(final Object onclose) {
2650         setEventHandler(Event.TYPE_CLOSE, onclose);
2651     }
2652 
2653     /**
2654      * Returns the {@code oncuechange} event handler for this element.
2655      * @return the {@code oncuechange} event handler for this element
2656      */
2657     @JsxGetter({CHROME, IE})
2658     public Function getOncuechange() {
2659         return getEventHandler("cuechange");
2660     }
2661 
2662     /**
2663      * Sets the {@code oncuechange} event handler for this element.
2664      * @param oncuechange the {@code oncuechange} event handler for this element
2665      */
2666     @JsxSetter({CHROME, IE})
2667     public void setOncuechange(final Object oncuechange) {
2668         setEventHandler("cuechange", oncuechange);
2669     }
2670 
2671     /**
2672      * Returns the {@code ondrag} event handler for this element.
2673      * @return the {@code ondrag} event handler for this element
2674      */
2675     @JsxGetter
2676     public Function getOndrag() {
2677         return getEventHandler("drag");
2678     }
2679 
2680     /**
2681      * Sets the {@code ondrag} event handler for this element.
2682      * @param ondrag the {@code ondrag} event handler for this element
2683      */
2684     @JsxSetter
2685     public void setOndrag(final Object ondrag) {
2686         setEventHandler("drag", ondrag);
2687     }
2688 
2689     /**
2690      * Returns the {@code ondragend} event handler for this element.
2691      * @return the {@code ondragend} event handler for this element
2692      */
2693     @JsxGetter
2694     public Function getOndragend() {
2695         return getEventHandler("dragend");
2696     }
2697 
2698     /**
2699      * Sets the {@code ondragend} event handler for this element.
2700      * @param ondragend the {@code ondragend} event handler for this element
2701      */
2702     @JsxSetter
2703     public void setOndragend(final Object ondragend) {
2704         setEventHandler("dragend", ondragend);
2705     }
2706 
2707     /**
2708      * Returns the {@code ondragenter} event handler for this element.
2709      * @return the {@code ondragenter} event handler for this element
2710      */
2711     @JsxGetter
2712     public Function getOndragenter() {
2713         return getEventHandler("dragenter");
2714     }
2715 
2716     /**
2717      * Sets the {@code ondragenter} event handler for this element.
2718      * @param ondragenter the {@code ondragenter} event handler for this element
2719      */
2720     @JsxSetter
2721     public void setOndragenter(final Object ondragenter) {
2722         setEventHandler("dragenter", ondragenter);
2723     }
2724 
2725     /**
2726      * Returns the {@code ondragleave} event handler for this element.
2727      * @return the {@code ondragleave} event handler for this element
2728      */
2729     @JsxGetter
2730     public Function getOndragleave() {
2731         return getEventHandler("dragleave");
2732     }
2733 
2734     /**
2735      * Sets the {@code ondragleave} event handler for this element.
2736      * @param ondragleave the {@code ondragleave} event handler for this element
2737      */
2738     @JsxSetter
2739     public void setOndragleave(final Object ondragleave) {
2740         setEventHandler("dragleave", ondragleave);
2741     }
2742 
2743     /**
2744      * Returns the {@code ondragover} event handler for this element.
2745      * @return the {@code ondragover} event handler for this element
2746      */
2747     @JsxGetter
2748     public Function getOndragover() {
2749         return getEventHandler("dragover");
2750     }
2751 
2752     /**
2753      * Sets the {@code ondragover} event handler for this element.
2754      * @param ondragover the {@code ondragover} event handler for this element
2755      */
2756     @JsxSetter
2757     public void setOndragover(final Object ondragover) {
2758         setEventHandler("dragover", ondragover);
2759     }
2760 
2761     /**
2762      * Returns the {@code ondragstart} event handler for this element.
2763      * @return the {@code ondragstart} event handler for this element
2764      */
2765     @JsxGetter
2766     public Function getOndragstart() {
2767         return getEventHandler("dragstart");
2768     }
2769 
2770     /**
2771      * Sets the {@code ondragstart} event handler for this element.
2772      * @param ondragstart the {@code ondragstart} event handler for this element
2773      */
2774     @JsxSetter
2775     public void setOndragstart(final Object ondragstart) {
2776         setEventHandler("dragstart", ondragstart);
2777     }
2778 
2779     /**
2780      * Returns the {@code ondrop} event handler for this element.
2781      * @return the {@code ondrop} event handler for this element
2782      */
2783     @JsxGetter
2784     public Function getOndrop() {
2785         return getEventHandler("drop");
2786     }
2787 
2788     /**
2789      * Sets the {@code ondrop} event handler for this element.
2790      * @param ondrop the {@code ondrop} event handler for this element
2791      */
2792     @JsxSetter
2793     public void setOndrop(final Object ondrop) {
2794         setEventHandler("drop", ondrop);
2795     }
2796 
2797     /**
2798      * Returns the {@code ondurationchange} event handler for this element.
2799      * @return the {@code ondurationchange} event handler for this element
2800      */
2801     @JsxGetter
2802     public Function getOndurationchange() {
2803         return getEventHandler("durationchange");
2804     }
2805 
2806     /**
2807      * Sets the {@code ondurationchange} event handler for this element.
2808      * @param ondurationchange the {@code ondurationchange} event handler for this element
2809      */
2810     @JsxSetter
2811     public void setOndurationchange(final Object ondurationchange) {
2812         setEventHandler("durationchange", ondurationchange);
2813     }
2814 
2815     /**
2816      * Returns the {@code onemptied} event handler for this element.
2817      * @return the {@code onemptied} event handler for this element
2818      */
2819     @JsxGetter
2820     public Function getOnemptied() {
2821         return getEventHandler("emptied");
2822     }
2823 
2824     /**
2825      * Sets the {@code onemptied} event handler for this element.
2826      * @param onemptied the {@code onemptied} event handler for this element
2827      */
2828     @JsxSetter
2829     public void setOnemptied(final Object onemptied) {
2830         setEventHandler("emptied", onemptied);
2831     }
2832 
2833     /**
2834      * Returns the {@code onended} event handler for this element.
2835      * @return the {@code onended} event handler for this element
2836      */
2837     @JsxGetter
2838     public Function getOnended() {
2839         return getEventHandler("ended");
2840     }
2841 
2842     /**
2843      * Sets the {@code onended} event handler for this element.
2844      * @param onended the {@code onended} event handler for this element
2845      */
2846     @JsxSetter
2847     public void setOnended(final Object onended) {
2848         setEventHandler("ended", onended);
2849     }
2850 
2851     /**
2852      * Returns the {@code ongotpointercapture} event handler for this element.
2853      * @return the {@code ongotpointercapture} event handler for this element
2854      */
2855     @Override
2856     @JsxGetter(CHROME)
2857     public Function getOngotpointercapture() {
2858         return getEventHandler("gotpointercapture");
2859     }
2860 
2861     /**
2862      * Sets the {@code ongotpointercapture} event handler for this element.
2863      * @param ongotpointercapture the {@code ongotpointercapture} event handler for this element
2864      */
2865     @Override
2866     @JsxSetter(CHROME)
2867     public void setOngotpointercapture(final Object ongotpointercapture) {
2868         setEventHandler("gotpointercapture", ongotpointercapture);
2869     }
2870 
2871     /**
2872      * Returns the {@code oninvalid} event handler for this element.
2873      * @return the {@code oninvalid} event handler for this element
2874      */
2875     @JsxGetter({CHROME, FF})
2876     public Function getOninvalid() {
2877         return getEventHandler("invalid");
2878     }
2879 
2880     /**
2881      * Sets the {@code oninvalid} event handler for this element.
2882      * @param oninvalid the {@code oninvalid} event handler for this element
2883      */
2884     @JsxSetter({CHROME, FF})
2885     public void setOninvalid(final Object oninvalid) {
2886         setEventHandler("invalid", oninvalid);
2887     }
2888 
2889     /**
2890      * Returns the {@code onload} event handler for this element.
2891      * @return the {@code onload} event handler for this element
2892      */
2893     @JsxGetter
2894     public Function getOnload() {
2895         return getEventHandler(Event.TYPE_LOAD);
2896     }
2897 
2898     /**
2899      * Sets the {@code onload} event handler for this element.
2900      * @param onload the {@code onload} event handler for this element
2901      */
2902     @JsxSetter
2903     public void setOnload(final Object onload) {
2904         setEventHandler(Event.TYPE_LOAD, onload);
2905     }
2906 
2907     /**
2908      * Returns the {@code onloadeddata} event handler for this element.
2909      * @return the {@code onloadeddata} event handler for this element
2910      */
2911     @JsxGetter
2912     public Function getOnloadeddata() {
2913         return getEventHandler("loadeddata");
2914     }
2915 
2916     /**
2917      * Sets the {@code onloadeddata} event handler for this element.
2918      * @param onloadeddata the {@code onloadeddata} event handler for this element
2919      */
2920     @JsxSetter
2921     public void setOnloadeddata(final Object onloadeddata) {
2922         setEventHandler("loadeddata", onloadeddata);
2923     }
2924 
2925     /**
2926      * Returns the {@code onloadedmetadata} event handler for this element.
2927      * @return the {@code onloadedmetadata} event handler for this element
2928      */
2929     @JsxGetter
2930     public Function getOnloadedmetadata() {
2931         return getEventHandler("loadedmetadata");
2932     }
2933 
2934     /**
2935      * Sets the {@code onloadedmetadata} event handler for this element.
2936      * @param onloadedmetadata the {@code onloadedmetadata} event handler for this element
2937      */
2938     @JsxSetter
2939     public void setOnloadedmetadata(final Object onloadedmetadata) {
2940         setEventHandler("loadedmetadata", onloadedmetadata);
2941     }
2942 
2943     /**
2944      * Returns the {@code onloadstart} event handler for this element.
2945      * @return the {@code onloadstart} event handler for this element
2946      */
2947     @JsxGetter
2948     public Function getOnloadstart() {
2949         return getEventHandler("loadstart");
2950     }
2951 
2952     /**
2953      * Sets the {@code onloadstart} event handler for this element.
2954      * @param onloadstart the {@code onloadstart} event handler for this element
2955      */
2956     @JsxSetter
2957     public void setOnloadstart(final Object onloadstart) {
2958         setEventHandler("loadstart", onloadstart);
2959     }
2960 
2961     /**
2962      * Returns the {@code onlostpointercapture} event handler for this element.
2963      * @return the {@code onlostpointercapture} event handler for this element
2964      */
2965     @Override
2966     @JsxGetter(CHROME)
2967     public Function getOnlostpointercapture() {
2968         return getEventHandler("lostpointercapture");
2969     }
2970 
2971     /**
2972      * Sets the {@code onlostpointercapture} event handler for this element.
2973      * @param onlostpointercapture the {@code onlostpointercapture} event handler for this element
2974      */
2975     @Override
2976     @JsxSetter(CHROME)
2977     public void setOnlostpointercapture(final Object onlostpointercapture) {
2978         setEventHandler("lostpointercapture", onlostpointercapture);
2979     }
2980 
2981     /**
2982      * Returns the {@code onmouseenter} event handler for this element.
2983      * @return the {@code onmouseenter} event handler for this element
2984      */
2985     @JsxGetter
2986     public Function getOnmouseenter() {
2987         return getEventHandler("mouseenter");
2988     }
2989 
2990     /**
2991      * Sets the {@code onmouseenter} event handler for this element.
2992      * @param onmouseenter the {@code onmouseenter} event handler for this element
2993      */
2994     @JsxSetter
2995     public void setOnmouseenter(final Object onmouseenter) {
2996         setEventHandler("mouseenter", onmouseenter);
2997     }
2998 
2999     /**
3000      * Returns the {@code onmouseleave} event handler for this element.
3001      * @return the {@code onmouseleave} event handler for this element
3002      */
3003     @JsxGetter
3004     public Function getOnmouseleave() {
3005         return getEventHandler("mouseleave");
3006     }
3007 
3008     /**
3009      * Sets the {@code onmouseleave} event handler for this element.
3010      * @param onmouseleave the {@code onmouseleave} event handler for this element
3011      */
3012     @JsxSetter
3013     public void setOnmouseleave(final Object onmouseleave) {
3014         setEventHandler("mouseleave", onmouseleave);
3015     }
3016 
3017     /**
3018      * Returns the {@code onmousewheel} event handler for this element.
3019      * @return the {@code onmousewheel} event handler for this element
3020      */
3021     @JsxGetter({CHROME, IE})
3022     public Function getOnmousewheel() {
3023         return getEventHandler("mousewheel");
3024     }
3025 
3026     /**
3027      * Sets the {@code onmousewheel} event handler for this element.
3028      * @param onmousewheel the {@code onmousewheel} event handler for this element
3029      */
3030     @JsxSetter({CHROME, IE})
3031     public void setOnmousewheel(final Object onmousewheel) {
3032         setEventHandler("mousewheel", onmousewheel);
3033     }
3034 
3035     /**
3036      * Returns the {@code onpause} event handler for this element.
3037      * @return the {@code onpause} event handler for this element
3038      */
3039     @JsxGetter
3040     public Function getOnpause() {
3041         return getEventHandler("pause");
3042     }
3043 
3044     /**
3045      * Sets the {@code onpause} event handler for this element.
3046      * @param onpause the {@code onpause} event handler for this element
3047      */
3048     @JsxSetter
3049     public void setOnpause(final Object onpause) {
3050         setEventHandler("pause", onpause);
3051     }
3052 
3053     /**
3054      * Returns the {@code onplay} event handler for this element.
3055      * @return the {@code onplay} event handler for this element
3056      */
3057     @JsxGetter
3058     public Function getOnplay() {
3059         return getEventHandler("play");
3060     }
3061 
3062     /**
3063      * Sets the {@code onplay} event handler for this element.
3064      * @param onplay the {@code onplay} event handler for this element
3065      */
3066     @JsxSetter
3067     public void setOnplay(final Object onplay) {
3068         setEventHandler("play", onplay);
3069     }
3070 
3071     /**
3072      * Returns the {@code onplaying} event handler for this element.
3073      * @return the {@code onplaying} event handler for this element
3074      */
3075     @JsxGetter
3076     public Function getOnplaying() {
3077         return getEventHandler("playing");
3078     }
3079 
3080     /**
3081      * Sets the {@code onplaying} event handler for this element.
3082      * @param onplaying the {@code onplaying} event handler for this element
3083      */
3084     @JsxSetter
3085     public void setOnplaying(final Object onplaying) {
3086         setEventHandler("playing", onplaying);
3087     }
3088 
3089     /**
3090      * Returns the {@code onpointercancel} event handler for this element.
3091      * @return the {@code onpointercancel} event handler for this element
3092      */
3093     @Override
3094     @JsxGetter(CHROME)
3095     public Function getOnpointercancel() {
3096         return getEventHandler("pointercancel");
3097     }
3098 
3099     /**
3100      * Sets the {@code onpointercancel} event handler for this element.
3101      * @param onpointercancel the {@code onpointercancel} event handler for this element
3102      */
3103     @Override
3104     @JsxSetter(CHROME)
3105     public void setOnpointercancel(final Object onpointercancel) {
3106         setEventHandler("pointercancel", onpointercancel);
3107     }
3108 
3109     /**
3110      * Returns the {@code onpointerdown} event handler for this element.
3111      * @return the {@code onpointerdown} event handler for this element
3112      */
3113     @Override
3114     @JsxGetter(CHROME)
3115     public Function getOnpointerdown() {
3116         return getEventHandler("pointerdown");
3117     }
3118 
3119     /**
3120      * Sets the {@code onpointerdown} event handler for this element.
3121      * @param onpointerdown the {@code onpointerdown} event handler for this element
3122      */
3123     @Override
3124     @JsxSetter(CHROME)
3125     public void setOnpointerdown(final Object onpointerdown) {
3126         setEventHandler("pointerdown", onpointerdown);
3127     }
3128 
3129     /**
3130      * Returns the {@code onpointerenter} event handler for this element.
3131      * @return the {@code onpointerenter} event handler for this element
3132      */
3133     @Override
3134     @JsxGetter(CHROME)
3135     public Function getOnpointerenter() {
3136         return getEventHandler("pointerenter");
3137     }
3138 
3139     /**
3140      * Sets the {@code onpointerenter} event handler for this element.
3141      * @param onpointerenter the {@code onpointerenter} event handler for this element
3142      */
3143     @Override
3144     @JsxSetter(CHROME)
3145     public void setOnpointerenter(final Object onpointerenter) {
3146         setEventHandler("pointerenter", onpointerenter);
3147     }
3148 
3149     /**
3150      * Returns the {@code onpointerleave} event handler for this element.
3151      * @return the {@code onpointerleave} event handler for this element
3152      */
3153     @Override
3154     @JsxGetter(CHROME)
3155     public Function getOnpointerleave() {
3156         return getEventHandler("pointerleave");
3157     }
3158 
3159     /**
3160      * Sets the {@code onpointerleave} event handler for this element.
3161      * @param onpointerleave the {@code onpointerleave} event handler for this element
3162      */
3163     @Override
3164     @JsxSetter(CHROME)
3165     public void setOnpointerleave(final Object onpointerleave) {
3166         setEventHandler("pointerleave", onpointerleave);
3167     }
3168 
3169     /**
3170      * Returns the {@code onpointermove} event handler for this element.
3171      * @return the {@code onpointermove} event handler for this element
3172      */
3173     @Override
3174     @JsxGetter(CHROME)
3175     public Function getOnpointermove() {
3176         return getEventHandler("pointermove");
3177     }
3178 
3179     /**
3180      * Sets the {@code onpointermove} event handler for this element.
3181      * @param onpointermove the {@code onpointermove} event handler for this element
3182      */
3183     @Override
3184     @JsxSetter(CHROME)
3185     public void setOnpointermove(final Object onpointermove) {
3186         setEventHandler("pointermove", onpointermove);
3187     }
3188 
3189     /**
3190      * Returns the {@code onpointerout} event handler for this element.
3191      * @return the {@code onpointerout} event handler for this element
3192      */
3193     @Override
3194     @JsxGetter(CHROME)
3195     public Function getOnpointerout() {
3196         return getEventHandler("pointerout");
3197     }
3198 
3199     /**
3200      * Sets the {@code onpointerout} event handler for this element.
3201      * @param onpointerout the {@code onpointerout} event handler for this element
3202      */
3203     @Override
3204     @JsxSetter(CHROME)
3205     public void setOnpointerout(final Object onpointerout) {
3206         setEventHandler("pointerout", onpointerout);
3207     }
3208 
3209     /**
3210      * Returns the {@code onpointerover} event handler for this element.
3211      * @return the {@code onpointerover} event handler for this element
3212      */
3213     @Override
3214     @JsxGetter(CHROME)
3215     public Function getOnpointerover() {
3216         return getEventHandler("pointerover");
3217     }
3218 
3219     /**
3220      * Sets the {@code onpointerover} event handler for this element.
3221      * @param onpointerover the {@code onpointerover} event handler for this element
3222      */
3223     @Override
3224     @JsxSetter(CHROME)
3225     public void setOnpointerover(final Object onpointerover) {
3226         setEventHandler("pointerover", onpointerover);
3227     }
3228 
3229     /**
3230      * Returns the {@code onpointerup} event handler for this element.
3231      * @return the {@code onpointerup} event handler for this element
3232      */
3233     @Override
3234     @JsxGetter(CHROME)
3235     public Function getOnpointerup() {
3236         return getEventHandler("pointerup");
3237     }
3238 
3239     /**
3240      * Sets the {@code onpointerup} event handler for this element.
3241      * @param onpointerup the {@code onpointerup} event handler for this element
3242      */
3243     @Override
3244     @JsxSetter(CHROME)
3245     public void setOnpointerup(final Object onpointerup) {
3246         setEventHandler("pointerup", onpointerup);
3247     }
3248 
3249     /**
3250      * Returns the {@code onprogress} event handler for this element.
3251      * @return the {@code onprogress} event handler for this element
3252      */
3253     @JsxGetter
3254     public Function getOnprogress() {
3255         return getEventHandler("progress");
3256     }
3257 
3258     /**
3259      * Sets the {@code onprogress} event handler for this element.
3260      * @param onprogress the {@code onprogress} event handler for this element
3261      */
3262     @JsxSetter
3263     public void setOnprogress(final Object onprogress) {
3264         setEventHandler("progress", onprogress);
3265     }
3266 
3267     /**
3268      * Returns the {@code onratechange} event handler for this element.
3269      * @return the {@code onratechange} event handler for this element
3270      */
3271     @JsxGetter
3272     public Function getOnratechange() {
3273         return getEventHandler("ratechange");
3274     }
3275 
3276     /**
3277      * Sets the {@code onratechange} event handler for this element.
3278      * @param onratechange the {@code onratechange} event handler for this element
3279      */
3280     @JsxSetter
3281     public void setOnratechange(final Object onratechange) {
3282         setEventHandler("ratechange", onratechange);
3283     }
3284 
3285     /**
3286      * Returns the {@code onreset} event handler for this element.
3287      * @return the {@code onreset} event handler for this element
3288      */
3289     @JsxGetter
3290     public Function getOnreset() {
3291         return getEventHandler(Event.TYPE_RESET);
3292     }
3293 
3294     /**
3295      * Sets the {@code onreset} event handler for this element.
3296      * @param onreset the {@code onreset} event handler for this element
3297      */
3298     @JsxSetter
3299     public void setOnreset(final Object onreset) {
3300         setEventHandler(Event.TYPE_RESET, onreset);
3301     }
3302 
3303     /**
3304      * Returns the {@code onscroll} event handler for this element.
3305      * @return the {@code onscroll} event handler for this element
3306      */
3307     @JsxGetter
3308     public Function getOnscroll() {
3309         return getEventHandler("scroll");
3310     }
3311 
3312     /**
3313      * Sets the {@code onscroll} event handler for this element.
3314      * @param onscroll the {@code onscroll} event handler for this element
3315      */
3316     @JsxSetter
3317     public void setOnscroll(final Object onscroll) {
3318         setEventHandler("scroll", onscroll);
3319     }
3320 
3321     /**
3322      * Returns the {@code onseeked} event handler for this element.
3323      * @return the {@code onseeked} event handler for this element
3324      */
3325     @JsxGetter
3326     public Function getOnseeked() {
3327         return getEventHandler("seeked");
3328     }
3329 
3330     /**
3331      * Sets the {@code onseeked} event handler for this element.
3332      * @param onseeked the {@code onseeked} event handler for this element
3333      */
3334     @JsxSetter
3335     public void setOnseeked(final Object onseeked) {
3336         setEventHandler("seeked", onseeked);
3337     }
3338 
3339     /**
3340      * Returns the {@code onseeking} event handler for this element.
3341      * @return the {@code onseeking} event handler for this element
3342      */
3343     @JsxGetter
3344     public Function getOnseeking() {
3345         return getEventHandler("seeking");
3346     }
3347 
3348     /**
3349      * Sets the {@code onseeking} event handler for this element.
3350      * @param onseeking the {@code onseeking} event handler for this element
3351      */
3352     @JsxSetter
3353     public void setOnseeking(final Object onseeking) {
3354         setEventHandler("seeking", onseeking);
3355     }
3356 
3357     /**
3358      * Returns the {@code onselect} event handler for this element.
3359      * @return the {@code onselect} event handler for this element
3360      */
3361     @JsxGetter
3362     public Function getOnselect() {
3363         return getEventHandler("select");
3364     }
3365 
3366     /**
3367      * Sets the {@code onselect} event handler for this element.
3368      * @param onselect the {@code onselect} event handler for this element
3369      */
3370     @JsxSetter
3371     public void setOnselect(final Object onselect) {
3372         setEventHandler("select", onselect);
3373     }
3374 
3375     /**
3376      * Returns the {@code onshow} event handler for this element.
3377      * @return the {@code onshow} event handler for this element
3378      */
3379     @JsxGetter({CHROME, FF})
3380     public Function getOnshow() {
3381         return getEventHandler("show");
3382     }
3383 
3384     /**
3385      * Sets the {@code onshow} event handler for this element.
3386      * @param onshow the {@code onshow} event handler for this element
3387      */
3388     @JsxSetter({CHROME, FF})
3389     public void setOnshow(final Object onshow) {
3390         setEventHandler("show", onshow);
3391     }
3392 
3393     /**
3394      * Returns the {@code onstalled} event handler for this element.
3395      * @return the {@code onstalled} event handler for this element
3396      */
3397     @JsxGetter
3398     public Function getOnstalled() {
3399         return getEventHandler("stalled");
3400     }
3401 
3402     /**
3403      * Sets the {@code onstalled} event handler for this element.
3404      * @param onstalled the {@code onstalled} event handler for this element
3405      */
3406     @JsxSetter
3407     public void setOnstalled(final Object onstalled) {
3408         setEventHandler("stalled", onstalled);
3409     }
3410 
3411     /**
3412      * Returns the {@code onsuspend} event handler for this element.
3413      * @return the {@code onsuspend} event handler for this element
3414      */
3415     @JsxGetter
3416     public Function getOnsuspend() {
3417         return getEventHandler("suspend");
3418     }
3419 
3420     /**
3421      * Sets the {@code onsuspend} event handler for this element.
3422      * @param onsuspend the {@code onsuspend} event handler for this element
3423      */
3424     @JsxSetter
3425     public void setOnsuspend(final Object onsuspend) {
3426         setEventHandler("suspend", onsuspend);
3427     }
3428 
3429     /**
3430      * Returns the {@code ontimeupdate} event handler for this element.
3431      * @return the {@code ontimeupdate} event handler for this element
3432      */
3433     @JsxGetter
3434     public Function getOntimeupdate() {
3435         return getEventHandler("timeupdate");
3436     }
3437 
3438     /**
3439      * Sets the {@code ontimeupdate} event handler for this element.
3440      * @param ontimeupdate the {@code ontimeupdate} event handler for this element
3441      */
3442     @JsxSetter
3443     public void setOntimeupdate(final Object ontimeupdate) {
3444         setEventHandler("timeupdate", ontimeupdate);
3445     }
3446 
3447     /**
3448      * Returns the {@code ontoggle} event handler for this element.
3449      * @return the {@code ontoggle} event handler for this element
3450      */
3451     @JsxGetter({CHROME, FF52})
3452     public Function getOntoggle() {
3453         return getEventHandler("toggle");
3454     }
3455 
3456     /**
3457      * Sets the {@code ontoggle} event handler for this element.
3458      * @param ontoggle the {@code ontoggle} event handler for this element
3459      */
3460     @JsxSetter({CHROME, FF52})
3461     public void setOntoggle(final Object ontoggle) {
3462         setEventHandler("toggle", ontoggle);
3463     }
3464 
3465     /**
3466      * Returns the {@code onvolumechange} event handler for this element.
3467      * @return the {@code onvolumechange} event handler for this element
3468      */
3469     @JsxGetter
3470     public Function getOnvolumechange() {
3471         return getEventHandler("volumechange");
3472     }
3473 
3474     /**
3475      * Sets the {@code onvolumechange} event handler for this element.
3476      * @param onvolumechange the {@code onvolumechange} event handler for this element
3477      */
3478     @JsxSetter
3479     public void setOnvolumechange(final Object onvolumechange) {
3480         setEventHandler("volumechange", onvolumechange);
3481     }
3482 
3483     /**
3484      * Returns the {@code onwaiting} event handler for this element.
3485      * @return the {@code onwaiting} event handler for this element
3486      */
3487     @JsxGetter
3488     public Function getOnwaiting() {
3489         return getEventHandler("waiting");
3490     }
3491 
3492     /**
3493      * Sets the {@code onwaiting} event handler for this element.
3494      * @param onwaiting the {@code onwaiting} event handler for this element
3495      */
3496     @JsxSetter
3497     public void setOnwaiting(final Object onwaiting) {
3498         setEventHandler("waiting", onwaiting);
3499     }
3500 
3501     /**
3502      * Returns the {@code oncopy} event handler for this element.
3503      * @return the {@code oncopy} event handler for this element
3504      */
3505     @Override
3506     @JsxGetter({FF, IE})
3507     public Function getOncopy() {
3508         return getEventHandler("copy");
3509     }
3510 
3511     /**
3512      * Sets the {@code oncopy} event handler for this element.
3513      * @param oncopy the {@code oncopy} event handler for this element
3514      */
3515     @Override
3516     @JsxSetter({FF, IE})
3517     public void setOncopy(final Object oncopy) {
3518         setEventHandler("copy", oncopy);
3519     }
3520 
3521     /**
3522      * Returns the {@code oncut} event handler for this element.
3523      * @return the {@code oncut} event handler for this element
3524      */
3525     @Override
3526     @JsxGetter({FF, IE})
3527     public Function getOncut() {
3528         return getEventHandler("cut");
3529     }
3530 
3531     /**
3532      * Sets the {@code oncut} event handler for this element.
3533      * @param oncut the {@code oncut} event handler for this element
3534      */
3535     @Override
3536     @JsxSetter({FF, IE})
3537     public void setOncut(final Object oncut) {
3538         setEventHandler("cut", oncut);
3539     }
3540 
3541     /**
3542      * Returns the {@code onpaste} event handler for this element.
3543      * @return the {@code onpaste} event handler for this element
3544      */
3545     @Override
3546     @JsxGetter({FF, IE})
3547     public Function getOnpaste() {
3548         return getEventHandler("paste");
3549     }
3550 
3551     /**
3552      * Sets the {@code onpaste} event handler for this element.
3553      * @param onpaste the {@code onpaste} event handler for this element
3554      */
3555     @Override
3556     @JsxSetter({FF, IE})
3557     public void setOnpaste(final Object onpaste) {
3558         setEventHandler("paste", onpaste);
3559     }
3560 
3561     /**
3562      * Returns the {@code onmozfullscreenchange} event handler for this element.
3563      * @return the {@code onmozfullscreenchange} event handler for this element
3564      */
3565     @JsxGetter(FF)
3566     public Function getOnmozfullscreenchange() {
3567         return getEventHandler("mozfullscreenchange");
3568     }
3569 
3570     /**
3571      * Sets the {@code onmozfullscreenchange} event handler for this element.
3572      * @param onmozfullscreenchange the {@code onmozfullscreenchange} event handler for this element
3573      */
3574     @JsxSetter(FF)
3575     public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
3576         setEventHandler("mozfullscreenchange", onmozfullscreenchange);
3577     }
3578 
3579     /**
3580      * Returns the {@code onmozfullscreenerror} event handler for this element.
3581      * @return the {@code onmozfullscreenerror} event handler for this element
3582      */
3583     @JsxGetter(FF)
3584     public Function getOnmozfullscreenerror() {
3585         return getEventHandler("mozfullscreenerror");
3586     }
3587 
3588     /**
3589      * Sets the {@code onmozfullscreenerror} event handler for this element.
3590      * @param onmozfullscreenerror the {@code onmozfullscreenerror} event handler for this element
3591      */
3592     @JsxSetter(FF)
3593     public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
3594         setEventHandler("mozfullscreenerror", onmozfullscreenerror);
3595     }
3596 
3597     /**
3598      * Returns the {@code onmozpointerlockchange} event handler for this element.
3599      * @return the {@code onmozpointerlockchange} event handler for this element
3600      */
3601     @JsxGetter(FF45)
3602     public Function getOnmozpointerlockchange() {
3603         return getEventHandler("mozpointerlockchange");
3604     }
3605 
3606     /**
3607      * Sets the {@code onmozpointerlockchange} event handler for this element.
3608      * @param onmozpointerlockchange the {@code onmozpointerlockchange} event handler for this element
3609      */
3610     @JsxSetter(FF45)
3611     public void setOnmozpointerlockchange(final Object onmozpointerlockchange) {
3612         setEventHandler("mozpointerlockchange", onmozpointerlockchange);
3613     }
3614 
3615     /**
3616      * Returns the {@code onmozpointerlockerror} event handler for this element.
3617      * @return the {@code onmozpointerlockerror} event handler for this element
3618      */
3619     @JsxGetter(FF45)
3620     public Function getOnmozpointerlockerror() {
3621         return getEventHandler("mozpointerlockerror");
3622     }
3623 
3624     /**
3625      * Sets the {@code onmozpointerlockerror} event handler for this element.
3626      * @param onmozpointerlockerror the {@code onmozpointerlockerror} event handler for this element
3627      */
3628     @JsxSetter(FF45)
3629     public void setOnmozpointerlockerror(final Object onmozpointerlockerror) {
3630         setEventHandler("mozpointerlockerror", onmozpointerlockerror);
3631     }
3632 
3633     /**
3634      * Returns the {@code onactivate} event handler for this element.
3635      * @return the {@code onactivate} event handler for this element
3636      */
3637     @JsxGetter(IE)
3638     public Function getOnactivate() {
3639         return getEventHandler("activate");
3640     }
3641 
3642     /**
3643      * Sets the {@code onactivate} event handler for this element.
3644      * @param onactivate the {@code onactivate} event handler for this element
3645      */
3646     @JsxSetter(IE)
3647     public void setOnactivate(final Object onactivate) {
3648         setEventHandler("activate", onactivate);
3649     }
3650 
3651     /**
3652      * Returns the {@code onbeforeactivate} event handler for this element.
3653      * @return the {@code onbeforeactivate} event handler for this element
3654      */
3655     @JsxGetter(IE)
3656     public Function getOnbeforeactivate() {
3657         return getEventHandler("beforeactivate");
3658     }
3659 
3660     /**
3661      * Sets the {@code onbeforeactivate} event handler for this element.
3662      * @param onbeforeactivate the {@code onbeforeactivate} event handler for this element
3663      */
3664     @JsxSetter(IE)
3665     public void setOnbeforeactivate(final Object onbeforeactivate) {
3666         setEventHandler("beforeactivate", onbeforeactivate);
3667     }
3668 
3669     /**
3670      * Returns the {@code onbeforecopy} event handler for this element.
3671      * @return the {@code onbeforecopy} event handler for this element
3672      */
3673     @Override
3674     @JsxGetter(IE)
3675     public Function getOnbeforecopy() {
3676         return getEventHandler("beforecopy");
3677     }
3678 
3679     /**
3680      * Sets the {@code onbeforecopy} event handler for this element.
3681      * @param onbeforecopy the {@code onbeforecopy} event handler for this element
3682      */
3683     @Override
3684     @JsxSetter(IE)
3685     public void setOnbeforecopy(final Object onbeforecopy) {
3686         setEventHandler("beforecopy", onbeforecopy);
3687     }
3688 
3689     /**
3690      * Returns the {@code onbeforecut} event handler for this element.
3691      * @return the {@code onbeforecut} event handler for this element
3692      */
3693     @Override
3694     @JsxGetter(IE)
3695     public Function getOnbeforecut() {
3696         return getEventHandler("beforecut");
3697     }
3698 
3699     /**
3700      * Sets the {@code onbeforecut} event handler for this element.
3701      * @param onbeforecut the {@code onbeforecut} event handler for this element
3702      */
3703     @Override
3704     @JsxSetter(IE)
3705     public void setOnbeforecut(final Object onbeforecut) {
3706         setEventHandler("beforecut", onbeforecut);
3707     }
3708 
3709     /**
3710      * Returns the {@code onbeforedeactivate} event handler for this element.
3711      * @return the {@code onbeforedeactivate} event handler for this element
3712      */
3713     @JsxGetter(IE)
3714     public Function getOnbeforedeactivate() {
3715         return getEventHandler("beforedeactivate");
3716     }
3717 
3718     /**
3719      * Sets the {@code onbeforedeactivate} event handler for this element.
3720      * @param onbeforedeactivate the {@code onbeforedeactivate} event handler for this element
3721      */
3722     @JsxSetter(IE)
3723     public void setOnbeforedeactivate(final Object onbeforedeactivate) {
3724         setEventHandler("beforedeactivate", onbeforedeactivate);
3725     }
3726 
3727     /**
3728      * Returns the {@code onbeforepaste} event handler for this element.
3729      * @return the {@code onbeforepaste} event handler for this element
3730      */
3731     @Override
3732     @JsxGetter(IE)
3733     public Function getOnbeforepaste() {
3734         return getEventHandler("beforepaste");
3735     }
3736 
3737     /**
3738      * Sets the {@code onbeforepaste} event handler for this element.
3739      * @param onbeforepaste the {@code onbeforepaste} event handler for this element
3740      */
3741     @Override
3742     @JsxSetter(IE)
3743     public void setOnbeforepaste(final Object onbeforepaste) {
3744         setEventHandler("beforepaste", onbeforepaste);
3745     }
3746 
3747     /**
3748      * Returns the {@code ondeactivate} event handler for this element.
3749      * @return the {@code ondeactivate} event handler for this element
3750      */
3751     @JsxGetter(IE)
3752     public Function getOndeactivate() {
3753         return getEventHandler("deactivate");
3754     }
3755 
3756     /**
3757      * Sets the {@code ondeactivate} event handler for this element.
3758      * @param ondeactivate the {@code ondeactivate} event handler for this element
3759      */
3760     @JsxSetter(IE)
3761     public void setOndeactivate(final Object ondeactivate) {
3762         setEventHandler("deactivate", ondeactivate);
3763     }
3764 
3765     /**
3766      * Returns the {@code onhelp} event handler for this element.
3767      * @return the {@code onhelp} event handler for this element
3768      */
3769     @JsxGetter(IE)
3770     public Function getOnhelp() {
3771         return getEventHandler("help");
3772     }
3773 
3774     /**
3775      * Sets the {@code onhelp} event handler for this element.
3776      * @param onhelp the {@code onhelp} event handler for this element
3777      */
3778     @JsxSetter(IE)
3779     public void setOnhelp(final Object onhelp) {
3780         setEventHandler("help", onhelp);
3781     }
3782 
3783     /**
3784      * Returns the {@code onmscontentzoom} event handler for this element.
3785      * @return the {@code onmscontentzoom} event handler for this element
3786      */
3787     @JsxGetter(IE)
3788     public Function getOnmscontentzoom() {
3789         return getEventHandler("mscontentzoom");
3790     }
3791 
3792     /**
3793      * Sets the {@code onmscontentzoom} event handler for this element.
3794      * @param onmscontentzoom the {@code onmscontentzoom} event handler for this element
3795      */
3796     @JsxSetter(IE)
3797     public void setOnmscontentzoom(final Object onmscontentzoom) {
3798         setEventHandler("mscontentzoom", onmscontentzoom);
3799     }
3800 
3801     /**
3802      * Returns the {@code onmsmanipulationstatechanged} event handler for this element.
3803      * @return the {@code onmsmanipulationstatechanged} event handler for this element
3804      */
3805     @JsxGetter(IE)
3806     public Function getOnmsmanipulationstatechanged() {
3807         return getEventHandler("msmanipulationstatechanged");
3808     }
3809 
3810     /**
3811      * Sets the {@code onmsmanipulationstatechanged} event handler for this element.
3812      * @param onmsmanipulationstatechanged the {@code onmsmanipulationstatechanged} event handler for this element
3813      */
3814     @JsxSetter(IE)
3815     public void setOnmsmanipulationstatechanged(final Object onmsmanipulationstatechanged) {
3816         setEventHandler("msmanipulationstatechanged", onmsmanipulationstatechanged);
3817     }
3818 
3819     /**
3820      * Returns the {@code onselectstart} event handler for this element.
3821      * @return the {@code onselectstart} event handler for this element
3822      */
3823     @Override
3824     @JsxGetter({IE, FF52})
3825     public Function getOnselectstart() {
3826         return getEventHandler("selectstart");
3827     }
3828 
3829     /**
3830      * Sets the {@code onselectstart} event handler for this element.
3831      * @param onselectstart the {@code onselectstart} event handler for this element
3832      */
3833     @Override
3834     @JsxSetter({IE, FF52})
3835     public void setOnselectstart(final Object onselectstart) {
3836         setEventHandler("selectstart", onselectstart);
3837     }
3838 
3839     /**
3840      * Returns the {@code onanimationend} event handler.
3841      * @return the {@code onanimationend} event handler
3842      */
3843     @JsxGetter(FF52)
3844     public Function getOnanimationend() {
3845         return getEventHandler("animationend");
3846     }
3847 
3848     /**
3849      * Sets the {@code onanimationend} event handler.
3850      * @param animationend the {@code onanimationend} event handler
3851      */
3852     @JsxSetter(FF52)
3853     public void setOnanimationend(final Object animationend) {
3854         setEventHandler("animationend", animationend);
3855     }
3856 
3857     /**
3858      * Returns the {@code onanimationiteration} event handler.
3859      * @return the {@code onanimationiteration} event handler
3860      */
3861     @JsxGetter(FF52)
3862     public Function getOnanimationiteration() {
3863         return getEventHandler("animationiteration");
3864     }
3865 
3866     /**
3867      * Sets the {@code onanimationiteration} event handler.
3868      * @param animationiteration the {@code onanimationiteration} event handler
3869      */
3870     @JsxSetter(FF52)
3871     public void setOnanimationiteration(final Object animationiteration) {
3872         setEventHandler("animationiteration", animationiteration);
3873     }
3874 
3875     /**
3876      * Returns the {@code onanimationstart} event handler.
3877      * @return the {@code onanimationstart} event handler
3878      */
3879     @JsxGetter(FF52)
3880     public Function getOnanimationstart() {
3881         return getEventHandler("animationstart");
3882     }
3883 
3884     /**
3885      * Sets the {@code onanimationstart} event handler.
3886      * @param animationstart the {@code onanimationstart} event handler
3887      */
3888     @JsxSetter(FF52)
3889     public void setOnanimationstart(final Object animationstart) {
3890         setEventHandler("animationstart", animationstart);
3891     }
3892 
3893     /**
3894      * Returns the {@code ondragexit} event handler.
3895      * @return the {@code ondragexit} event handler
3896      */
3897     @JsxGetter(FF52)
3898     public Function getOndragexit() {
3899         return getEventHandler("dragexit");
3900     }
3901 
3902     /**
3903      * Sets the {@code ondragexit} event handler.
3904      * @param dragexit the {@code ondragexit} event handler
3905      */
3906     @JsxSetter(FF52)
3907     public void setOndragexit(final Object dragexit) {
3908         setEventHandler("dragexit", dragexit);
3909     }
3910 
3911     /**
3912      * Returns the {@code onloadend} event handler.
3913      * @return the {@code onloadend} event handler
3914      */
3915     @JsxGetter(FF52)
3916     public Function getOnloadend() {
3917         return getEventHandler("loadend");
3918     }
3919 
3920     /**
3921      * Sets the {@code onloadend} event handler.
3922      * @param loadend the {@code onloadend} event handler
3923      */
3924     @JsxSetter(FF52)
3925     public void setOnloadend(final Object loadend) {
3926         setEventHandler("loadend", loadend);
3927     }
3928 
3929     /**
3930      * Returns the {@code ontransitionend} event handler.
3931      * @return the {@code ontransitionend} event handler
3932      */
3933     @JsxGetter(FF52)
3934     public Function getOntransitionend() {
3935         return getEventHandler("transitionend");
3936     }
3937 
3938     /**
3939      * Sets the {@code ontransitionend} event handler.
3940      * @param transitionend the {@code ontransitionend} event handler
3941      */
3942     @JsxSetter(FF52)
3943     public void setOntransitionend(final Object transitionend) {
3944         setEventHandler("transitionend", transitionend);
3945     }
3946 
3947     /**
3948      * Returns the {@code onwebkitanimationend} event handler.
3949      * @return the {@code onwebkitanimationend} event handler
3950      */
3951     @JsxGetter(FF52)
3952     public Function getOnwebkitanimationend() {
3953         return getEventHandler("webkitanimationend");
3954     }
3955 
3956     /**
3957      * Sets the {@code onwebkitanimationend} event handler.
3958      * @param webkitanimationend the {@code onwebkitanimationend} event handler
3959      */
3960     @JsxSetter(FF52)
3961     public void setOnwebkitanimationend(final Object webkitanimationend) {
3962         setEventHandler("webkitanimationend", webkitanimationend);
3963     }
3964 
3965     /**
3966      * Returns the {@code onwebkitanimationiteration} event handler.
3967      * @return the {@code onwebkitanimationiteration} event handler
3968      */
3969     @JsxGetter(FF52)
3970     public Function getOnwebkitanimationiteration() {
3971         return getEventHandler("webkitanimationiteration");
3972     }
3973 
3974     /**
3975      * Sets the {@code onwebkitanimationiteration} event handler.
3976      * @param webkitanimationiteration the {@code onwebkitanimationiteration} event handler
3977      */
3978     @JsxSetter(FF52)
3979     public void setOnwebkitanimationiteration(final Object webkitanimationiteration) {
3980         setEventHandler("webkitanimationiteration", webkitanimationiteration);
3981     }
3982 
3983     /**
3984      * Returns the {@code onwebkitanimationstart} event handler.
3985      * @return the {@code onwebkitanimationstart} event handler
3986      */
3987     @JsxGetter(FF52)
3988     public Function getOnwebkitanimationstart() {
3989         return getEventHandler("webkitanimationstart");
3990     }
3991 
3992     /**
3993      * Sets the {@code onwebkitanimationstart} event handler.
3994      * @param webkitanimationstart the {@code onwebkitanimationstart} event handler
3995      */
3996     @JsxSetter(FF52)
3997     public void setOnwebkitanimationstart(final Object webkitanimationstart) {
3998         setEventHandler("webkitanimationstart", webkitanimationstart);
3999     }
4000 
4001     /**
4002      * Returns the {@code onwebkittransitionend} event handler.
4003      * @return the {@code onwebkittransitionend} event handler
4004      */
4005     @JsxGetter(FF52)
4006     public Function getOnwebkittransitionend() {
4007         return getEventHandler("webkittransitionend");
4008     }
4009 
4010     /**
4011      * Sets the {@code onwebkittransitionend} event handler.
4012      * @param webkittransitionend the {@code onwebkittransitionend} event handler
4013      */
4014     @JsxSetter(FF52)
4015     public void setOnwebkittransitionend(final Object webkittransitionend) {
4016         setEventHandler("webkittransitionend", webkittransitionend);
4017     }
4018 
4019 }