View Javadoc
1   /*
2    * Copyright (c) 2002-2025 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    * https://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 org.htmlunit.javascript.host.dom;
16  
17  import static org.htmlunit.BrowserVersionFeatures.EVENT_ONANIMATION_DOCUMENT_CREATE_NOT_SUPPORTED;
18  import static org.htmlunit.BrowserVersionFeatures.EVENT_ONCLOSE_DOCUMENT_CREATE_NOT_SUPPORTED;
19  import static org.htmlunit.BrowserVersionFeatures.EVENT_ONPOPSTATE_DOCUMENT_CREATE_NOT_SUPPORTED;
20  import static org.htmlunit.BrowserVersionFeatures.EVENT_TYPE_MUTATIONEVENT;
21  import static org.htmlunit.BrowserVersionFeatures.EVENT_TYPE_TEXTEVENT;
22  import static org.htmlunit.BrowserVersionFeatures.EVENT_TYPE_WHEELEVENT;
23  import static org.htmlunit.BrowserVersionFeatures.HTMLDOCUMENT_COOKIES_IGNORE_BLANK;
24  import static org.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_EVALUATE_RECREATES_RESULT;
25  import static org.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_SELECTION_RANGE_COUNT;
26  import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
27  import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
28  import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
29  import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
30  
31  import java.io.IOException;
32  import java.io.Serializable;
33  import java.lang.reflect.InvocationTargetException;
34  import java.net.URL;
35  import java.time.ZoneId;
36  import java.time.format.DateTimeFormatter;
37  import java.util.Collections;
38  import java.util.Date;
39  import java.util.HashMap;
40  import java.util.HashSet;
41  import java.util.Locale;
42  import java.util.Map;
43  import java.util.Set;
44  import java.util.UUID;
45  import java.util.function.Predicate;
46  
47  import org.apache.commons.lang3.StringUtils;
48  import org.apache.commons.logging.Log;
49  import org.apache.commons.logging.LogFactory;
50  import org.htmlunit.HttpHeader;
51  import org.htmlunit.Page;
52  import org.htmlunit.SgmlPage;
53  import org.htmlunit.WebClient;
54  import org.htmlunit.WebResponse;
55  import org.htmlunit.WebWindow;
56  import org.htmlunit.corejs.javascript.Callable;
57  import org.htmlunit.corejs.javascript.Context;
58  import org.htmlunit.corejs.javascript.Function;
59  import org.htmlunit.corejs.javascript.NativeFunction;
60  import org.htmlunit.corejs.javascript.Scriptable;
61  import org.htmlunit.corejs.javascript.ScriptableObject;
62  import org.htmlunit.cssparser.parser.CSSException;
63  import org.htmlunit.html.DomComment;
64  import org.htmlunit.html.DomDocumentFragment;
65  import org.htmlunit.html.DomElement;
66  import org.htmlunit.html.DomNode;
67  import org.htmlunit.html.DomText;
68  import org.htmlunit.html.FrameWindow;
69  import org.htmlunit.html.Html;
70  import org.htmlunit.html.HtmlAnchor;
71  import org.htmlunit.html.HtmlArea;
72  import org.htmlunit.html.HtmlAttributeChangeEvent;
73  import org.htmlunit.html.HtmlElement;
74  import org.htmlunit.html.HtmlEmbed;
75  import org.htmlunit.html.HtmlForm;
76  import org.htmlunit.html.HtmlFrameSet;
77  import org.htmlunit.html.HtmlImage;
78  import org.htmlunit.html.HtmlPage;
79  import org.htmlunit.html.HtmlRb;
80  import org.htmlunit.html.HtmlRp;
81  import org.htmlunit.html.HtmlRt;
82  import org.htmlunit.html.HtmlRtc;
83  import org.htmlunit.html.HtmlScript;
84  import org.htmlunit.html.HtmlSvg;
85  import org.htmlunit.html.HtmlUnknownElement;
86  import org.htmlunit.html.UnknownElementFactory;
87  import org.htmlunit.html.impl.SimpleRange;
88  import org.htmlunit.http.HttpUtils;
89  import org.htmlunit.httpclient.HtmlUnitBrowserCompatCookieSpec;
90  import org.htmlunit.javascript.HtmlUnitScriptable;
91  import org.htmlunit.javascript.JavaScriptEngine;
92  import org.htmlunit.javascript.configuration.JsxClass;
93  import org.htmlunit.javascript.configuration.JsxConstructor;
94  import org.htmlunit.javascript.configuration.JsxFunction;
95  import org.htmlunit.javascript.configuration.JsxGetter;
96  import org.htmlunit.javascript.configuration.JsxSetter;
97  import org.htmlunit.javascript.host.Element;
98  import org.htmlunit.javascript.host.FontFaceSet;
99  import org.htmlunit.javascript.host.Location;
100 import org.htmlunit.javascript.host.NativeFunctionPrefixResolver;
101 import org.htmlunit.javascript.host.Window;
102 import org.htmlunit.javascript.host.animations.AnimationEvent;
103 import org.htmlunit.javascript.host.css.StyleSheetList;
104 import org.htmlunit.javascript.host.dom.AbstractList.EffectOnCache;
105 import org.htmlunit.javascript.host.event.BeforeUnloadEvent;
106 import org.htmlunit.javascript.host.event.CloseEvent;
107 import org.htmlunit.javascript.host.event.CompositionEvent;
108 import org.htmlunit.javascript.host.event.CustomEvent;
109 import org.htmlunit.javascript.host.event.DragEvent;
110 import org.htmlunit.javascript.host.event.Event;
111 import org.htmlunit.javascript.host.event.FocusEvent;
112 import org.htmlunit.javascript.host.event.HashChangeEvent;
113 import org.htmlunit.javascript.host.event.KeyboardEvent;
114 import org.htmlunit.javascript.host.event.MessageEvent;
115 import org.htmlunit.javascript.host.event.MouseEvent;
116 import org.htmlunit.javascript.host.event.MutationEvent;
117 import org.htmlunit.javascript.host.event.PointerEvent;
118 import org.htmlunit.javascript.host.event.PopStateEvent;
119 import org.htmlunit.javascript.host.event.ProgressEvent;
120 import org.htmlunit.javascript.host.event.TextEvent;
121 import org.htmlunit.javascript.host.event.UIEvent;
122 import org.htmlunit.javascript.host.event.WheelEvent;
123 import org.htmlunit.javascript.host.file.Blob;
124 import org.htmlunit.javascript.host.html.HTMLAllCollection;
125 import org.htmlunit.javascript.host.html.HTMLBodyElement;
126 import org.htmlunit.javascript.host.html.HTMLCollection;
127 import org.htmlunit.javascript.host.html.HTMLElement;
128 import org.htmlunit.javascript.host.html.HTMLFrameSetElement;
129 import org.htmlunit.util.Cookie;
130 import org.htmlunit.util.UrlUtils;
131 import org.htmlunit.xpath.xml.utils.PrefixResolver;
132 import org.w3c.dom.CDATASection;
133 import org.w3c.dom.DOMException;
134 import org.w3c.dom.DocumentType;
135 import org.w3c.dom.ProcessingInstruction;
136 
137 /**
138  * A JavaScript object for {@code Document}.
139  *
140  * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
141  * @author David K. Taylor
142  * @author <a href="mailto:chen_jun@users.sourceforge.net">Chen Jun</a>
143  * @author <a href="mailto:cse@dynabean.de">Christian Sell</a>
144  * @author Chris Erskine
145  * @author Marc Guillemot
146  * @author Daniel Gredler
147  * @author Michael Ottati
148  * @author <a href="mailto:george@murnock.com">George Murnock</a>
149  * @author Ahmed Ashour
150  * @author Rob Di Marco
151  * @author Ronald Brill
152  * @author Chuck Dumont
153  * @author Frank Danek
154  * @author Madis Pärn
155  * @author Lai Quang Duong
156  * @author Sven Strickroth
157  *
158  * @see <a href="http://msdn.microsoft.com/en-us/library/ms531073.aspx">MSDN documentation</a>
159  * @see <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-7068919">W3C Dom Level 1</a>
160  */
161 @JsxClass
162 public class Document extends Node {
163 
164     private static final Log LOG = LogFactory.getLog(Document.class);
165 
166     /** https://developer.mozilla.org/en/Rich-Text_Editing_in_Mozilla#Executing_Commands */
167     private static final Set<String> EXECUTE_CMDS_FF = new HashSet<>();
168     private static final Set<String> EXECUTE_CMDS_CHROME = new HashSet<>();
169     /** The formatter to use for the <code>lastModified</code> attribute. */
170     private static final DateTimeFormatter LAST_MODIFIED_DATE_FORMATTER
171                                             = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
172 
173     /** Contains all supported DOM level 2 events. */
174     private static final Map<String, Class<? extends Event>> SUPPORTED_DOM2_EVENT_TYPE_MAP;
175     /** Contains all supported DOM level 3 events. DOM level 2 events are not included. */
176     private static final Map<String, Class<? extends Event>> SUPPORTED_DOM3_EVENT_TYPE_MAP;
177     /** Contains all supported vendor specific events. */
178     private static final Map<String, Class<? extends Event>> SUPPORTED_VENDOR_EVENT_TYPE_MAP;
179 
180     /*
181       Initializes the supported event type map.
182       Map<String, Class> which maps strings a caller may use when calling into
183       {@link #createEvent(String)} to the associated event class. To support a new
184       event creation type, the event type and associated class need to be added into this map in
185       the static initializer. The map is unmodifiable. Any class that is a value in this map MUST
186       have a no-arg constructor.
187      */
188     static {
189         final Map<String, Class<? extends Event>> dom2EventMap = new HashMap<>();
190         dom2EventMap.put("HTMLEvents", Event.class);
191         dom2EventMap.put("MouseEvents", MouseEvent.class);
192         dom2EventMap.put("MutationEvents", MutationEvent.class);
193         dom2EventMap.put("UIEvents", UIEvent.class);
194         SUPPORTED_DOM2_EVENT_TYPE_MAP = Collections.unmodifiableMap(dom2EventMap);
195 
196         final Map<String, Class<? extends Event>> dom3EventMap = new HashMap<>();
197         dom3EventMap.put("Event", Event.class);
198         dom3EventMap.put("KeyboardEvent", KeyboardEvent.class);
199         dom3EventMap.put("MouseEvent", MouseEvent.class);
200         dom3EventMap.put("MessageEvent", MessageEvent.class);
201         dom3EventMap.put("MutationEvent", MutationEvent.class);
202         dom3EventMap.put("UIEvent", UIEvent.class);
203         dom3EventMap.put("CustomEvent", CustomEvent.class);
204         dom3EventMap.put("CloseEvent", CloseEvent.class);
205         dom3EventMap.put("CompositionEvent", CompositionEvent.class);
206         dom3EventMap.put("DragEvent", DragEvent.class);
207         dom3EventMap.put("TextEvent", TextEvent.class);
208         SUPPORTED_DOM3_EVENT_TYPE_MAP = Collections.unmodifiableMap(dom3EventMap);
209 
210         final Map<String, Class<? extends Event>> additionalEventMap = new HashMap<>();
211         additionalEventMap.put("BeforeUnloadEvent", BeforeUnloadEvent.class);
212         additionalEventMap.put("Events", Event.class);
213         additionalEventMap.put("HashChangeEvent", HashChangeEvent.class);
214         additionalEventMap.put("KeyEvents", KeyboardEvent.class);
215         additionalEventMap.put("PointerEvent", PointerEvent.class);
216         additionalEventMap.put("PopStateEvent", PopStateEvent.class);
217         additionalEventMap.put("ProgressEvent", ProgressEvent.class);
218         additionalEventMap.put("FocusEvent", FocusEvent.class);
219         additionalEventMap.put("WheelEvent", WheelEvent.class);
220         additionalEventMap.put("AnimationEvent", AnimationEvent.class);
221         SUPPORTED_VENDOR_EVENT_TYPE_MAP = Collections.unmodifiableMap(additionalEventMap);
222     }
223 
224     private Window window_;
225     private DOMImplementation implementation_;
226     private String designMode_;
227     private String compatMode_;
228     private int documentMode_ = -1;
229     private String domain_;
230     private String lastModified_;
231     private ScriptableObject currentScript_;
232     private transient FontFaceSet fonts_;
233     private transient StyleSheetList styleSheetList_;
234 
235     private final Map<String, Blob> blobUrl2Blobs_ = new HashMap<>();
236 
237     static {
238         // commands
239         String[] cmds = {
240             "BackColor", "BackgroundImageCache" /* Undocumented */,
241             "Bold",
242             "CreateLink", "Delete",
243             "FontName", "FontSize", "ForeColor", "FormatBlock",
244             "Indent", "InsertHorizontalRule", "InsertImage",
245             "InsertOrderedList", "InsertParagraph", "InsertUnorderedList",
246             "Italic", "JustifyCenter", "JustifyFull", "JustifyLeft", "JustifyNone",
247             "JustifyRight",
248             "Outdent",
249             "Print",
250             "Redo", "RemoveFormat",
251             "SelectAll", "StrikeThrough", "Subscript", "Superscript",
252             "Underline", "Undo", "Unlink", "Unselect"
253         };
254         for (final String cmd : cmds) {
255             if (!"Bold".equals(cmd)) {
256                 EXECUTE_CMDS_CHROME.add(cmd.toLowerCase(Locale.ROOT));
257             }
258         }
259 
260         cmds = new String[] {
261             "backColor", "bold", "contentReadOnly", "copy", "createLink", "cut", "decreaseFontSize", "delete",
262             "fontName", "fontSize", "foreColor", "formatBlock", "heading", "hiliteColor", "increaseFontSize",
263             "indent", "insertHorizontalRule", "insertHTML", "insertImage", "insertOrderedList", "insertUnorderedList",
264             "insertParagraph", "italic",
265             "justifyCenter", "JustifyFull", "justifyLeft", "justifyRight", "outdent", "paste", "redo",
266             "removeFormat", "selectAll", "strikeThrough", "subscript", "superscript", "underline", "undo", "unlink",
267             "useCSS", "styleWithCSS"
268         };
269         for (final String cmd : cmds) {
270             EXECUTE_CMDS_FF.add(cmd.toLowerCase(Locale.ROOT));
271             if (!"bold".equals(cmd)) {
272                 EXECUTE_CMDS_CHROME.add(cmd.toLowerCase(Locale.ROOT));
273             }
274         }
275     }
276 
277     /**
278      * JavaScript constructor.
279      */
280     @Override
281     @JsxConstructor
282     public void jsConstructor() {
283         throw JavaScriptEngine.typeErrorIllegalConstructor();
284     }
285 
286     /**
287      * Sets the Window JavaScript object that encloses this document.
288      * @param window the Window JavaScript object that encloses this document
289      */
290     public void setWindow(final Window window) {
291         window_ = window;
292     }
293 
294     /**
295      * Returns the value of the {@code location} property.
296      * @return the value of the {@code location} property
297      */
298     @JsxGetter
299     public Location getLocation() {
300         if (window_ == null) {
301             return null;
302         }
303         return window_.getLocation();
304     }
305 
306     /**
307      * Sets the value of the {@code location} property. The location's default property is "href",
308      * so setting "document.location='http://www.sf.net'" is equivalent to setting
309      * "document.location.href='http://www.sf.net'".
310      * @see <a href="http://msdn.microsoft.com/en-us/library/ms535866.aspx">MSDN documentation</a>
311      * @param location the location to navigate to
312      * @throws IOException when location loading fails
313      */
314     @JsxSetter
315     public void setLocation(final String location) throws IOException {
316         window_.setLocation(location);
317     }
318 
319     /**
320      * Returns the value of the {@code referrer} property.
321      * @return the value of the {@code referrer} property
322      */
323     @JsxGetter
324     public String getReferrer() {
325         String referrer = "";
326         final WebResponse webResponse = getPage().getWebResponse();
327         if (webResponse != null) {
328             referrer = webResponse.getWebRequest().getAdditionalHeaders().get(HttpHeader.REFERER);
329             if (referrer == null) {
330                 referrer = "";
331             }
332         }
333         return referrer;
334     }
335 
336     /**
337      * Gets the JavaScript property {@code documentElement} for the document.
338      * @return the root node for the document
339      */
340     @JsxGetter
341     public Element getDocumentElement() {
342         final Object documentElement = getPage().getDocumentElement();
343         if (documentElement == null) {
344             // for instance with an XML document with parsing error
345             return null;
346         }
347         return (Element) getScriptableFor(documentElement);
348     }
349 
350     /**
351      * Gets the JavaScript property {@code rootElement}.
352      * @return the root node for the document
353      */
354     @JsxGetter
355     public Element getRootElement() {
356         return null;
357     }
358 
359     /**
360      * Gets the JavaScript property {@code doctype} for the document.
361      * @return the DocumentType of the document
362      */
363     @JsxGetter
364     public HtmlUnitScriptable getDoctype() {
365         final Object documentType = getPage().getDoctype();
366         if (documentType == null) {
367             return null;
368         }
369         return getScriptableFor(documentType);
370     }
371 
372     /**
373      * Returns a value which indicates whether or not the document can be edited.
374      * @return a value which indicates whether or not the document can be edited
375      */
376     @JsxGetter
377     public String getDesignMode() {
378         if (designMode_ == null) {
379             designMode_ = "off";
380         }
381         return designMode_;
382     }
383 
384     /**
385      * Sets a value which indicates whether or not the document can be edited.
386      * @param mode a value which indicates whether or not the document can be edited
387      */
388     @JsxSetter
389     public void setDesignMode(final String mode) {
390         if ("on".equalsIgnoreCase(mode)) {
391             designMode_ = "on";
392             final SgmlPage page = getPage();
393             if (page != null && page.isHtmlPage()
394                     && getBrowserVersion().hasFeature(JS_DOCUMENT_SELECTION_RANGE_COUNT)) {
395                 final HtmlPage htmlPage = (HtmlPage) page;
396                 final DomNode child = htmlPage.getBody().getFirstChild();
397                 final DomNode rangeNode = child == null ? htmlPage.getBody() : child;
398                 htmlPage.setSelectionRange(new SimpleRange(rangeNode, 0));
399             }
400         }
401         else if ("off".equalsIgnoreCase(mode)) {
402             designMode_ = "off";
403         }
404     }
405 
406     /**
407      * Returns the page that this document is modeling.
408      * @return the page that this document is modeling
409      */
410     public SgmlPage getPage() {
411         return (SgmlPage) getDomNodeOrDie();
412     }
413 
414     /**
415      * Gets the window in which this document is contained.
416      * @return the window
417      */
418     @JsxGetter
419     public Object getDefaultView() {
420         return getWindow();
421     }
422 
423     /**
424      * Creates a new document fragment.
425      * @return a newly created document fragment
426      */
427     @JsxFunction
428     public HtmlUnitScriptable createDocumentFragment() {
429         final DomDocumentFragment fragment = getDomNodeOrDie().getPage().createDocumentFragment();
430         final DocumentFragment node = new DocumentFragment();
431         node.setParentScope(getParentScope());
432         node.setPrototype(getPrototype(node.getClass()));
433         node.setDomNode(fragment);
434         return getScriptableFor(fragment);
435     }
436 
437     /**
438      * Creates a new HTML attribute with the specified name.
439      *
440      * @param attributeName the name of the attribute to create
441      * @return an attribute with the specified name
442      */
443     @JsxFunction
444     public Attr createAttribute(final String attributeName) {
445         return getPage().createAttribute(attributeName).getScriptableObject();
446     }
447 
448     /**
449      * Imports a node from another document to this document.
450      * The source node is not altered or removed from the original document;
451      * this method creates a new copy of the source node.
452      *
453      * @param importedNode the node to import
454      * @param deep Whether to recursively import the subtree under the specified node; or not
455      * @return the imported node that belongs to this Document
456      */
457     @JsxFunction
458     public HtmlUnitScriptable importNode(final Node importedNode, final boolean deep) {
459         DomNode domNode = importedNode.getDomNodeOrDie();
460         domNode = domNode.cloneNode(deep);
461         domNode.processImportNode(this);
462         for (final DomNode childNode : domNode.getDescendants()) {
463             childNode.processImportNode(this);
464         }
465         return domNode.getScriptableObject();
466     }
467 
468     /**
469      * Adopts a node from an external document.
470      * The node and its subtree is removed from the document it's in (if any),
471      * and its ownerDocument is changed to the current document.
472      * The node can then be inserted into the current document.
473      *
474      * @param externalNode the node from another document to be adopted
475      * @return the adopted node that can be used in the current document
476      */
477     @JsxFunction
478     public HtmlUnitScriptable adoptNode(final Node externalNode) {
479         externalNode.remove();
480         return importNode(externalNode, true);
481     }
482 
483     /**
484      * Returns the implementation object of the current document.
485      * @return implementation-specific object
486      */
487     @JsxGetter
488     public DOMImplementation getImplementation() {
489         if (implementation_ == null) {
490             implementation_ = new DOMImplementation();
491             implementation_.setParentScope(getWindow());
492             implementation_.setPrototype(getPrototype(implementation_.getClass()));
493         }
494         return implementation_;
495     }
496 
497     /**
498      * Adapts any DOM node to resolve namespaces so that an XPath expression can be easily
499      * evaluated relative to the context of the node where it appeared within the document.
500      * @param nodeResolver the node to be used as a context for namespace resolution
501      * @return an XPathNSResolver which resolves namespaces with respect to the definitions
502      *         in scope for a specified node
503      */
504     @JsxFunction
505     public XPathNSResolver createNSResolver(final Node nodeResolver) {
506         final XPathNSResolver resolver = new XPathNSResolver();
507         resolver.setElement(nodeResolver);
508         resolver.setParentScope(getWindow());
509         resolver.setPrototype(getPrototype(resolver.getClass()));
510         return resolver;
511     }
512 
513     /**
514      * Create a new DOM text node with the given data.
515      *
516      * @param newData the string value for the text node
517      * @return the new text node or NOT_FOUND if there is an error
518      */
519     @JsxFunction
520     public HtmlUnitScriptable createTextNode(final String newData) {
521         final DomNode domNode = new DomText(getDomNodeOrDie().getPage(), newData);
522         return makeScriptableFor(domNode);
523     }
524 
525     /**
526      * Creates a new Comment.
527      * @param comment the comment text
528      * @return the new Comment
529      */
530     @JsxFunction
531     public HtmlUnitScriptable createComment(final String comment) {
532         final DomNode domNode = new DomComment(getDomNodeOrDie().getPage(), comment);
533         return getScriptableFor(domNode);
534     }
535 
536     /**
537      * Evaluates an XPath expression string and returns a result of the specified type if possible.
538      * @param expression the XPath expression string to be parsed and evaluated
539      * @param contextNode the context node for the evaluation of this XPath expression
540      * @param resolver the resolver permits translation of all prefixes, including the XML namespace prefix,
541      *        within the XPath expression into appropriate namespace URIs.
542      * @param type If a specific type is specified, then the result will be returned as the corresponding type
543      * @param result the result object which may be reused and returned by this method
544      * @return the result of the evaluation of the XPath expression
545      */
546     @JsxFunction
547     public XPathResult evaluate(final String expression, final Node contextNode,
548             final Object resolver, final int type, final Object result) {
549         XPathResult xPathResult = null;
550         if (result instanceof XPathResult) {
551             xPathResult = (XPathResult) result;
552 
553             if (getBrowserVersion().hasFeature(JS_DOCUMENT_EVALUATE_RECREATES_RESULT)) {
554                 xPathResult = new XPathResult();
555                 xPathResult.setParentScope(getParentScope());
556                 xPathResult.setPrototype(getPrototype(xPathResult.getClass()));
557             }
558         }
559         else if (result == null
560                 || JavaScriptEngine.isUndefined(result)
561                 || result instanceof ScriptableObject) {
562             xPathResult = new XPathResult();
563             xPathResult.setParentScope(getParentScope());
564             xPathResult.setPrototype(getPrototype(xPathResult.getClass()));
565         }
566         else {
567             throw JavaScriptEngine.typeError("Argument 5 of Document.evaluate has to be an XPathResult or null.");
568         }
569 
570         try {
571             PrefixResolver prefixResolver = null;
572             if (resolver instanceof NativeFunction) {
573                 prefixResolver = new NativeFunctionPrefixResolver(
574                                             (NativeFunction) resolver, contextNode.getParentScope());
575             }
576             else if (resolver instanceof PrefixResolver) {
577                 prefixResolver = (PrefixResolver) resolver;
578             }
579             xPathResult.init(contextNode.getDomNodeOrDie().getByXPath(expression, prefixResolver), type);
580             return xPathResult;
581         }
582         catch (final Exception e) {
583             throw JavaScriptEngine.asJavaScriptException(
584                     getWindow(),
585                     "Failed to execute 'evaluate': " + e.getMessage(),
586                     org.htmlunit.javascript.host.dom.DOMException.SYNTAX_ERR);
587         }
588     }
589 
590     /**
591      * Creates a new element with the given tag name.
592      *
593      * @param tagName the tag name
594      * @return the new HTML element, or NOT_FOUND if the tag is not supported
595      */
596     @JsxFunction
597     public HtmlUnitScriptable createElement(final Object tagName) {
598         if (tagName == null || JavaScriptEngine.isUndefined(tagName)) {
599             final org.w3c.dom.Node element = getPage().createElement("unknown");
600             ((HtmlUnknownElement) element).markAsCreatedByJavascript();
601             return getScriptableFor(element);
602         }
603 
604         // https://dom.spec.whatwg.org/#dom-document-createelement
605         // NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D]
606         //                       | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF]
607         //                       | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
608         // NameChar      ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
609         // Name          ::= NameStartChar (NameChar)*
610 
611         // but i have no idea what the browsers are doing
612         // the following code is a wild guess that might be good enough for the moment
613         final String tagNameString = JavaScriptEngine.toString(tagName);
614         if (tagNameString.length() > 0) {
615             final int firstChar = tagNameString.charAt(0);
616             if (!(isLetter(firstChar)
617                     || ':' == firstChar
618                     || '_' == firstChar)) {
619                 if (LOG.isInfoEnabled()) {
620                     LOG.info("createElement: Provided string '" + tagNameString + "' contains an invalid character");
621                 }
622                 throw JavaScriptEngine.asJavaScriptException(
623                         getWindow(),
624                         "createElement: Provided string '" + tagNameString + "' contains an invalid character",
625                         org.htmlunit.javascript.host.dom.DOMException.INVALID_CHARACTER_ERR);
626             }
627             for (int i = 1; i < tagNameString.length(); i++) {
628                 final int c = tagNameString.charAt(i);
629                 if (!(Character.isLetterOrDigit(c)
630                         || ':' == c
631                         || '_' == c
632                         || '-' == c
633                         || '.' == c)) {
634                     if (LOG.isInfoEnabled()) {
635                         LOG.info("createElement: Provided string '"
636                                     + tagNameString + "' contains an invalid character");
637                     }
638                     throw JavaScriptEngine.asJavaScriptException(
639                             getWindow(),
640                             "createElement: Provided string '" + tagNameString
641                                 + "' contains an invalid character",
642                             org.htmlunit.javascript.host.dom.DOMException.INVALID_CHARACTER_ERR);
643                 }
644             }
645         }
646 
647         org.w3c.dom.Node element = getPage().createElement(tagNameString);
648 
649         if (element instanceof HtmlImage) {
650             ((HtmlImage) element).markAsCreatedByJavascript();
651         }
652         else if (element instanceof HtmlRb) {
653             ((HtmlRb) element).markAsCreatedByJavascript();
654         }
655         else if (element instanceof HtmlRp) {
656             ((HtmlRp) element).markAsCreatedByJavascript();
657         }
658         else if (element instanceof HtmlRt) {
659             ((HtmlRt) element).markAsCreatedByJavascript();
660         }
661         else if (element instanceof HtmlRtc) {
662             ((HtmlRtc) element).markAsCreatedByJavascript();
663         }
664         else if (element instanceof HtmlUnknownElement) {
665             ((HtmlUnknownElement) element).markAsCreatedByJavascript();
666         }
667         else if (element instanceof HtmlSvg) {
668             element = UnknownElementFactory.INSTANCE.createElementNS(getPage(), "", "svg", null);
669             ((HtmlUnknownElement) element).markAsCreatedByJavascript();
670         }
671         final HtmlUnitScriptable jsElement = getScriptableFor(element);
672 
673         if (jsElement == NOT_FOUND) {
674             if (LOG.isDebugEnabled()) {
675                 LOG.debug("createElement(" + tagName
676                     + ") cannot return a result as there isn't a JavaScript object for the element "
677                     + element.getClass().getName());
678             }
679         }
680         return jsElement;
681     }
682 
683     // our version of the Character.isLetter() without MODIFIER_LETTER
684     private static boolean isLetter(final int codePoint) {
685         return ((((1 << Character.UPPERCASE_LETTER)
686                     | (1 << Character.LOWERCASE_LETTER)
687                     | (1 << Character.TITLECASE_LETTER)
688                     | (1 << Character.OTHER_LETTER)
689                 ) >> Character.getType(codePoint)) & 1) != 0;
690     }
691 
692     /**
693      * Creates a new HTML element with the given tag name, and name.
694      *
695      * @param namespaceURI the URI that identifies an XML namespace
696      * @param qualifiedName the qualified name of the element type to instantiate
697      * @return the new HTML element, or NOT_FOUND if the tag is not supported
698      */
699     @JsxFunction
700     public HtmlUnitScriptable createElementNS(final String namespaceURI, final String qualifiedName) {
701         if ("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul".equals(namespaceURI)) {
702             throw JavaScriptEngine.typeError("XUL not available");
703         }
704 
705         final org.w3c.dom.Element element;
706         if (Html.XHTML_NAMESPACE.equals(namespaceURI)
707                 || Html.SVG_NAMESPACE.equals(namespaceURI)) {
708             element = getPage().createElementNS(namespaceURI, qualifiedName);
709         }
710         else {
711             element = new DomElement(namespaceURI, qualifiedName, getPage(), null);
712         }
713         return getScriptableFor(element);
714     }
715 
716     /**
717      * Returns all the descendant elements with the specified tag name.
718      * @param tagName the name to search for
719      * @return all the descendant elements with the specified tag name
720      */
721     @JsxFunction
722     public HTMLCollection getElementsByTagName(final String tagName) {
723         final HTMLCollection collection = new HTMLCollection(getDomNodeOrDie(), false);
724 
725         if (org.htmlunit.util.StringUtils.equalsChar('*', tagName)) {
726             collection.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> true);
727         }
728         else {
729             collection.setIsMatchingPredicate(
730                     (Predicate<DomNode> & Serializable)
731                     node -> tagName.equalsIgnoreCase(node.getNodeName()));
732         }
733 
734         return collection;
735     }
736 
737     /**
738      * Returns a list of elements with the given tag name belonging to the given namespace.
739      * @param namespaceURI the namespace URI of elements to look for
740      * @param localName is either the local name of elements to look for or the special value "*",
741      *                  which matches all elements.
742      * @return a live NodeList of found elements in the order they appear in the tree
743      */
744     @JsxFunction
745     public HTMLCollection getElementsByTagNameNS(final Object namespaceURI, final String localName) {
746         final HTMLCollection elements = new HTMLCollection(getDomNodeOrDie(), false);
747         elements.setIsMatchingPredicate(
748                 (Predicate<DomNode> & Serializable)
749                 node -> localName.equals(node.getLocalName()));
750         return elements;
751     }
752 
753     /**
754      * Returns the value of the {@code activeElement} property.
755      * @see <a href="http://msdn.microsoft.com/en-us/library/ms533065.aspx">MSDN documentation</a>
756      * @return the value of the {@code activeElement} property
757      */
758     @JsxGetter
759     public Object getActiveElement() {
760         return null;
761     }
762 
763     /**
764      * Returns the character encoding of the current document.
765      * @return the character encoding of the current document
766      */
767     @JsxGetter
768     public String getCharacterSet() {
769         if (!(getPage() instanceof HtmlPage)) {
770             // TODO: implement XmlPage.getCharset
771             return "";
772         }
773         return getPage().getCharset().name();
774     }
775 
776     /**
777      * Retrieves the character set used to encode the document.
778      * @return the character set used to encode the document
779      */
780     @JsxGetter
781     public String getCharset() {
782         if (!(getPage() instanceof HtmlPage)) {
783             // TODO: implement XmlPage.getCharset
784             return "";
785         }
786         return getPage().getCharset().name();
787     }
788 
789     /**
790      * Returns the value of the JavaScript property {@code anchors}.
791      * @see <a href="http://msdn.microsoft.com/en-us/library/ms537435.aspx">MSDN documentation</a>
792      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_doc_ref4.html#1024543">
793      * Gecko DOM reference</a>
794      * @return the value of this property
795      */
796     @JsxGetter
797     public HTMLCollection getAnchors() {
798         final HTMLCollection anchors = new HTMLCollection(getDomNodeOrDie(), true);
799 
800         anchors.setIsMatchingPredicate(
801                 (Predicate<DomNode> & Serializable)
802                 node -> {
803                     if (!(node instanceof HtmlAnchor)) {
804                         return false;
805                     }
806                     final HtmlAnchor anchor = (HtmlAnchor) node;
807                     return anchor.hasAttribute(DomElement.NAME_ATTRIBUTE);
808                 });
809 
810         anchors.setEffectOnCacheFunction(
811                 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
812                     event -> {
813                         if (DomElement.NAME_ATTRIBUTE.equals(event.getName())
814                                 || DomElement.ID_ATTRIBUTE.equals(event.getName())) {
815                             return EffectOnCache.RESET;
816                         }
817                         return EffectOnCache.NONE;
818                     });
819 
820         return anchors;
821     }
822 
823     /**
824      * Returns the value of the JavaScript property {@code applets}.
825      * @see <a href="http://msdn.microsoft.com/en-us/library/ms537436.aspx">
826      * MSDN documentation</a>
827      * @see <a href="https://developer.mozilla.org/En/DOM:document.applets">
828      * Gecko DOM reference</a>
829      * @return the value of this property
830      */
831     @JsxGetter
832     public HTMLCollection getApplets() {
833         return new HTMLCollection(getDomNodeOrDie(), false);
834     }
835 
836     /**
837      * Returns this document's {@code body} element.
838      * @return this document's {@code body} element
839      */
840     @JsxGetter
841     public HTMLElement getBody() {
842         final Page page = getPage();
843         if (page instanceof HtmlPage) {
844             final HtmlPage htmlPage = (HtmlPage) page;
845             final HtmlElement body = htmlPage.getBody();
846             if (body != null) {
847                 return body.getScriptableObject();
848             }
849 
850             // strange but this returns the frameset element
851             final DomElement doc = htmlPage.getDocumentElement();
852             if (doc != null) {
853                 for (final DomNode node : doc.getChildren()) {
854                     if (node instanceof HtmlFrameSet) {
855                         return (HTMLElement) node.getScriptableObject();
856                     }
857                 }
858             }
859         }
860         return null;
861     }
862 
863     /**
864      * Sets the {@code body} element of the document.
865      * @param htmlElement the new html element
866      */
867     @JsxSetter
868     public void setBody(final HTMLElement htmlElement) {
869         if (htmlElement instanceof HTMLBodyElement || htmlElement instanceof HTMLFrameSetElement) {
870             final Page page = getPage();
871             if (page instanceof HtmlPage) {
872                 final HtmlElement body = ((HtmlPage) page).getBody();
873                 if (body != null) {
874                     body.replace(htmlElement.getDomNodeOrDie());
875                 }
876             }
877             return;
878         }
879         throw JavaScriptEngine.asJavaScriptException(
880                 getWindow(),
881                 "Failed to set the 'body' property on 'Document': "
882                         + "The new body element is of type '" +  htmlElement.getTagName() + "'. "
883                         + "It must be either a 'BODY' or 'FRAMESET' element.",
884                 org.htmlunit.javascript.host.dom.DOMException.HIERARCHY_REQUEST_ERR);
885     }
886 
887     /**
888      * JavaScript function {@code close}.
889      * <p>See <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/section-dynamic.html">
890      * http://www.whatwg.org/specs/web-apps/current-work/multipage/section-dynamic.html</a> for
891      * a good description of the semantics of open(), write(), writeln() and close().</p>
892      *
893      * @throws IOException if an IO problem occurs
894      */
895     @JsxFunction({CHROME, EDGE})
896     public void close() throws IOException {
897         // nothing to do
898     }
899 
900     /**
901      * Returns the {@code compatMode} property.
902      * @return the {@code compatMode} property
903      */
904     @JsxGetter
905     public String getCompatMode() {
906         // initialize the modes
907         getDocumentMode();
908         return compatMode_;
909     }
910 
911     /**
912      * Returns the {@code documentMode} property.
913      * @return the {@code documentMode} property
914      */
915     public int getDocumentMode() {
916         if (documentMode_ != -1) {
917             return documentMode_;
918         }
919 
920         compatMode_ = "CSS1Compat";
921 
922         if (isQuirksDocType()) {
923             compatMode_ = "BackCompat";
924         }
925 
926         final float version = getBrowserVersion().getBrowserVersionNumeric();
927         documentMode_ = (int) Math.floor(version);
928         return documentMode_;
929     }
930 
931     private boolean isQuirksDocType() {
932         final DocumentType docType = getPage().getDoctype();
933         if (docType != null) {
934             final String systemId = docType.getSystemId();
935             if (systemId != null) {
936                 if ("http://www.w3.org/TR/html4/strict.dtd".equals(systemId)) {
937                     return false;
938                 }
939 
940                 if ("http://www.w3.org/TR/html4/loose.dtd".equals(systemId)) {
941                     final String publicId = docType.getPublicId();
942                     if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicId)) {
943                         return false;
944                     }
945                 }
946 
947                 if ("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd".equals(systemId)
948                     || "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd".equals(systemId)) {
949                     return false;
950                 }
951             }
952             else if (docType.getPublicId() == null) {
953                 return docType.getName() == null;
954             }
955         }
956         return true;
957     }
958 
959     /**
960      * <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
961      *
962      * Called from the HTMLParser if a 'X-UA-Compatible' meta tag found.
963      * @param documentMode the mode forced by the meta tag
964      */
965     public void forceDocumentMode(final int documentMode) {
966         documentMode_ = documentMode;
967         compatMode_ = documentMode == 5 ? "BackCompat" : "CSS1Compat";
968     }
969 
970     /**
971      * Returns the first element within the document that matches the specified group of selectors.
972      * @param selectors the selectors
973      * @return null if no matches are found; otherwise, it returns the first matching element
974      */
975     @JsxFunction
976     public Node querySelector(final String selectors) {
977         try {
978             final DomNode node = getDomNodeOrDie().querySelector(selectors);
979             if (node != null) {
980                 return node.getScriptableObject();
981             }
982             return null;
983         }
984         catch (final CSSException e) {
985             throw JavaScriptEngine.asJavaScriptException(
986                     getWindow(),
987                     "An invalid or illegal selector was specified (selector: '"
988                             + selectors + "' error: " + e.getMessage() + ").",
989                     org.htmlunit.javascript.host.dom.DOMException.SYNTAX_ERR);
990         }
991     }
992 
993     /**
994      * Retrieves all element nodes from descendants of the starting element node that match any selector
995      * within the supplied selector strings.
996      * The NodeList object returned by the querySelectorAll() method must be static, not live.
997      * @param selectors the selectors
998      * @return the static node list
999      */
1000     @JsxFunction
1001     public NodeList querySelectorAll(final String selectors) {
1002         try {
1003             return NodeList.staticNodeList(this, getDomNodeOrDie().querySelectorAll(selectors));
1004         }
1005         catch (final CSSException e) {
1006             throw JavaScriptEngine.asJavaScriptException(
1007                     getWindow(),
1008                     "An invalid or illegal selector was specified (selector: '"
1009                             + selectors + "' error: " + e.getMessage() + ").",
1010                     org.htmlunit.javascript.host.dom.DOMException.SYNTAX_ERR);
1011         }
1012     }
1013 
1014     /**
1015      * Indicates if the command is supported.
1016      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms536681.aspx">MSDN documentation</a>
1017      * @param cmd the command identifier
1018      * @return {@code true} if the command is supported
1019      */
1020     @JsxFunction
1021     public boolean queryCommandSupported(final String cmd) {
1022         return hasCommand(cmd, true);
1023     }
1024 
1025     private boolean hasCommand(final String cmd, final boolean includeBold) {
1026         if (null == cmd) {
1027             return false;
1028         }
1029 
1030         final String cmdLC = cmd.toLowerCase(Locale.ROOT);
1031         if (getBrowserVersion().isChrome() || getBrowserVersion().isEdge()) {
1032             return EXECUTE_CMDS_CHROME.contains(cmdLC) || (includeBold && "bold".equalsIgnoreCase(cmd));
1033         }
1034         return EXECUTE_CMDS_FF.contains(cmdLC);
1035     }
1036 
1037     /**
1038      * Indicates if the command can be successfully executed using <code>execCommand</code>, given
1039      * the current state of the document.
1040      * @param cmd the command identifier
1041      * @return {@code true} if the command can be successfully executed
1042      */
1043     @JsxFunction
1044     public boolean queryCommandEnabled(final String cmd) {
1045         return hasCommand(cmd, true);
1046     }
1047 
1048     /**
1049      * Executes a command.
1050      * @see <a href="http://msdn2.microsoft.com/en-us/library/ms536419.aspx">MSDN documentation</a>
1051      * @param cmd the command identifier
1052      * @param userInterface display a user interface if the command supports one
1053      * @param value the string, number, or other value to assign (possible values depend on the command)
1054      * @return {@code true} if the command was successful, {@code false} otherwise
1055      */
1056     @JsxFunction
1057     public boolean execCommand(final String cmd, final boolean userInterface, final Object value) {
1058         if (!hasCommand(cmd, false)) {
1059             return false;
1060         }
1061         if (LOG.isWarnEnabled()) {
1062             LOG.warn("Nothing done for execCommand(" + cmd + ", ...) (feature not implemented)");
1063         }
1064         return true;
1065     }
1066 
1067     /**
1068      * Returns the value of the {@code URL} property.
1069      * @return the value of the {@code URL} property
1070      */
1071     @JsxGetter(propertyName = "URL")
1072     public String getURL_js() {
1073         return getPage().getUrl().toExternalForm();
1074     }
1075 
1076     /**
1077      * Returns the value of the {@code documentURI} property.
1078      * @return the value of the {@code documentURI} property
1079      */
1080     @JsxGetter
1081     public String getDocumentURI() {
1082         return getURL_js();
1083     }
1084 
1085     /**
1086      * Returns the {@code cookie} property.
1087      * @return the {@code cookie} property
1088      */
1089     @JsxGetter
1090     public String getCookie() {
1091         final SgmlPage sgmlPage = getPage();
1092 
1093         final StringBuilder builder = new StringBuilder();
1094         final Set<Cookie> cookies = sgmlPage.getWebClient().getCookies(sgmlPage.getUrl());
1095         for (final Cookie cookie : cookies) {
1096             if (cookie.isHttpOnly()) {
1097                 continue;
1098             }
1099             if (builder.length() != 0) {
1100                 builder.append("; ");
1101             }
1102             if (!HtmlUnitBrowserCompatCookieSpec.EMPTY_COOKIE_NAME.equals(cookie.getName())) {
1103                 builder.append(cookie.getName()).append('=');
1104             }
1105             builder.append(cookie.getValue());
1106         }
1107 
1108         return builder.toString();
1109     }
1110 
1111     /**
1112      * Adds a cookie, as long as cookies are enabled.
1113      * @see <a href="http://msdn.microsoft.com/en-us/library/ms533693.aspx">MSDN documentation</a>
1114      * @param newCookie in the format "name=value[;expires=date][;domain=domainname][;path=path][;secure]
1115      */
1116     @JsxSetter
1117     public void setCookie(final String newCookie) {
1118         final SgmlPage sgmlPage = getPage();
1119         final WebClient client = sgmlPage.getWebClient();
1120 
1121         if (StringUtils.isBlank(newCookie)
1122                 && client.getBrowserVersion().hasFeature(HTMLDOCUMENT_COOKIES_IGNORE_BLANK)) {
1123             return;
1124         }
1125         client.addCookie(newCookie, sgmlPage.getUrl(), this);
1126     }
1127 
1128     /**
1129      * Implementation of the {@link org.w3c.dom.events.DocumentEvent} interface's
1130      * {@link org.w3c.dom.events.DocumentEvent#createEvent(String)} method. The method creates an
1131      * uninitialized event of the specified type.
1132      *
1133      * @see <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-DocumentEvent">DocumentEvent</a>
1134      * @param eventType the event type to create
1135      * @return an event object for the specified type
1136      * @throws DOMException if the event type is not supported (will have a type of
1137      *         DOMException.NOT_SUPPORTED_ERR)
1138      */
1139     @JsxFunction
1140     public Event createEvent(final String eventType) throws DOMException {
1141         Class<? extends Event> clazz = SUPPORTED_DOM2_EVENT_TYPE_MAP.get(eventType);
1142         if (clazz == null) {
1143             clazz = SUPPORTED_DOM3_EVENT_TYPE_MAP.get(eventType);
1144             if (CloseEvent.class == clazz
1145                     && getBrowserVersion().hasFeature(EVENT_ONCLOSE_DOCUMENT_CREATE_NOT_SUPPORTED)) {
1146                 clazz = null;
1147             }
1148             else if (TextEvent.class == clazz
1149                     && !getBrowserVersion().hasFeature(EVENT_TYPE_TEXTEVENT)) {
1150                 clazz = CompositionEvent.class;
1151             }
1152         }
1153 
1154         if (MutationEvent.class == clazz
1155                 && !getBrowserVersion().hasFeature(EVENT_TYPE_MUTATIONEVENT)) {
1156             clazz = null;
1157         }
1158         else if (clazz == null
1159                 && ("Events".equals(eventType)
1160                     || "HashChangeEvent".equals(eventType)
1161                     || "BeforeUnloadEvent".equals(eventType)
1162                     || "PopStateEvent".equals(eventType)
1163                     || "FocusEvent".equals(eventType)
1164                     || "WheelEvent".equals(eventType)
1165                             && getBrowserVersion().hasFeature(EVENT_TYPE_WHEELEVENT)
1166                     || "AnimationEvent".equals(eventType))) {
1167             clazz = SUPPORTED_VENDOR_EVENT_TYPE_MAP.get(eventType);
1168 
1169             if (PopStateEvent.class == clazz
1170                     && getBrowserVersion().hasFeature(EVENT_ONPOPSTATE_DOCUMENT_CREATE_NOT_SUPPORTED)) {
1171                 clazz = null;
1172             }
1173             if (AnimationEvent.class == clazz
1174                     && getBrowserVersion().hasFeature(EVENT_ONANIMATION_DOCUMENT_CREATE_NOT_SUPPORTED)) {
1175                 clazz = null;
1176             }
1177         }
1178 
1179         if (clazz == null) {
1180             throw JavaScriptEngine.asJavaScriptException(
1181                     this,
1182                     "Event Type '" + eventType + "' is not supported.",
1183                     org.htmlunit.javascript.host.dom.DOMException.NOT_SUPPORTED_ERR);
1184         }
1185 
1186         try {
1187             final Event event = clazz.getDeclaredConstructor().newInstance();
1188             event.setParentScope(getWindow());
1189             event.setPrototype(getPrototype(clazz));
1190             event.eventCreated();
1191             return event;
1192         }
1193         catch (final InstantiationException | IllegalAccessException
1194                 | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
1195             throw JavaScriptEngine.reportRuntimeError("Failed to instantiate event: class ='" + clazz.getName()
1196                             + "' for event type of '" + eventType + "': " + e.getMessage());
1197         }
1198     }
1199 
1200     /**
1201      * Returns a new NodeIterator object.
1202      *
1203      * @param root The root node at which to begin the NodeIterator's traversal.
1204      * @param whatToShow an optional long representing a bitmask created by combining
1205      *        the constant properties of {@link NodeFilter}
1206      * @param filter an object implementing the {@link NodeFilter} interface
1207      * @return a new NodeIterator object
1208      */
1209     @JsxFunction
1210     public NodeIterator createNodeIterator(final Node root, final int whatToShow, final Scriptable filter) {
1211         final org.w3c.dom.traversal.NodeFilter filterWrapper = createFilterWrapper(filter, false);
1212         final NodeIterator iterator = new NodeIterator(root, whatToShow, filterWrapper);
1213         iterator.setParentScope(getParentScope());
1214         iterator.setPrototype(getPrototype(iterator.getClass()));
1215         return iterator;
1216     }
1217 
1218     private static org.w3c.dom.traversal.NodeFilter createFilterWrapper(final Scriptable filter,
1219             final boolean filterFunctionOnly) {
1220         org.w3c.dom.traversal.NodeFilter filterWrapper = null;
1221         if (filter != null) {
1222             filterWrapper = n -> {
1223                 final Object[] args = {((DomNode) n).getScriptableObject()};
1224                 final Object response;
1225                 if (filter instanceof Callable) {
1226                     response = ((Callable) filter).call(Context.getCurrentContext(), filter, filter, args);
1227                 }
1228                 else {
1229                     if (filterFunctionOnly) {
1230                         throw JavaScriptEngine.reportRuntimeError("only a function is allowed as filter");
1231                     }
1232                     response = ScriptableObject.callMethod(filter, "acceptNode", args);
1233                 }
1234                 return (short) JavaScriptEngine.toNumber(response);
1235             };
1236         }
1237         return filterWrapper;
1238     }
1239 
1240     /**
1241      * Creates and returns a new TreeWalker. The following JavaScript parameters are passed into this method:
1242      * <ul>
1243      *   <li>JavaScript param 1: The root node of the TreeWalker. Must not be {@code null}.</li>
1244      *   <li>JavaScript param 2: Flag specifying which types of nodes appear in the logical view of the TreeWalker.
1245      *       See {@link NodeFilter} for the set of possible Show_ values.</li>
1246      *   <li>JavaScript param 3: The {@link NodeFilter} to be used with this TreeWalker, or {@code null}
1247      *       to indicate no filter.</li>
1248      *   <li>JavaScript param 4: If {@code false}, the contents of EntityReference nodes are not present
1249      *       in the logical view.</li>
1250      * </ul>
1251      *
1252      * @see <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html">DOM-Level-2-Traversal-Range</a>
1253      * @param root the node which will serve as the root for the TreeWalker
1254      * @param whatToShow specifies which node types may appear in the logical view of the tree presented
1255      * @param filter the NodeFilter to be used with this TreeWalker, or null to indicate no filter
1256      * @param expandEntityReferences If false,
1257      *        the contents of EntityReference nodes are not presented in the logical view
1258      * @throws DOMException on attempt to create a TreeWalker with a root that is {@code null}
1259      * @return a new TreeWalker
1260      */
1261     @JsxFunction
1262     public TreeWalker createTreeWalker(final Node root, final double whatToShow, final Scriptable filter,
1263             boolean expandEntityReferences) throws DOMException {
1264 
1265         // seems that Rhino doesn't like long as parameter type
1266         // this strange conversation preserves NodeFilter.SHOW_ALL
1267         final int whatToShowI = (int) Double.valueOf(whatToShow).longValue();
1268 
1269         expandEntityReferences = false;
1270 
1271         final org.w3c.dom.traversal.NodeFilter filterWrapper = createFilterWrapper(filter, false);
1272         final TreeWalker t = new TreeWalker(root, whatToShowI, filterWrapper, expandEntityReferences);
1273         t.setParentScope(getWindow(this));
1274         t.setPrototype(staticGetPrototype(getWindow(this), TreeWalker.class));
1275         return t;
1276     }
1277 
1278     @SuppressWarnings("unchecked")
1279     private static Scriptable staticGetPrototype(final Window window,
1280             final Class<? extends HtmlUnitScriptable> javaScriptClass) {
1281         final Scriptable prototype = window.getPrototype(javaScriptClass);
1282         if (prototype == null && javaScriptClass != HtmlUnitScriptable.class) {
1283             return staticGetPrototype(window, (Class<? extends HtmlUnitScriptable>) javaScriptClass.getSuperclass());
1284         }
1285         return prototype;
1286     }
1287 
1288     /**
1289      * Creates and returns a new range.
1290      * @return a new range
1291      * @see <a href="http://www.xulplanet.com/references/objref/HTMLDocument.html#method_createRange">XUL Planet</a>
1292      */
1293     @JsxFunction
1294     public Range createRange() {
1295         final Range range = new Range(this);
1296         range.setParentScope(getWindow());
1297         range.setPrototype(getPrototype(Range.class));
1298         return range;
1299     }
1300 
1301     /**
1302      * Returns the domain name of the server that served the document, or {@code null} if the server
1303      * cannot be identified by a domain name.
1304      * @return the domain name of the server that served the document
1305      * @see <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-2250147">
1306      * W3C documentation</a>
1307      */
1308     @JsxGetter
1309     public String getDomain() {
1310         if (domain_ == null && getPage().getWebResponse() != null) {
1311             URL url = getPage().getUrl();
1312             if (url == UrlUtils.URL_ABOUT_BLANK) {
1313                 final WebWindow w = getWindow().getWebWindow();
1314                 if (w instanceof FrameWindow) {
1315                     url = ((FrameWindow) w).getEnclosingPage().getUrl();
1316                 }
1317                 else {
1318                     return null;
1319                 }
1320             }
1321             domain_ = url.getHost().toLowerCase(Locale.ROOT);
1322         }
1323 
1324         return domain_;
1325     }
1326 
1327     /**
1328      * Sets the domain of this document.
1329      *
1330      * <p>Domains can only be set to suffixes of the existing domain
1331      * with the exception of setting the domain to itself.</p>
1332      * <p>
1333      * The domain will be set according to the following rules:
1334      * <ol>
1335      * <li>If the newDomain.equalsIgnoreCase(currentDomain) the method returns with no error.</li>
1336      * <li>If the browser version is netscape, the newDomain is downshifted.</li>
1337      * <li>The change will take place if and only if the suffixes of the
1338      *       current domain and the new domain match AND there are at least
1339      *       two domain qualifiers e.g. the following transformations are legal
1340      *       d1.d2.d3.gargoylesoftware.com may be transformed to itself or:
1341      *          d2.d3.gargoylesoftware.com
1342      *             d3.gargoylesoftware.com
1343      *                gargoylesoftware.com
1344      * <p>
1345      *        transformation to:        com
1346      *        will fail
1347      * </li>
1348      * </ol>
1349      * <p>
1350      * TODO This code could be modified to understand country domain suffixes.
1351      * The domain www.bbc.co.uk should be trimmable only down to bbc.co.uk
1352      * trimming to co.uk should not be possible.
1353      * @param newDomain the new domain to set
1354      */
1355     @JsxSetter
1356     public void setDomain(String newDomain) {
1357         newDomain = newDomain.toLowerCase(Locale.ROOT);
1358 
1359         final String currentDomain = getDomain();
1360         if (currentDomain.equalsIgnoreCase(newDomain)) {
1361             return;
1362         }
1363 
1364         if (newDomain.indexOf('.') == -1) {
1365             throw JavaScriptEngine.reportRuntimeError("Illegal domain value, cannot set domain from: \""
1366                     + currentDomain + "\" to: \"" + newDomain + "\" (new domain has to contain a dot).");
1367         }
1368 
1369         if (currentDomain.indexOf('.') > -1
1370                 && !currentDomain.toLowerCase(Locale.ROOT).endsWith("." + newDomain.toLowerCase(Locale.ROOT))) {
1371             throw JavaScriptEngine.reportRuntimeError("Illegal domain value, cannot set domain from: \""
1372                     + currentDomain + "\" to: \"" + newDomain + "\"");
1373         }
1374 
1375         domain_ = newDomain;
1376     }
1377 
1378     /**
1379      * Sets the {@code onclick} event handler for this element.
1380      * @param handler the {@code onclick} event handler for this element
1381      */
1382     @JsxSetter
1383     public void setOnclick(final Object handler) {
1384         setEventHandler(MouseEvent.TYPE_CLICK, handler);
1385     }
1386 
1387     /**
1388      * Returns the {@code onclick} event handler for this element.
1389      * @return the {@code onclick} event handler for this element
1390      */
1391     @JsxGetter
1392     public Function getOnclick() {
1393         return getEventHandler(MouseEvent.TYPE_CLICK);
1394     }
1395 
1396     /**
1397      * Sets the {@code ondblclick} event handler for this element.
1398      * @param handler the {@code ondblclick} event handler for this element
1399      */
1400     @JsxSetter
1401     public void setOndblclick(final Object handler) {
1402         setEventHandler(MouseEvent.TYPE_DBL_CLICK, handler);
1403     }
1404 
1405     /**
1406      * Returns the {@code ondblclick} event handler for this element.
1407      * @return the {@code ondblclick} event handler for this element
1408      */
1409     @JsxGetter
1410     public Function getOndblclick() {
1411         return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
1412     }
1413 
1414     /**
1415      * Sets the {@code onblur} event handler for this element.
1416      * @param handler the {@code onblur} event handler for this element
1417      */
1418     @JsxSetter
1419     public void setOnblur(final Object handler) {
1420         setEventHandler(Event.TYPE_BLUR, handler);
1421     }
1422 
1423     /**
1424      * Returns the {@code onblur} event handler for this element.
1425      * @return the {@code onblur} event handler for this element
1426      */
1427     @JsxGetter
1428     public Function getOnblur() {
1429         return getEventHandler(Event.TYPE_BLUR);
1430     }
1431 
1432     /**
1433      * Sets the {@code onfocus} event handler for this element.
1434      * @param handler the {@code onfocus} event handler for this element
1435      */
1436     @JsxSetter
1437     public void setOnfocus(final Object handler) {
1438         setEventHandler(Event.TYPE_FOCUS, handler);
1439     }
1440 
1441     /**
1442      * Returns the {@code onfocus} event handler for this element.
1443      * @return the {@code onfocus} event handler for this element
1444      */
1445     @JsxGetter
1446     public Function getOnfocus() {
1447         return getEventHandler(Event.TYPE_FOCUS);
1448     }
1449 
1450     /**
1451      * Sets the {@code onkeydown} event handler for this element.
1452      * @param handler the {@code onkeydown} event handler for this element
1453      */
1454     @JsxSetter
1455     public void setOnkeydown(final Object handler) {
1456         setEventHandler(Event.TYPE_KEY_DOWN, handler);
1457     }
1458 
1459     /**
1460      * Returns the {@code onkeydown} event handler for this element.
1461      * @return the {@code onkeydown} event handler for this element
1462      */
1463     @JsxGetter
1464     public Function getOnkeydown() {
1465         return getEventHandler(Event.TYPE_KEY_DOWN);
1466     }
1467 
1468     /**
1469      * Sets the {@code onkeypress} event handler for this element.
1470      * @param handler the {@code onkeypress} event handler for this element
1471      */
1472     @JsxSetter
1473     public void setOnkeypress(final Object handler) {
1474         setEventHandler(Event.TYPE_KEY_PRESS, handler);
1475     }
1476 
1477     /**
1478      * Returns the {@code onkeypress} event handler for this element.
1479      * @return the {@code onkeypress} event handler for this element
1480      */
1481     @JsxGetter
1482     public Function getOnkeypress() {
1483         return getEventHandler(Event.TYPE_KEY_PRESS);
1484     }
1485 
1486     /**
1487      * Sets the {@code onkeyup} event handler for this element.
1488      * @param handler the {@code onkeyup} event handler for this element
1489      */
1490     @JsxSetter
1491     public void setOnkeyup(final Object handler) {
1492         setEventHandler(Event.TYPE_KEY_UP, handler);
1493     }
1494 
1495     /**
1496      * Returns the {@code onkeyup} event handler for this element.
1497      * @return the {@code onkeyup} event handler for this element
1498      */
1499     @JsxGetter
1500     public Function getOnkeyup() {
1501         return getEventHandler(Event.TYPE_KEY_UP);
1502     }
1503 
1504     /**
1505      * Sets the {@code onmousedown} event handler for this element.
1506      * @param handler the {@code onmousedown} event handler for this element
1507      */
1508     @JsxSetter
1509     public void setOnmousedown(final Object handler) {
1510         setEventHandler(MouseEvent.TYPE_MOUSE_DOWN, handler);
1511     }
1512 
1513     /**
1514      * Returns the {@code onmousedown} event handler for this element.
1515      * @return the {@code onmousedown} event handler for this element
1516      */
1517     @JsxGetter
1518     public Function getOnmousedown() {
1519         return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
1520     }
1521 
1522     /**
1523      * Sets the {@code onmousemove} event handler for this element.
1524      * @param handler the {@code onmousemove} event handler for this element
1525      */
1526     @JsxSetter
1527     public void setOnmousemove(final Object handler) {
1528         setEventHandler(MouseEvent.TYPE_MOUSE_MOVE, handler);
1529     }
1530 
1531     /**
1532      * Returns the {@code onmousemove} event handler for this element.
1533      * @return the {@code onmousemove} event handler for this element
1534      */
1535     @JsxGetter
1536     public Function getOnmousemove() {
1537         return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
1538     }
1539 
1540     /**
1541      * Sets the {@code onmouseout} event handler for this element.
1542      * @param handler the {@code onmouseout} event handler for this element
1543      */
1544     @JsxSetter
1545     public void setOnmouseout(final Object handler) {
1546         setEventHandler(MouseEvent.TYPE_MOUSE_OUT, handler);
1547     }
1548 
1549     /**
1550      * Returns the {@code onmouseout} event handler for this element.
1551      * @return the {@code onmouseout} event handler for this element
1552      */
1553     @JsxGetter
1554     public Function getOnmouseout() {
1555         return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
1556     }
1557 
1558     /**
1559      * Sets the {@code onmouseover} event handler for this element.
1560      * @param handler the {@code onmouseover} event handler for this element
1561      */
1562     @JsxSetter
1563     public void setOnmouseover(final Object handler) {
1564         setEventHandler(MouseEvent.TYPE_MOUSE_OVER, handler);
1565     }
1566 
1567     /**
1568      * Returns the {@code onmouseover} event handler for this element.
1569      * @return the {@code onmouseover} event handler for this element
1570      */
1571     @JsxGetter
1572     public Function getOnmouseover() {
1573         return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
1574     }
1575 
1576     /**
1577      * Sets the {@code onmouseup} event handler for this element.
1578      * @param handler the {@code onmouseup} event handler for this element
1579      */
1580     @JsxSetter
1581     public void setOnmouseup(final Object handler) {
1582         setEventHandler(MouseEvent.TYPE_MOUSE_UP, handler);
1583     }
1584 
1585     /**
1586      * Returns the {@code onmouseup} event handler for this element.
1587      * @return the {@code onmouseup} event handler for this element
1588      */
1589     @JsxGetter
1590     public Function getOnmouseup() {
1591         return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
1592     }
1593 
1594     /**
1595      * Sets the {@code oncontextmenu} event handler for this element.
1596      * @param handler the {@code oncontextmenu} event handler for this element
1597      */
1598     @JsxSetter
1599     public void setOncontextmenu(final Object handler) {
1600         setEventHandler(MouseEvent.TYPE_CONTEXT_MENU, handler);
1601     }
1602 
1603     /**
1604      * Returns the {@code oncontextmenu} event handler for this element.
1605      * @return the {@code oncontextmenu} event handler for this element
1606      */
1607     @JsxGetter
1608     public Function getOncontextmenu() {
1609         return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
1610     }
1611 
1612     /**
1613      * Sets the {@code onresize} event handler for this element.
1614      * @param handler the {@code onresize} event handler for this element
1615      */
1616     @JsxSetter
1617     public void setOnresize(final Object handler) {
1618         setEventHandler(Event.TYPE_RESIZE, handler);
1619     }
1620 
1621     /**
1622      * Returns the {@code onresize} event handler for this element.
1623      * @return the {@code onresize} event handler for this element
1624      */
1625     @JsxGetter
1626     public Function getOnresize() {
1627         return getEventHandler(Event.TYPE_RESIZE);
1628     }
1629 
1630     /**
1631      * Sets the {@code onerror} event handler for this element.
1632      * @param handler the {@code onerror} event handler for this element
1633      */
1634     @JsxSetter
1635     public void setOnerror(final Object handler) {
1636         setEventHandler(Event.TYPE_ERROR, handler);
1637     }
1638 
1639     /**
1640      * Returns the {@code onerror} event handler for this element.
1641      * @return the {@code onerror} event handler for this element
1642      */
1643     @JsxGetter
1644     public Function getOnerror() {
1645         return getEventHandler(Event.TYPE_ERROR);
1646     }
1647 
1648     /**
1649      * Returns the {@code oninput} event handler for this element.
1650      * @return the {@code oninput} event handler for this element
1651      */
1652     @JsxGetter
1653     public Function getOninput() {
1654         return getEventHandler(Event.TYPE_INPUT);
1655     }
1656 
1657     /**
1658      * Sets the {@code oninput} event handler for this element.
1659      * @param oninput the {@code oninput} event handler for this element
1660      */
1661     @JsxSetter
1662     public void setOninput(final Object oninput) {
1663         setEventHandler(Event.TYPE_INPUT, oninput);
1664     }
1665 
1666     /**
1667      * Returns the {@code hidden} property.
1668      * @return the {@code hidden} property
1669      */
1670     @JsxGetter
1671     public boolean getHidden() {
1672         return false;
1673     }
1674 
1675     /**
1676      * {@inheritDoc}
1677      */
1678     @Override
1679     @JsxGetter
1680     public int getChildElementCount() {
1681         int counter = 0;
1682         if (getPage().getDocumentElement() != null) {
1683             counter++;
1684         }
1685         return counter;
1686     }
1687 
1688     /**
1689      * Returns the element for the specified x coordinate and the specified y coordinate.
1690      * The current implementation always returns null element.
1691      *
1692      * @param x the x offset, in pixels
1693      * @param y the y offset, in pixels
1694      * @return the element for the specified x coordinate and the specified y coordinate
1695      */
1696     @JsxFunction
1697     public HtmlUnitScriptable elementFromPoint(final int x, final int y) {
1698         return null;
1699     }
1700 
1701     /**
1702      * Returns the value of the {@code forms} property.
1703      * @return the value of the {@code forms} property
1704      */
1705     @JsxGetter
1706     public HTMLCollection getForms() {
1707         final HTMLCollection forms = new HTMLCollection(getDomNodeOrDie(), false) {
1708             @Override
1709             public Object call(final Context cx, final Scriptable scope,
1710                     final Scriptable thisObj, final Object[] args) {
1711                 throw JavaScriptEngine.typeError("document.forms is not a function");
1712             }
1713         };
1714 
1715         forms.setIsMatchingPredicate(
1716                 (Predicate<DomNode> & Serializable)
1717                 node -> node instanceof HtmlForm && node.getPrefix() == null);
1718         return forms;
1719     }
1720 
1721     /**
1722      * Returns the value of the {@code embeds} property.
1723      * @return the value of the {@code embeds} property
1724      */
1725     @JsxGetter
1726     public HTMLCollection getEmbeds() {
1727         final HTMLCollection embeds = new HTMLCollection(getDomNodeOrDie(), false) {
1728             @Override
1729             public Object call(final Context cx, final Scriptable scope,
1730                     final Scriptable thisObj, final Object[] args) {
1731                 throw JavaScriptEngine.typeError("document.embeds is not a function");
1732             }
1733         };
1734 
1735         embeds.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlEmbed);
1736         return embeds;
1737     }
1738 
1739     /**
1740      * Returns the value of the {@code embeds} property.
1741      * @return the value of the {@code embeds} property
1742      */
1743     @JsxGetter
1744     public HTMLCollection getImages() {
1745         final HTMLCollection images = new HTMLCollection(getDomNodeOrDie(), false) {
1746             @Override
1747             public Object call(final Context cx, final Scriptable scope,
1748                     final Scriptable thisObj, final Object[] args) {
1749                 throw JavaScriptEngine.typeError("document.images is not a function");
1750             }
1751         };
1752 
1753         images.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlImage);
1754         return images;
1755     }
1756 
1757     /**
1758      * Returns the value of the {@code scripts} property.
1759      * @return the value of the {@code scripts} property
1760      */
1761     @JsxGetter
1762     public HTMLCollection getScripts() {
1763         final HTMLCollection scripts = new HTMLCollection(getDomNodeOrDie(), false) {
1764             @Override
1765             public Object call(final Context cx, final Scriptable scope,
1766                     final Scriptable thisObj, final Object[] args) {
1767                 throw JavaScriptEngine.typeError("document.scripts is not a function");
1768             }
1769         };
1770 
1771         scripts.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlScript);
1772         return scripts;
1773     }
1774 
1775     /**
1776      * Retrieves a collection of stylesheet objects representing the style sheets that correspond
1777      * to each instance of a Link or
1778      * {@link org.htmlunit.javascript.host.css.CSSStyleDeclaration} object in the document.
1779      *
1780      * @return styleSheet collection
1781      */
1782     @JsxGetter
1783     public StyleSheetList getStyleSheets() {
1784         if (styleSheetList_ == null) {
1785             styleSheetList_ = new StyleSheetList(this);
1786         }
1787         return styleSheetList_;
1788     }
1789 
1790     /**
1791      * Returns the value of the {@code plugins} property.
1792      * @return the value of the {@code plugins} property
1793      */
1794     @JsxGetter
1795     public HTMLCollection getPlugins() {
1796         return getEmbeds();
1797     }
1798 
1799     /**
1800      * Returns the value of the JavaScript property {@code links}. Refer also to the
1801      * <a href="http://msdn.microsoft.com/en-us/library/ms537465.aspx">MSDN documentation</a>.
1802      * @return the value of this property
1803      */
1804     @JsxGetter
1805     public HTMLCollection getLinks() {
1806         final HTMLCollection links = new HTMLCollection(getDomNodeOrDie(), true);
1807 
1808         links.setEffectOnCacheFunction(
1809                 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1810                 event -> {
1811                     final HtmlElement node = event.getHtmlElement();
1812                     if ((node instanceof HtmlAnchor || node instanceof HtmlArea) && "href".equals(event.getName())) {
1813                         return EffectOnCache.RESET;
1814                     }
1815                     return EffectOnCache.NONE;
1816                 });
1817 
1818         links.setIsMatchingPredicate(
1819                 (Predicate<DomNode> & Serializable)
1820                 node ->
1821                     (node instanceof HtmlAnchor || node instanceof HtmlArea)
1822                     && ((HtmlElement) node).hasAttribute("href"));
1823 
1824         return links;
1825     }
1826 
1827     /**
1828      * Returns all the descendant elements with the specified class name.
1829      * @param className the name to search for
1830      * @return all the descendant elements with the specified class name
1831      * @see <a href="https://developer.mozilla.org/en/DOM/document.getElementsByClassName">Mozilla doc</a>
1832      */
1833     @JsxFunction
1834     public HTMLCollection getElementsByClassName(final String className) {
1835         return null;
1836     }
1837 
1838     /**
1839      * Returns all HTML elements that have a {@code name} attribute with the specified value.
1840      * <p>
1841      * Refer to <a href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-71555259">
1842      * The DOM spec</a> for details.
1843      *
1844      * @param elementName - value of the {@code name} attribute to look for
1845      * @return all HTML elements that have a {@code name} attribute with the specified value
1846      */
1847     @JsxFunction
1848     public NodeList getElementsByName(final String elementName) {
1849         return null;
1850     }
1851 
1852     /**
1853      * Returns {@code false} if the active element in the document has no focus;
1854      * {@code true} if the active element in the document has focus.
1855      * @return whether the active element in the document has focus or not
1856      */
1857     @JsxFunction
1858     public boolean hasFocus() {
1859         return false;
1860     }
1861 
1862     /**
1863      * Returns this document's title.
1864      * @return this document's title
1865      */
1866     @JsxGetter
1867     public String getTitle() {
1868         return "";
1869     }
1870 
1871     /**
1872      * Sets this document's title.
1873      * @param title the new title
1874      */
1875     @JsxSetter
1876     public void setTitle(final String title) {
1877         // nothing to do
1878     }
1879 
1880     /**
1881      * {@inheritDoc}
1882      */
1883     @Override
1884     @JsxGetter
1885     public HTMLCollection getChildren() {
1886         return super.getChildren();
1887     }
1888 
1889     /**
1890      * Returns the {@code contentType} property.
1891      * @return the {@code contentType} property
1892      */
1893     @JsxGetter
1894     public String getContentType() {
1895         return getPage().getContentType();
1896     }
1897 
1898     /**
1899      * Returns the current selection.
1900      * @return the current selection
1901      */
1902     @JsxFunction
1903     public Selection getSelection() {
1904         return null;
1905     }
1906 
1907     /**
1908      * Returns this document's {@code head} element.
1909      * @return this document's {@code head} element
1910      */
1911     @JsxGetter
1912     public Object getHead() {
1913         return null;
1914     }
1915 
1916     /**
1917      * Returns a string representing the encoding under which the document was parsed.
1918      * @return a string representing the encoding under which the document was parsed
1919      */
1920     @JsxGetter
1921     public String getInputEncoding() {
1922         return getPage().getCharset().name();
1923     }
1924 
1925     /**
1926      * Returns the last modification date of the document.
1927      * @see <a href="https://developer.mozilla.org/en/DOM/document.lastModified">Mozilla documentation</a>
1928      * @return the date as string
1929      */
1930     @JsxGetter
1931     public String getLastModified() {
1932         if (lastModified_ == null) {
1933             final WebResponse webResponse = getPage().getWebResponse();
1934             final Date lastModified;
1935             if (webResponse != null) {
1936                 String stringDate = webResponse.getResponseHeaderValue("Last-Modified");
1937                 if (stringDate == null) {
1938                     stringDate = webResponse.getResponseHeaderValue("Date");
1939                 }
1940                 lastModified = parseDateOrNow(stringDate);
1941             }
1942             else {
1943                 lastModified = new Date();
1944             }
1945 
1946             final ZoneId zoneid = Context.getCurrentContext().getTimeZone().toZoneId();
1947             lastModified_ = LAST_MODIFIED_DATE_FORMATTER.format(lastModified.toInstant().atZone(zoneid));
1948         }
1949         return lastModified_;
1950     }
1951 
1952     private static Date parseDateOrNow(final String stringDate) {
1953         final Date date = HttpUtils.parseDate(stringDate);
1954         if (date == null) {
1955             return new Date();
1956         }
1957         return date;
1958     }
1959 
1960     /**
1961      * Mock for the moment.
1962      */
1963     @JsxFunction({FF, FF_ESR})
1964     public void releaseCapture() {
1965         // nothing to do
1966     }
1967 
1968     /**
1969      * Returns the ready state of the document.
1970      * @return the ready state of the document
1971      *
1972      * @see DomNode#READY_STATE_UNINITIALIZED
1973      * @see DomNode#READY_STATE_LOADING
1974      * @see DomNode#READY_STATE_LOADED
1975      * @see DomNode#READY_STATE_INTERACTIVE
1976      * @see DomNode#READY_STATE_COMPLETE
1977      */
1978     @JsxGetter
1979     public String getReadyState() {
1980         return getDomNodeOrDie().getReadyState();
1981     }
1982 
1983     /**
1984      * Does nothing special anymore.
1985      *
1986      * @param type the type of events to capture
1987      * @see Window#captureEvents(String)
1988      */
1989     @JsxFunction
1990     public void captureEvents(final String type) {
1991         // Empty.
1992     }
1993 
1994     /**
1995      * Does nothing special anymore.
1996      *
1997      * @param type the type of events to capture
1998      * @see Window#releaseEvents(String)
1999      */
2000     @JsxFunction
2001     public void releaseEvents(final String type) {
2002         // Empty.
2003     }
2004 
2005     /**
2006      * Returns the value of the {@code alinkColor} property.
2007      * @return the value of the {@code alinkColor} property
2008      */
2009     @JsxGetter
2010     public String getAlinkColor() {
2011         final HTMLElement body = getBody();
2012         if (body instanceof HTMLBodyElement) {
2013             return ((HTMLBodyElement) body).getALink();
2014         }
2015         return null;
2016     }
2017 
2018     /**
2019      * Sets the value of the {@code alinkColor} property.
2020      * @param color the value of the {@code alinkColor} property
2021      */
2022     @JsxSetter
2023     public void setAlinkColor(final String color) {
2024         final HTMLElement body = getBody();
2025         if (body instanceof HTMLBodyElement) {
2026             ((HTMLBodyElement) body).setALink(color);
2027         }
2028     }
2029 
2030     /**
2031      * Returns the value of the {@code bgColor} property.
2032      * @return the value of the {@code bgColor} property
2033      * @see <a href="http://msdn.microsoft.com/en-us/library/ms533505.aspx">MSDN Documentation</a>
2034      */
2035     @JsxGetter
2036     public String getBgColor() {
2037         final HTMLElement body = getBody();
2038         if (body instanceof HTMLBodyElement) {
2039             return ((HTMLBodyElement) body).getBgColor();
2040         }
2041         return null;
2042     }
2043 
2044     /**
2045      * Sets the value of the {@code bgColor} property.
2046      * @param color the value of the {@code bgColor} property
2047      * @see <a href="http://msdn.microsoft.com/en-us/library/ms533505.aspx">MSDN Documentation</a>
2048      */
2049     @JsxSetter
2050     public void setBgColor(final String color) {
2051         final HTMLElement body = getBody();
2052         if (body instanceof HTMLBodyElement) {
2053             ((HTMLBodyElement) body).setBgColor(color);
2054         }
2055     }
2056 
2057     /**
2058      * Returns the value of the {@code fgColor} property.
2059      * @return the value of the {@code fgColor} property
2060      */
2061     @JsxGetter
2062     public String getFgColor() {
2063         final HTMLElement body = getBody();
2064         if (body instanceof HTMLBodyElement) {
2065             return ((HTMLBodyElement) body).getText();
2066         }
2067         return null;
2068     }
2069 
2070     /**
2071      * Sets the value of the {@code fgColor} property.
2072      * @param color the value of the {@code fgColor} property
2073      */
2074     @JsxSetter
2075     public void setFgColor(final String color) {
2076         final HTMLElement body = getBody();
2077         if (body instanceof HTMLBodyElement) {
2078             ((HTMLBodyElement) body).setText(color);
2079         }
2080     }
2081 
2082     /**
2083      * Returns the value of the {@code linkColor} property.
2084      * @return the value of the {@code linkColor} property
2085      */
2086     @JsxGetter
2087     public String getLinkColor() {
2088         final HTMLElement body = getBody();
2089         if (body instanceof HTMLBodyElement) {
2090             return ((HTMLBodyElement) body).getLink();
2091         }
2092         return null;
2093     }
2094 
2095     /**
2096      * Sets the value of the {@code linkColor} property.
2097      * @param color the value of the {@code linkColor} property
2098      */
2099     @JsxSetter
2100     public void setLinkColor(final String color) {
2101         final HTMLElement body = getBody();
2102         if (body instanceof HTMLBodyElement) {
2103             ((HTMLBodyElement) body).setLink(color);
2104         }
2105     }
2106 
2107     /**
2108      * Returns the value of the {@code vlinkColor} property.
2109      * @return the value of the {@code vlinkColor} property
2110      */
2111     @JsxGetter
2112     public String getVlinkColor() {
2113         final HTMLElement body = getBody();
2114         if (body instanceof HTMLBodyElement) {
2115             return ((HTMLBodyElement) body).getVLink();
2116         }
2117         return null;
2118     }
2119 
2120     /**
2121      * Sets the value of the {@code vlinkColor} property.
2122      * @param color the value of the {@code vlinkColor} property
2123      */
2124     @JsxSetter
2125     public void setVlinkColor(final String color) {
2126         final HTMLElement body = getBody();
2127         if (body instanceof HTMLBodyElement) {
2128             ((HTMLBodyElement) body).setVLink(color);
2129         }
2130     }
2131 
2132     /**
2133      * {@inheritDoc}
2134      */
2135     @Override
2136     @JsxGetter
2137     public Element getLastElementChild() {
2138         return super.getLastElementChild();
2139     }
2140 
2141     /**
2142      * {@inheritDoc}
2143      */
2144     @Override
2145     @JsxGetter
2146     public Element getFirstElementChild() {
2147         return super.getFirstElementChild();
2148     }
2149 
2150     /**
2151      * Returns the {@code xmlEncoding} property.
2152      * @return the {@code xmlEncoding} property
2153      */
2154     @JsxGetter({CHROME, EDGE})
2155     public String getXmlEncoding() {
2156         return getPage().getXmlEncoding();
2157     }
2158 
2159     /**
2160      * Returns the {@code xmlStandalone} property.
2161      * @return the {@code xmlStandalone} property
2162      */
2163     @JsxGetter({CHROME, EDGE})
2164     public boolean isXmlStandalone() {
2165         return getPage().getXmlStandalone();
2166     }
2167 
2168     /**
2169      * Returns the {@code xmlVersion} property.
2170      * @return the {@code xmlVersion} property
2171      */
2172     @JsxGetter({CHROME, EDGE})
2173     public String getXmlVersion() {
2174         return getPage().getXmlVersion();
2175     }
2176 
2177     /**
2178      * Returns the {@code onabort} event handler for this element.
2179      * @return the {@code onabort} event handler for this element
2180      */
2181     @JsxGetter
2182     public Function getOnabort() {
2183         return getEventHandler(Event.TYPE_ABORT);
2184     }
2185 
2186     /**
2187      * Sets the {@code onabort} event handler for this element.
2188      * @param onabort the {@code onabort} event handler for this element
2189      */
2190     @JsxSetter
2191     public void setOnabort(final Object onabort) {
2192         setEventHandler(Event.TYPE_ABORT, onabort);
2193     }
2194 
2195     /**
2196      * Returns the {@code onauxclick} event handler for this element.
2197      * @return the {@code onauxclick} event handler for this element
2198      */
2199     @JsxGetter({CHROME, EDGE})
2200     public Function getOnauxclick() {
2201         return getEventHandler(Event.TYPE_AUXCLICK);
2202     }
2203 
2204     /**
2205      * Sets the {@code onauxclick} event handler for this element.
2206      * @param onauxclick the {@code onauxclick} event handler for this element
2207      */
2208     @JsxSetter({CHROME, EDGE})
2209     public void setOnauxclick(final Object onauxclick) {
2210         setEventHandler(Event.TYPE_AUXCLICK, onauxclick);
2211     }
2212 
2213     /**
2214      * Returns the {@code onbeforecopy} event handler for this element.
2215      * @return the {@code onbeforecopy} event handler for this element
2216      */
2217     @JsxGetter({CHROME, EDGE})
2218     public Function getOnbeforecopy() {
2219         return getEventHandler(Event.TYPE_BEFORECOPY);
2220     }
2221 
2222     /**
2223      * Sets the {@code onbeforecopy} event handler for this element.
2224      * @param onbeforecopy the {@code onbeforecopy} event handler for this element
2225      */
2226     @JsxSetter({CHROME, EDGE})
2227     public void setOnbeforecopy(final Object onbeforecopy) {
2228         setEventHandler(Event.TYPE_BEFORECOPY, onbeforecopy);
2229     }
2230 
2231     /**
2232      * Returns the {@code onbeforecut} event handler for this element.
2233      * @return the {@code onbeforecut} event handler for this element
2234      */
2235     @JsxGetter({CHROME, EDGE})
2236     public Function getOnbeforecut() {
2237         return getEventHandler(Event.TYPE_BEFORECUT);
2238     }
2239 
2240     /**
2241      * Sets the {@code onbeforecut} event handler for this element.
2242      * @param onbeforecut the {@code onbeforecut} event handler for this element
2243      */
2244     @JsxSetter({CHROME, EDGE})
2245     public void setOnbeforecut(final Object onbeforecut) {
2246         setEventHandler(Event.TYPE_BEFORECUT, onbeforecut);
2247     }
2248 
2249     /**
2250      * Returns the {@code onbeforepaste} event handler for this element.
2251      * @return the {@code onbeforepaste} event handler for this element
2252      */
2253     @JsxGetter({CHROME, EDGE})
2254     public Function getOnbeforepaste() {
2255         return getEventHandler(Event.TYPE_BEFOREPASTE);
2256     }
2257 
2258     /**
2259      * Sets the {@code onbeforepaste} event handler for this element.
2260      * @param onbeforepaste the {@code onbeforepaste} event handler for this element
2261      */
2262     @JsxSetter({CHROME, EDGE})
2263     public void setOnbeforepaste(final Object onbeforepaste) {
2264         setEventHandler(Event.TYPE_BEFOREPASTE, onbeforepaste);
2265     }
2266 
2267     /**
2268      * Returns the {@code oncancel} event handler for this element.
2269      * @return the {@code oncancel} event handler for this element
2270      */
2271     @JsxGetter({CHROME, EDGE})
2272     public Function getOncancel() {
2273         return getEventHandler(Event.TYPE_CANCEL);
2274     }
2275 
2276     /**
2277      * Sets the {@code oncancel} event handler for this element.
2278      * @param oncancel the {@code oncancel} event handler for this element
2279      */
2280     @JsxSetter({CHROME, EDGE})
2281     public void setOncancel(final Object oncancel) {
2282         setEventHandler(Event.TYPE_CANCEL, oncancel);
2283     }
2284 
2285     /**
2286      * Returns the {@code oncanplay} event handler for this element.
2287      * @return the {@code oncanplay} event handler for this element
2288      */
2289     @JsxGetter
2290     public Function getOncanplay() {
2291         return getEventHandler(Event.TYPE_CANPLAY);
2292     }
2293 
2294     /**
2295      * Sets the {@code oncanplay} event handler for this element.
2296      * @param oncanplay the {@code oncanplay} event handler for this element
2297      */
2298     @JsxSetter
2299     public void setOncanplay(final Object oncanplay) {
2300         setEventHandler(Event.TYPE_CANPLAY, oncanplay);
2301     }
2302 
2303     /**
2304      * Returns the {@code oncanplaythrough} event handler for this element.
2305      * @return the {@code oncanplaythrough} event handler for this element
2306      */
2307     @JsxGetter
2308     public Function getOncanplaythrough() {
2309         return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2310     }
2311 
2312     /**
2313      * Sets the {@code oncanplaythrough} event handler for this element.
2314      * @param oncanplaythrough the {@code oncanplaythrough} event handler for this element
2315      */
2316     @JsxSetter
2317     public void setOncanplaythrough(final Object oncanplaythrough) {
2318         setEventHandler(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2319     }
2320 
2321     /**
2322      * Returns the {@code onchange} event handler for this element.
2323      * @return the {@code onchange} event handler for this element
2324      */
2325     @JsxGetter
2326     public Function getOnchange() {
2327         return getEventHandler(Event.TYPE_CHANGE);
2328     }
2329 
2330     /**
2331      * Sets the {@code onchange} event handler for this element.
2332      * @param onchange the {@code onchange} event handler for this element
2333      */
2334     @JsxSetter
2335     public void setOnchange(final Object onchange) {
2336         setEventHandler(Event.TYPE_CHANGE, onchange);
2337     }
2338 
2339     /**
2340      * Returns the {@code onclose} event handler for this element.
2341      * @return the {@code onclose} event handler for this element
2342      */
2343     @JsxGetter({CHROME, EDGE})
2344     public Function getOnclose() {
2345         return getEventHandler(Event.TYPE_CLOSE);
2346     }
2347 
2348     /**
2349      * Sets the {@code onclose} event handler for this element.
2350      * @param onclose the {@code onclose} event handler for this element
2351      */
2352     @JsxSetter({CHROME, EDGE})
2353     public void setOnclose(final Object onclose) {
2354         setEventHandler(Event.TYPE_CLOSE, onclose);
2355     }
2356 
2357     /**
2358      * Returns the {@code oncopy} event handler for this element.
2359      * @return the {@code oncopy} event handler for this element
2360      */
2361     @JsxGetter
2362     public Function getOncopy() {
2363         return getEventHandler(Event.TYPE_COPY);
2364     }
2365 
2366     /**
2367      * Sets the {@code oncopy} event handler for this element.
2368      * @param oncopy the {@code oncopy} event handler for this element
2369      */
2370     @JsxSetter
2371     public void setOncopy(final Object oncopy) {
2372         setEventHandler(Event.TYPE_COPY, oncopy);
2373     }
2374 
2375     /**
2376      * Returns the {@code oncuechange} event handler for this element.
2377      * @return the {@code oncuechange} event handler for this element
2378      */
2379     @JsxGetter({CHROME, EDGE})
2380     public Function getOncuechange() {
2381         return getEventHandler(Event.TYPE_CUECHANGE);
2382     }
2383 
2384     /**
2385      * Sets the {@code oncuechange} event handler for this element.
2386      * @param oncuechange the {@code oncuechange} event handler for this element
2387      */
2388     @JsxSetter({CHROME, EDGE})
2389     public void setOncuechange(final Object oncuechange) {
2390         setEventHandler(Event.TYPE_CUECHANGE, oncuechange);
2391     }
2392 
2393     /**
2394      * Returns the {@code oncut} event handler for this element.
2395      * @return the {@code oncut} event handler for this element
2396      */
2397     @JsxGetter
2398     public Function getOncut() {
2399         return getEventHandler(Event.TYPE_CUT);
2400     }
2401 
2402     /**
2403      * Sets the {@code oncut} event handler for this element.
2404      * @param oncut the {@code oncut} event handler for this element
2405      */
2406     @JsxSetter
2407     public void setOncut(final Object oncut) {
2408         setEventHandler(Event.TYPE_CUT, oncut);
2409     }
2410 
2411     /**
2412      * Returns the {@code ondrag} event handler for this element.
2413      * @return the {@code ondrag} event handler for this element
2414      */
2415     @JsxGetter
2416     public Function getOndrag() {
2417         return getEventHandler(Event.TYPE_DRAG);
2418     }
2419 
2420     /**
2421      * Sets the {@code ondrag} event handler for this element.
2422      * @param ondrag the {@code ondrag} event handler for this element
2423      */
2424     @JsxSetter
2425     public void setOndrag(final Object ondrag) {
2426         setEventHandler(Event.TYPE_DRAG, ondrag);
2427     }
2428 
2429     /**
2430      * Returns the {@code ondragend} event handler for this element.
2431      * @return the {@code ondragend} event handler for this element
2432      */
2433     @JsxGetter
2434     public Function getOndragend() {
2435         return getEventHandler(Event.TYPE_DRAGEND);
2436     }
2437 
2438     /**
2439      * Sets the {@code ondragend} event handler for this element.
2440      * @param ondragend the {@code ondragend} event handler for this element
2441      */
2442     @JsxSetter
2443     public void setOndragend(final Object ondragend) {
2444         setEventHandler(Event.TYPE_DRAGEND, ondragend);
2445     }
2446 
2447     /**
2448      * Returns the {@code ondragenter} event handler for this element.
2449      * @return the {@code ondragenter} event handler for this element
2450      */
2451     @JsxGetter
2452     public Function getOndragenter() {
2453         return getEventHandler(Event.TYPE_DRAGENTER);
2454     }
2455 
2456     /**
2457      * Sets the {@code ondragenter} event handler for this element.
2458      * @param ondragenter the {@code ondragenter} event handler for this element
2459      */
2460     @JsxSetter
2461     public void setOndragenter(final Object ondragenter) {
2462         setEventHandler(Event.TYPE_DRAGENTER, ondragenter);
2463     }
2464 
2465     /**
2466      * Returns the {@code ondragleave} event handler for this element.
2467      * @return the {@code ondragleave} event handler for this element
2468      */
2469     @JsxGetter
2470     public Function getOndragleave() {
2471         return getEventHandler(Event.TYPE_DRAGLEAVE);
2472     }
2473 
2474     /**
2475      * Sets the {@code ondragleave} event handler for this element.
2476      * @param ondragleave the {@code ondragleave} event handler for this element
2477      */
2478     @JsxSetter
2479     public void setOndragleave(final Object ondragleave) {
2480         setEventHandler(Event.TYPE_DRAGLEAVE, ondragleave);
2481     }
2482 
2483     /**
2484      * Returns the {@code ondragover} event handler for this element.
2485      * @return the {@code ondragover} event handler for this element
2486      */
2487     @JsxGetter
2488     public Function getOndragover() {
2489         return getEventHandler(Event.TYPE_DRAGOVER);
2490     }
2491 
2492     /**
2493      * Sets the {@code ondragover} event handler for this element.
2494      * @param ondragover the {@code ondragover} event handler for this element
2495      */
2496     @JsxSetter
2497     public void setOndragover(final Object ondragover) {
2498         setEventHandler(Event.TYPE_DRAGOVER, ondragover);
2499     }
2500 
2501     /**
2502      * Returns the {@code ondragstart} event handler for this element.
2503      * @return the {@code ondragstart} event handler for this element
2504      */
2505     @JsxGetter
2506     public Function getOndragstart() {
2507         return getEventHandler(Event.TYPE_DRAGSTART);
2508     }
2509 
2510     /**
2511      * Sets the {@code ondragstart} event handler for this element.
2512      * @param ondragstart the {@code ondragstart} event handler for this element
2513      */
2514     @JsxSetter
2515     public void setOndragstart(final Object ondragstart) {
2516         setEventHandler(Event.TYPE_DRAGSTART, ondragstart);
2517     }
2518 
2519     /**
2520      * Returns the {@code ondrop} event handler for this element.
2521      * @return the {@code ondrop} event handler for this element
2522      */
2523     @JsxGetter
2524     public Function getOndrop() {
2525         return getEventHandler(Event.TYPE_DROP);
2526     }
2527 
2528     /**
2529      * Sets the {@code ondrop} event handler for this element.
2530      * @param ondrop the {@code ondrop} event handler for this element
2531      */
2532     @JsxSetter
2533     public void setOndrop(final Object ondrop) {
2534         setEventHandler(Event.TYPE_DROP, ondrop);
2535     }
2536 
2537     /**
2538      * Returns the {@code ondurationchange} event handler for this element.
2539      * @return the {@code ondurationchange} event handler for this element
2540      */
2541     @JsxGetter
2542     public Function getOndurationchange() {
2543         return getEventHandler(Event.TYPE_DURATIONCHANGE);
2544     }
2545 
2546     /**
2547      * Sets the {@code ondurationchange} event handler for this element.
2548      * @param ondurationchange the {@code ondurationchange} event handler for this element
2549      */
2550     @JsxSetter
2551     public void setOndurationchange(final Object ondurationchange) {
2552         setEventHandler(Event.TYPE_DURATIONCHANGE, ondurationchange);
2553     }
2554 
2555     /**
2556      * Returns the {@code onemptied} event handler for this element.
2557      * @return the {@code onemptied} event handler for this element
2558      */
2559     @JsxGetter
2560     public Function getOnemptied() {
2561         return getEventHandler(Event.TYPE_EMPTIED);
2562     }
2563 
2564     /**
2565      * Sets the {@code onemptied} event handler for this element.
2566      * @param onemptied the {@code onemptied} event handler for this element
2567      */
2568     @JsxSetter
2569     public void setOnemptied(final Object onemptied) {
2570         setEventHandler(Event.TYPE_EMPTIED, onemptied);
2571     }
2572 
2573     /**
2574      * Returns the {@code onended} event handler for this element.
2575      * @return the {@code onended} event handler for this element
2576      */
2577     @JsxGetter
2578     public Function getOnended() {
2579         return getEventHandler(Event.TYPE_ENDED);
2580     }
2581 
2582     /**
2583      * Sets the {@code onended} event handler for this element.
2584      * @param onended the {@code onended} event handler for this element
2585      */
2586     @JsxSetter
2587     public void setOnended(final Object onended) {
2588         setEventHandler(Event.TYPE_ENDED, onended);
2589     }
2590 
2591     /**
2592      * Returns the {@code ongotpointercapture} event handler for this element.
2593      * @return the {@code ongotpointercapture} event handler for this element
2594      */
2595     @JsxGetter({CHROME, EDGE})
2596     public Function getOngotpointercapture() {
2597         return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
2598     }
2599 
2600     /**
2601      * Sets the {@code ongotpointercapture} event handler for this element.
2602      * @param ongotpointercapture the {@code ongotpointercapture} event handler for this element
2603      */
2604     @JsxSetter({CHROME, EDGE})
2605     public void setOngotpointercapture(final Object ongotpointercapture) {
2606         setEventHandler(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
2607     }
2608 
2609     /**
2610      * Returns the {@code oninvalid} event handler for this element.
2611      * @return the {@code oninvalid} event handler for this element
2612      */
2613     @JsxGetter
2614     public Function getOninvalid() {
2615         return getEventHandler(Event.TYPE_INVALID);
2616     }
2617 
2618     /**
2619      * Sets the {@code oninvalid} event handler for this element.
2620      * @param oninvalid the {@code oninvalid} event handler for this element
2621      */
2622     @JsxSetter
2623     public void setOninvalid(final Object oninvalid) {
2624         setEventHandler(Event.TYPE_INVALID, oninvalid);
2625     }
2626 
2627     /**
2628      * Returns the {@code onload} event handler for this element.
2629      * @return the {@code onload} event handler for this element
2630      */
2631     @JsxGetter
2632     public Function getOnload() {
2633         return getEventHandler(Event.TYPE_LOAD);
2634     }
2635 
2636     /**
2637      * Sets the {@code onload} event handler for this element.
2638      * @param onload the {@code onload} event handler for this element
2639      */
2640     @JsxSetter
2641     public void setOnload(final Object onload) {
2642         setEventHandler(Event.TYPE_LOAD, onload);
2643     }
2644 
2645     /**
2646      * Returns the {@code onloadeddata} event handler for this element.
2647      * @return the {@code onloadeddata} event handler for this element
2648      */
2649     @JsxGetter
2650     public Function getOnloadeddata() {
2651         return getEventHandler(Event.TYPE_LOADEDDATA);
2652     }
2653 
2654     /**
2655      * Sets the {@code onloadeddata} event handler for this element.
2656      * @param onloadeddata the {@code onloadeddata} event handler for this element
2657      */
2658     @JsxSetter
2659     public void setOnloadeddata(final Object onloadeddata) {
2660         setEventHandler(Event.TYPE_LOADEDDATA, onloadeddata);
2661     }
2662 
2663     /**
2664      * Returns the {@code onloadedmetadata} event handler for this element.
2665      * @return the {@code onloadedmetadata} event handler for this element
2666      */
2667     @JsxGetter
2668     public Function getOnloadedmetadata() {
2669         return getEventHandler(Event.TYPE_LOADEDMETADATA);
2670     }
2671 
2672     /**
2673      * Sets the {@code onloadedmetadata} event handler for this element.
2674      * @param onloadedmetadata the {@code onloadedmetadata} event handler for this element
2675      */
2676     @JsxSetter
2677     public void setOnloadedmetadata(final Object onloadedmetadata) {
2678         setEventHandler(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
2679     }
2680 
2681     /**
2682      * Returns the {@code onloadstart} event handler for this element.
2683      * @return the {@code onloadstart} event handler for this element
2684      */
2685     @JsxGetter
2686     public Function getOnloadstart() {
2687         return getEventHandler(Event.TYPE_LOAD_START);
2688     }
2689 
2690     /**
2691      * Sets the {@code onloadstart} event handler for this element.
2692      * @param onloadstart the {@code onloadstart} event handler for this element
2693      */
2694     @JsxSetter
2695     public void setOnloadstart(final Object onloadstart) {
2696         setEventHandler(Event.TYPE_LOAD_START, onloadstart);
2697     }
2698 
2699     /**
2700      * Returns the {@code onlostpointercapture} event handler for this element.
2701      * @return the {@code onlostpointercapture} event handler for this element
2702      */
2703     @JsxGetter({CHROME, EDGE})
2704     public Function getOnlostpointercapture() {
2705         return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2706     }
2707 
2708     /**
2709      * Sets the {@code onlostpointercapture} event handler for this element.
2710      * @param onlostpointercapture the {@code onlostpointercapture} event handler for this element
2711      */
2712     @JsxSetter({CHROME, EDGE})
2713     public void setOnlostpointercapture(final Object onlostpointercapture) {
2714         setEventHandler(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2715     }
2716 
2717     /**
2718      * Returns the {@code onmouseenter} event handler for this element.
2719      * @return the {@code onmouseenter} event handler for this element
2720      */
2721     @JsxGetter
2722     public Function getOnmouseenter() {
2723         return getEventHandler(Event.TYPE_MOUDEENTER);
2724     }
2725 
2726     /**
2727      * Sets the {@code onmouseenter} event handler for this element.
2728      * @param onmouseenter the {@code onmouseenter} event handler for this element
2729      */
2730     @JsxSetter
2731     public void setOnmouseenter(final Object onmouseenter) {
2732         setEventHandler(Event.TYPE_MOUDEENTER, onmouseenter);
2733     }
2734 
2735     /**
2736      * Returns the {@code onmouseleave} event handler for this element.
2737      * @return the {@code onmouseleave} event handler for this element
2738      */
2739     @JsxGetter
2740     public Function getOnmouseleave() {
2741         return getEventHandler(Event.TYPE_MOUSELEAVE);
2742     }
2743 
2744     /**
2745      * Sets the {@code onmouseleave} event handler for this element.
2746      * @param onmouseleave the {@code onmouseleave} event handler for this element
2747      */
2748     @JsxSetter
2749     public void setOnmouseleave(final Object onmouseleave) {
2750         setEventHandler(Event.TYPE_MOUSELEAVE, onmouseleave);
2751     }
2752 
2753     /**
2754      * Returns the {@code onmousewheel} event handler for this element.
2755      * @return the {@code onmousewheel} event handler for this element
2756      */
2757     @JsxGetter({CHROME, EDGE})
2758     public Function getOnmousewheel() {
2759         return getEventHandler(Event.TYPE_MOUSEWHEEL);
2760     }
2761 
2762     /**
2763      * Sets the {@code onmousewheel} event handler for this element.
2764      * @param onmousewheel the {@code onmousewheel} event handler for this element
2765      */
2766     @JsxSetter({CHROME, EDGE})
2767     public void setOnmousewheel(final Object onmousewheel) {
2768         setEventHandler(Event.TYPE_MOUSEWHEEL, onmousewheel);
2769     }
2770 
2771     /**
2772      * Returns the {@code onpaste} event handler for this element.
2773      * @return the {@code onpaste} event handler for this element
2774      */
2775     @JsxGetter
2776     public Function getOnpaste() {
2777         return getEventHandler(Event.TYPE_PASTE);
2778     }
2779 
2780     /**
2781      * Sets the {@code onpaste} event handler for this element.
2782      * @param onpaste the {@code onpaste} event handler for this element
2783      */
2784     @JsxSetter
2785     public void setOnpaste(final Object onpaste) {
2786         setEventHandler(Event.TYPE_PASTE, onpaste);
2787     }
2788 
2789     /**
2790      * Returns the {@code onpause} event handler for this element.
2791      * @return the {@code onpause} event handler for this element
2792      */
2793     @JsxGetter
2794     public Function getOnpause() {
2795         return getEventHandler(Event.TYPE_PAUSE);
2796     }
2797 
2798     /**
2799      * Sets the {@code onpause} event handler for this element.
2800      * @param onpause the {@code onpause} event handler for this element
2801      */
2802     @JsxSetter
2803     public void setOnpause(final Object onpause) {
2804         setEventHandler(Event.TYPE_PAUSE, onpause);
2805     }
2806 
2807     /**
2808      * Returns the {@code onplay} event handler for this element.
2809      * @return the {@code onplay} event handler for this element
2810      */
2811     @JsxGetter
2812     public Function getOnplay() {
2813         return getEventHandler(Event.TYPE_PLAY);
2814     }
2815 
2816     /**
2817      * Sets the {@code onplay} event handler for this element.
2818      * @param onplay the {@code onplay} event handler for this element
2819      */
2820     @JsxSetter
2821     public void setOnplay(final Object onplay) {
2822         setEventHandler(Event.TYPE_PLAY, onplay);
2823     }
2824 
2825     /**
2826      * Returns the {@code onplaying} event handler for this element.
2827      * @return the {@code onplaying} event handler for this element
2828      */
2829     @JsxGetter
2830     public Function getOnplaying() {
2831         return getEventHandler(Event.TYPE_PLAYING);
2832     }
2833 
2834     /**
2835      * Sets the {@code onplaying} event handler for this element.
2836      * @param onplaying the {@code onplaying} event handler for this element
2837      */
2838     @JsxSetter
2839     public void setOnplaying(final Object onplaying) {
2840         setEventHandler(Event.TYPE_PLAYING, onplaying);
2841     }
2842 
2843     /**
2844      * Returns the {@code onpointercancel} event handler for this element.
2845      * @return the {@code onpointercancel} event handler for this element
2846      */
2847     @JsxGetter({CHROME, EDGE})
2848     public Function getOnpointercancel() {
2849         return getEventHandler(Event.TYPE_POINTERCANCEL);
2850     }
2851 
2852     /**
2853      * Sets the {@code onpointercancel} event handler for this element.
2854      * @param onpointercancel the {@code onpointercancel} event handler for this element
2855      */
2856     @JsxSetter({CHROME, EDGE})
2857     public void setOnpointercancel(final Object onpointercancel) {
2858         setEventHandler(Event.TYPE_POINTERCANCEL, onpointercancel);
2859     }
2860 
2861     /**
2862      * Returns the {@code onpointerdown} event handler for this element.
2863      * @return the {@code onpointerdown} event handler for this element
2864      */
2865     @JsxGetter({CHROME, EDGE})
2866     public Function getOnpointerdown() {
2867         return getEventHandler(Event.TYPE_POINTERDOWN);
2868     }
2869 
2870     /**
2871      * Sets the {@code onpointerdown} event handler for this element.
2872      * @param onpointerdown the {@code onpointerdown} event handler for this element
2873      */
2874     @JsxSetter({CHROME, EDGE})
2875     public void setOnpointerdown(final Object onpointerdown) {
2876         setEventHandler(Event.TYPE_POINTERDOWN, onpointerdown);
2877     }
2878 
2879     /**
2880      * Returns the {@code onpointerenter} event handler for this element.
2881      * @return the {@code onpointerenter} event handler for this element
2882      */
2883     @JsxGetter({CHROME, EDGE})
2884     public Function getOnpointerenter() {
2885         return getEventHandler(Event.TYPE_POINTERENTER);
2886     }
2887 
2888     /**
2889      * Sets the {@code onpointerenter} event handler for this element.
2890      * @param onpointerenter the {@code onpointerenter} event handler for this element
2891      */
2892     @JsxSetter({CHROME, EDGE})
2893     public void setOnpointerenter(final Object onpointerenter) {
2894         setEventHandler(Event.TYPE_POINTERENTER, onpointerenter);
2895     }
2896 
2897     /**
2898      * Returns the {@code onpointerleave} event handler for this element.
2899      * @return the {@code onpointerleave} event handler for this element
2900      */
2901     @JsxGetter({CHROME, EDGE})
2902     public Function getOnpointerleave() {
2903         return getEventHandler(Event.TYPE_POINTERLEAVE);
2904     }
2905 
2906     /**
2907      * Sets the {@code onpointerleave} event handler for this element.
2908      * @param onpointerleave the {@code onpointerleave} event handler for this element
2909      */
2910     @JsxSetter({CHROME, EDGE})
2911     public void setOnpointerleave(final Object onpointerleave) {
2912         setEventHandler(Event.TYPE_POINTERLEAVE, onpointerleave);
2913     }
2914 
2915     /**
2916      * Returns the {@code onpointerlockchange} event handler for this element.
2917      * @return the {@code onpointerlockchange} event handler for this element
2918      */
2919     @JsxGetter({CHROME, EDGE})
2920     public Function getOnpointerlockchange() {
2921         return getEventHandler(Event.TYPE_POINTERLOCKCHANGE);
2922     }
2923 
2924     /**
2925      * Sets the {@code onpointerlockchange} event handler for this element.
2926      * @param onpointerlockchange the {@code onpointerlockchange} event handler for this element
2927      */
2928     @JsxSetter({CHROME, EDGE})
2929     public void setOnpointerlockchange(final Object onpointerlockchange) {
2930         setEventHandler(Event.TYPE_POINTERLOCKCHANGE, onpointerlockchange);
2931     }
2932 
2933     /**
2934      * Returns the {@code onpointerlockerror} event handler for this element.
2935      * @return the {@code onpointerlockerror} event handler for this element
2936      */
2937     @JsxGetter({CHROME, EDGE})
2938     public Function getOnpointerlockerror() {
2939         return getEventHandler(Event.TYPE_POINTERLOCKERROR);
2940     }
2941 
2942     /**
2943      * Sets the {@code onpointerlockerror} event handler for this element.
2944      * @param onpointerlockerror the {@code onpointerlockerror} event handler for this element
2945      */
2946     @JsxSetter({CHROME, EDGE})
2947     public void setOnpointerlockerror(final Object onpointerlockerror) {
2948         setEventHandler(Event.TYPE_POINTERLOCKERROR, onpointerlockerror);
2949     }
2950 
2951     /**
2952      * Returns the {@code onpointermove} event handler for this element.
2953      * @return the {@code onpointermove} event handler for this element
2954      */
2955     @JsxGetter({CHROME, EDGE})
2956     public Function getOnpointermove() {
2957         return getEventHandler(Event.TYPE_POINTERMOVE);
2958     }
2959 
2960     /**
2961      * Sets the {@code onpointermove} event handler for this element.
2962      * @param onpointermove the {@code onpointermove} event handler for this element
2963      */
2964     @JsxSetter({CHROME, EDGE})
2965     public void setOnpointermove(final Object onpointermove) {
2966         setEventHandler(Event.TYPE_POINTERMOVE, onpointermove);
2967     }
2968 
2969     /**
2970      * Returns the {@code onpointerout} event handler for this element.
2971      * @return the {@code onpointerout} event handler for this element
2972      */
2973     @JsxGetter({CHROME, EDGE})
2974     public Function getOnpointerout() {
2975         return getEventHandler(Event.TYPE_POINTEROUT);
2976     }
2977 
2978     /**
2979      * Sets the {@code onpointerout} event handler for this element.
2980      * @param onpointerout the {@code onpointerout} event handler for this element
2981      */
2982     @JsxSetter({CHROME, EDGE})
2983     public void setOnpointerout(final Object onpointerout) {
2984         setEventHandler(Event.TYPE_POINTEROUT, onpointerout);
2985     }
2986 
2987     /**
2988      * Returns the {@code onpointerover} event handler for this element.
2989      * @return the {@code onpointerover} event handler for this element
2990      */
2991     @JsxGetter({CHROME, EDGE})
2992     public Function getOnpointerover() {
2993         return getEventHandler(Event.TYPE_POINTEROVER);
2994     }
2995 
2996     /**
2997      * Sets the {@code onpointerover} event handler for this element.
2998      * @param onpointerover the {@code onpointerover} event handler for this element
2999      */
3000     @JsxSetter({CHROME, EDGE})
3001     public void setOnpointerover(final Object onpointerover) {
3002         setEventHandler(Event.TYPE_POINTEROVER, onpointerover);
3003     }
3004 
3005     /**
3006      * Returns the {@code onpointerup} event handler for this element.
3007      * @return the {@code onpointerup} event handler for this element
3008      */
3009     @JsxGetter({CHROME, EDGE})
3010     public Function getOnpointerup() {
3011         return getEventHandler(Event.TYPE_POINTERUP);
3012     }
3013 
3014     /**
3015      * Sets the {@code onpointerup} event handler for this element.
3016      * @param onpointerup the {@code onpointerup} event handler for this element
3017      */
3018     @JsxSetter({CHROME, EDGE})
3019     public void setOnpointerup(final Object onpointerup) {
3020         setEventHandler(Event.TYPE_POINTERUP, onpointerup);
3021     }
3022 
3023     /**
3024      * Returns the {@code onprogress} event handler for this element.
3025      * @return the {@code onprogress} event handler for this element
3026      */
3027     @JsxGetter
3028     public Function getOnprogress() {
3029         return getEventHandler(Event.TYPE_PROGRESS);
3030     }
3031 
3032     /**
3033      * Sets the {@code onprogress} event handler for this element.
3034      * @param onprogress the {@code onprogress} event handler for this element
3035      */
3036     @JsxSetter
3037     public void setOnprogress(final Object onprogress) {
3038         setEventHandler(Event.TYPE_PROGRESS, onprogress);
3039     }
3040 
3041     /**
3042      * Returns the {@code onratechange} event handler for this element.
3043      * @return the {@code onratechange} event handler for this element
3044      */
3045     @JsxGetter
3046     public Function getOnratechange() {
3047         return getEventHandler(Event.TYPE_RATECHANGE);
3048     }
3049 
3050     /**
3051      * Sets the {@code onratechange} event handler for this element.
3052      * @param onratechange the {@code onratechange} event handler for this element
3053      */
3054     @JsxSetter
3055     public void setOnratechange(final Object onratechange) {
3056         setEventHandler(Event.TYPE_RATECHANGE, onratechange);
3057     }
3058 
3059     /**
3060      * Returns the {@code onreadystatechange} event handler for this element.
3061      * @return the {@code onreadystatechange} event handler for this element
3062      */
3063     @JsxGetter
3064     public Function getOnreadystatechange() {
3065         return getEventHandler(Event.TYPE_READY_STATE_CHANGE);
3066     }
3067 
3068     /**
3069      * Sets the {@code onreadystatechange} event handler for this element.
3070      * @param onreadystatechange the {@code onreadystatechange} event handler for this element
3071      */
3072     @JsxSetter
3073     public void setOnreadystatechange(final Object onreadystatechange) {
3074         setEventHandler(Event.TYPE_READY_STATE_CHANGE, onreadystatechange);
3075     }
3076 
3077     /**
3078      * Returns the {@code onreset} event handler for this element.
3079      * @return the {@code onreset} event handler for this element
3080      */
3081     @JsxGetter
3082     public Function getOnreset() {
3083         return getEventHandler(Event.TYPE_RESET);
3084     }
3085 
3086     /**
3087      * Sets the {@code onreset} event handler for this element.
3088      * @param onreset the {@code onreset} event handler for this element
3089      */
3090     @JsxSetter
3091     public void setOnreset(final Object onreset) {
3092         setEventHandler(Event.TYPE_RESET, onreset);
3093     }
3094 
3095     /**
3096      * Returns the {@code onscroll} event handler for this element.
3097      * @return the {@code onscroll} event handler for this element
3098      */
3099     @JsxGetter
3100     public Function getOnscroll() {
3101         return getEventHandler(Event.TYPE_SCROLL);
3102     }
3103 
3104     /**
3105      * Sets the {@code onscroll} event handler for this element.
3106      * @param onscroll the {@code onscroll} event handler for this element
3107      */
3108     @JsxSetter
3109     public void setOnscroll(final Object onscroll) {
3110         setEventHandler(Event.TYPE_SCROLL, onscroll);
3111     }
3112 
3113     /**
3114      * Returns the {@code onsearch} event handler for this element.
3115      * @return the {@code onsearch} event handler for this element
3116      */
3117     @JsxGetter({CHROME, EDGE})
3118     public Function getOnsearch() {
3119         return getEventHandler(Event.TYPE_SEARCH);
3120     }
3121 
3122     /**
3123      * Sets the {@code onsearch} event handler for this element.
3124      * @param onsearch the {@code onsearch} event handler for this element
3125      */
3126     @JsxSetter({CHROME, EDGE})
3127     public void setOnsearch(final Object onsearch) {
3128         setEventHandler(Event.TYPE_SEARCH, onsearch);
3129     }
3130 
3131     /**
3132      * Returns the {@code onseeked} event handler for this element.
3133      * @return the {@code onseeked} event handler for this element
3134      */
3135     @JsxGetter
3136     public Function getOnseeked() {
3137         return getEventHandler(Event.TYPE_SEEKED);
3138     }
3139 
3140     /**
3141      * Sets the {@code onseeked} event handler for this element.
3142      * @param onseeked the {@code onseeked} event handler for this element
3143      */
3144     @JsxSetter
3145     public void setOnseeked(final Object onseeked) {
3146         setEventHandler(Event.TYPE_SEEKED, onseeked);
3147     }
3148 
3149     /**
3150      * Returns the {@code onseeking} event handler for this element.
3151      * @return the {@code onseeking} event handler for this element
3152      */
3153     @JsxGetter
3154     public Function getOnseeking() {
3155         return getEventHandler(Event.TYPE_SEEKING);
3156     }
3157 
3158     /**
3159      * Sets the {@code onseeking} event handler for this element.
3160      * @param onseeking the {@code onseeking} event handler for this element
3161      */
3162     @JsxSetter
3163     public void setOnseeking(final Object onseeking) {
3164         setEventHandler(Event.TYPE_SEEKING, onseeking);
3165     }
3166 
3167     /**
3168      * Returns the {@code onselect} event handler for this element.
3169      * @return the {@code onselect} event handler for this element
3170      */
3171     @JsxGetter
3172     public Function getOnselect() {
3173         return getEventHandler(Event.TYPE_SELECT);
3174     }
3175 
3176     /**
3177      * Sets the {@code onselect} event handler for this element.
3178      * @param onselect the {@code onselect} event handler for this element
3179      */
3180     @JsxSetter
3181     public void setOnselect(final Object onselect) {
3182         setEventHandler(Event.TYPE_SELECT, onselect);
3183     }
3184 
3185     /**
3186      * Returns the {@code onselectionchange} event handler for this element.
3187      * @return the {@code onselectionchange} event handler for this element
3188      */
3189     @JsxGetter({CHROME, EDGE})
3190     public Function getOnselectionchange() {
3191         return getEventHandler(Event.TYPE_SELECTIONCHANGE);
3192     }
3193 
3194     /**
3195      * Sets the {@code onselectionchange} event handler for this element.
3196      * @param onselectionchange the {@code onselectionchange} event handler for this element
3197      */
3198     @JsxSetter({CHROME, EDGE})
3199     public void setOnselectionchange(final Object onselectionchange) {
3200         setEventHandler(Event.TYPE_SELECTIONCHANGE, onselectionchange);
3201     }
3202 
3203     /**
3204      * Returns the {@code onselectstart} event handler for this element.
3205      * @return the {@code onselectstart} event handler for this element
3206      */
3207     @JsxGetter
3208     public Function getOnselectstart() {
3209         return getEventHandler(Event.TYPE_SELECTSTART);
3210     }
3211 
3212     /**
3213      * Sets the {@code onselectstart} event handler for this element.
3214      * @param onselectstart the {@code onselectstart} event handler for this element
3215      */
3216     @JsxSetter
3217     public void setOnselectstart(final Object onselectstart) {
3218         setEventHandler(Event.TYPE_SELECTSTART, onselectstart);
3219     }
3220 
3221     /**
3222      * Returns the {@code onstalled} event handler for this element.
3223      * @return the {@code onstalled} event handler for this element
3224      */
3225     @JsxGetter
3226     public Function getOnstalled() {
3227         return getEventHandler(Event.TYPE_STALLED);
3228     }
3229 
3230     /**
3231      * Sets the {@code onstalled} event handler for this element.
3232      * @param onstalled the {@code onstalled} event handler for this element
3233      */
3234     @JsxSetter
3235     public void setOnstalled(final Object onstalled) {
3236         setEventHandler(Event.TYPE_STALLED, onstalled);
3237     }
3238 
3239     /**
3240      * Returns the {@code onsubmit} event handler for this element.
3241      * @return the {@code onsubmit} event handler for this element
3242      */
3243     @JsxGetter
3244     public Function getOnsubmit() {
3245         return getEventHandler(Event.TYPE_SUBMIT);
3246     }
3247 
3248     /**
3249      * Sets the {@code onsubmit} event handler for this element.
3250      * @param onsubmit the {@code onsubmit} event handler for this element
3251      */
3252     @JsxSetter
3253     public void setOnsubmit(final Object onsubmit) {
3254         setEventHandler(Event.TYPE_SUBMIT, onsubmit);
3255     }
3256 
3257     /**
3258      * Returns the {@code onsuspend} event handler for this element.
3259      * @return the {@code onsuspend} event handler for this element
3260      */
3261     @JsxGetter
3262     public Function getOnsuspend() {
3263         return getEventHandler(Event.TYPE_SUSPEND);
3264     }
3265 
3266     /**
3267      * Sets the {@code onsuspend} event handler for this element.
3268      * @param onsuspend the {@code onsuspend} event handler for this element
3269      */
3270     @JsxSetter
3271     public void setOnsuspend(final Object onsuspend) {
3272         setEventHandler(Event.TYPE_SUSPEND, onsuspend);
3273     }
3274 
3275     /**
3276      * Returns the {@code ontimeupdate} event handler for this element.
3277      * @return the {@code ontimeupdate} event handler for this element
3278      */
3279     @JsxGetter
3280     public Function getOntimeupdate() {
3281         return getEventHandler(Event.TYPE_TIMEUPDATE);
3282     }
3283 
3284     /**
3285      * Sets the {@code ontimeupdate} event handler for this element.
3286      * @param ontimeupdate the {@code ontimeupdate} event handler for this element
3287      */
3288     @JsxSetter
3289     public void setOntimeupdate(final Object ontimeupdate) {
3290         setEventHandler(Event.TYPE_TIMEUPDATE, ontimeupdate);
3291     }
3292 
3293     /**
3294      * Returns the {@code ontoggle} event handler for this element.
3295      * @return the {@code ontoggle} event handler for this element
3296      */
3297     @JsxGetter({CHROME, EDGE})
3298     public Function getOntoggle() {
3299         return getEventHandler(Event.TYPE_TOGGLE);
3300     }
3301 
3302     /**
3303      * Sets the {@code ontoggle} event handler for this element.
3304      * @param ontoggle the {@code ontoggle} event handler for this element
3305      */
3306     @JsxSetter({CHROME, EDGE})
3307     public void setOntoggle(final Object ontoggle) {
3308         setEventHandler(Event.TYPE_TOGGLE, ontoggle);
3309     }
3310 
3311     /**
3312      * Returns the {@code onvolumechange} event handler for this element.
3313      * @return the {@code onvolumechange} event handler for this element
3314      */
3315     @JsxGetter
3316     public Function getOnvolumechange() {
3317         return getEventHandler(Event.TYPE_VOLUMECHANGE);
3318     }
3319 
3320     /**
3321      * Sets the {@code onvolumechange} event handler for this element.
3322      * @param onvolumechange the {@code onvolumechange} event handler for this element
3323      */
3324     @JsxSetter
3325     public void setOnvolumechange(final Object onvolumechange) {
3326         setEventHandler(Event.TYPE_VOLUMECHANGE, onvolumechange);
3327     }
3328 
3329     /**
3330      * Returns the {@code onwaiting} event handler for this element.
3331      * @return the {@code onwaiting} event handler for this element
3332      */
3333     @JsxGetter
3334     public Function getOnwaiting() {
3335         return getEventHandler(Event.TYPE_WAITING);
3336     }
3337 
3338     /**
3339      * Sets the {@code onwaiting} event handler for this element.
3340      * @param onwaiting the {@code onwaiting} event handler for this element
3341      */
3342     @JsxSetter
3343     public void setOnwaiting(final Object onwaiting) {
3344         setEventHandler(Event.TYPE_WAITING, onwaiting);
3345     }
3346 
3347     /**
3348      * Returns the {@code onwebkitfullscreenchange} event handler for this element.
3349      * @return the {@code onwebkitfullscreenchange} event handler for this element
3350      */
3351     @JsxGetter({CHROME, EDGE})
3352     public Function getOnwebkitfullscreenchange() {
3353         return getEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE);
3354     }
3355 
3356     /**
3357      * Sets the {@code onwebkitfullscreenchange} event handler for this element.
3358      * @param onwebkitfullscreenchange the {@code onwebkitfullscreenchange} event handler for this element
3359      */
3360     @JsxSetter({CHROME, EDGE})
3361     public void setOnwebkitfullscreenchange(final Object onwebkitfullscreenchange) {
3362         setEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE, onwebkitfullscreenchange);
3363     }
3364 
3365     /**
3366      * Returns the {@code onwebkitfullscreenerror} event handler for this element.
3367      * @return the {@code onwebkitfullscreenerror} event handler for this element
3368      */
3369     @JsxGetter({CHROME, EDGE})
3370     public Function getOnwebkitfullscreenerror() {
3371         return getEventHandler(Event.TYPE_WEBKITFULLSCREENERROR);
3372     }
3373 
3374     /**
3375      * Sets the {@code onwebkitfullscreenerror} event handler for this element.
3376      * @param onwebkitfullscreenerror the {@code onwebkitfullscreenerror} event handler for this element
3377      */
3378     @JsxSetter
3379     public void setOnwebkitfullscreenerror(final Object onwebkitfullscreenerror) {
3380         setEventHandler(Event.TYPE_WEBKITFULLSCREENERROR, onwebkitfullscreenerror);
3381     }
3382 
3383     /**
3384      * Returns the {@code onwheel} event handler for this element.
3385      * @return the {@code onwheel} event handler for this element
3386      */
3387     @JsxGetter
3388     public Function getOnwheel() {
3389         return getEventHandler(Event.TYPE_WHEEL);
3390     }
3391 
3392     /**
3393      * Sets the {@code onwheel} event handler for this element.
3394      * @param onwheel the {@code onwheel} event handler for this element
3395      */
3396     @JsxSetter
3397     public void setOnwheel(final Object onwheel) {
3398         setEventHandler(Event.TYPE_WHEEL, onwheel);
3399     }
3400 
3401     /**
3402      * Returns the {@code onafterscriptexecute} event handler for this element.
3403      * @return the {@code onafterscriptexecute} event handler for this element
3404      */
3405     @JsxGetter({FF, FF_ESR})
3406     public Function getOnafterscriptexecute() {
3407         return getEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE);
3408     }
3409 
3410     /**
3411      * Sets the {@code onafterscriptexecute} event handler for this element.
3412      * @param onafterscriptexecute the {@code onafterscriptexecute} event handler for this element
3413      */
3414     @JsxSetter({FF, FF_ESR})
3415     public void setOnafterscriptexecute(final Object onafterscriptexecute) {
3416         setEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE, onafterscriptexecute);
3417     }
3418 
3419     /**
3420      * Returns the {@code onbeforescriptexecute} event handler for this element.
3421      * @return the {@code onbeforescriptexecute} event handler for this element
3422      */
3423     @JsxGetter({FF, FF_ESR})
3424     public Function getOnbeforescriptexecute() {
3425         return getEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE);
3426     }
3427 
3428     /**
3429      * Sets the {@code onbeforescriptexecute} event handler for this element.
3430      * @param onbeforescriptexecute the {@code onbeforescriptexecute} event handler for this element
3431      */
3432     @JsxSetter({FF, FF_ESR})
3433     public void setOnbeforescriptexecute(final Object onbeforescriptexecute) {
3434         setEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE, onbeforescriptexecute);
3435     }
3436 
3437     /**
3438      * Returns the {@code onmozfullscreenchange} event handler for this element.
3439      * @return the {@code onmozfullscreenchange} event handler for this element
3440      */
3441     @JsxGetter({FF, FF_ESR})
3442     public Function getOnmozfullscreenchange() {
3443         return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
3444     }
3445 
3446     /**
3447      * Sets the {@code onmozfullscreenchange} event handler for this element.
3448      * @param onmozfullscreenchange the {@code onmozfullscreenchange} event handler for this element
3449      */
3450     @JsxSetter({FF, FF_ESR})
3451     public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
3452         setEventHandler(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
3453     }
3454 
3455     /**
3456      * Returns the {@code onmozfullscreenerror} event handler for this element.
3457      * @return the {@code onmozfullscreenerror} event handler for this element
3458      */
3459     @JsxGetter({FF, FF_ESR})
3460     public Function getOnmozfullscreenerror() {
3461         return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
3462     }
3463 
3464     /**
3465      * Sets the {@code onmozfullscreenerror} event handler for this element.
3466      * @param onmozfullscreenerror the {@code onmozfullscreenerror} event handler for this element
3467      */
3468     @JsxSetter({FF, FF_ESR})
3469     public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
3470         setEventHandler(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
3471     }
3472 
3473     /**
3474      * @return the {@code currentScript}
3475      */
3476     @JsxGetter
3477     public ScriptableObject getCurrentScript() {
3478         return currentScript_;
3479     }
3480 
3481     /**
3482      * @param script the {@code currentScript}
3483      */
3484     public void setCurrentScript(final ScriptableObject script) {
3485         currentScript_ = script;
3486     }
3487 
3488     /**
3489      * @return the {@code FontFaceSet}
3490      */
3491     @JsxGetter
3492     public ScriptableObject getFonts() {
3493         if (fonts_ == null) {
3494             final FontFaceSet fonts = new FontFaceSet();
3495             fonts.setParentScope(getWindow());
3496             fonts.setPrototype(getPrototype(fonts.getClass()));
3497             fonts_ = fonts;
3498         }
3499         return fonts_;
3500     }
3501 
3502     /**
3503      * Returns the value of the {@code all} property.
3504      * @return the value of the {@code all} property
3505      */
3506     @JsxGetter
3507     public HTMLCollection getAll() {
3508         final HTMLCollection all = new HTMLAllCollection(getDomNodeOrDie());
3509         all.setAvoidObjectDetection(true);
3510         all.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> true);
3511         return all;
3512     }
3513 
3514     /**
3515      * Returns the element with the specified ID, as long as it is an HTML element; {@code null} otherwise.
3516      * @param id the ID to search for
3517      * @return the element with the specified ID, as long as it is an HTML element; {@code null} otherwise
3518      */
3519     @JsxFunction
3520     public HtmlUnitScriptable getElementById(final String id) {
3521         final DomNode domNode = getDomNodeOrDie();
3522         for (final DomElement descendant : domNode.getDomElementDescendants()) {
3523             if (id.equals(descendant.getId())) {
3524                 return descendant.getScriptableObject();
3525             }
3526         }
3527         return null;
3528     }
3529 
3530     /**
3531      * Creates a new ProcessingInstruction.
3532      * @param target the target
3533      * @param data the data
3534      * @return the new ProcessingInstruction
3535      */
3536     @JsxFunction
3537     public HtmlUnitScriptable createProcessingInstruction(final String target, final String data) {
3538         final ProcessingInstruction node = getPage().createProcessingInstruction(target, data);
3539         return getScriptableFor(node);
3540     }
3541 
3542     /**
3543      * Creates a new createCDATASection.
3544      * @param data the data
3545      * @return the new CDATASection
3546      */
3547     @JsxFunction
3548     public HtmlUnitScriptable createCDATASection(final String data) {
3549         final CDATASection node = getPage().createCDATASection(data);
3550         return getScriptableFor(node);
3551     }
3552 
3553     /**
3554      * Does... nothing.
3555      * @see <a href="https://developer.mozilla.org/en/DOM/document.clear">Mozilla doc</a>
3556      */
3557     @JsxFunction
3558     public void clear() {
3559         // nothing
3560     }
3561 
3562     /**
3563      * {@inheritDoc}
3564      */
3565     @JsxFunction
3566     @Override
3567     public boolean contains(final Object element) {
3568         return getDocumentElement().contains(element);
3569     }
3570 
3571     /**
3572      * Generate and return the URL for the given blob.
3573      * @param blob the Blob containing the data
3574      * @return the URL {@link org.htmlunit.javascript.host.URL#createObjectURL(Object)}
3575      */
3576     public String generateBlobUrl(final Blob blob) {
3577         final URL url = getPage().getUrl();
3578 
3579         String origin = "null";
3580         if (!UrlUtils.URL_ABOUT_BLANK.equals(url)) {
3581             origin = url.getProtocol() + "://" + url.getAuthority();
3582         }
3583 
3584         final String blobUrl = "blob:" + origin + "/" + UUID.randomUUID();
3585         blobUrl2Blobs_.put(blobUrl, blob);
3586         return blobUrl;
3587     }
3588 
3589     /**
3590      * @param url the url to resolve
3591      * @return the Blob for the given URL or {@code null} if not found.
3592      */
3593     public Blob resolveBlobUrl(final String url) {
3594         return blobUrl2Blobs_.get(url);
3595     }
3596 
3597     /**
3598      * Revokes the URL for the given blob.
3599      * @param url the url to revoke {@link org.htmlunit.javascript.host.URL#revokeObjectURL(Scriptable)}
3600      */
3601     public void revokeBlobUrl(final String url) {
3602         blobUrl2Blobs_.remove(url);
3603     }
3604 }