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