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;
16  
17  import static org.htmlunit.BrowserVersionFeatures.EVENT_SCROLL_UIEVENT;
18  import static org.htmlunit.BrowserVersionFeatures.JS_WINDOW_SELECTION_NULL_IF_INVISIBLE;
19  import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
20  import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
21  import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
22  import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
23  
24  import java.io.IOException;
25  import java.io.ObjectInputStream;
26  import java.io.Serializable;
27  import java.lang.reflect.Method;
28  import java.net.MalformedURLException;
29  import java.net.URL;
30  import java.util.ArrayList;
31  import java.util.EnumMap;
32  import java.util.HashMap;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.function.Predicate;
36  import java.util.function.Supplier;
37  
38  import org.apache.commons.lang3.StringUtils;
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.htmlunit.AlertHandler;
42  import org.htmlunit.BrowserVersion;
43  import org.htmlunit.ConfirmHandler;
44  import org.htmlunit.ElementNotFoundException;
45  import org.htmlunit.Page;
46  import org.htmlunit.PrintHandler;
47  import org.htmlunit.PromptHandler;
48  import org.htmlunit.ScriptException;
49  import org.htmlunit.ScriptResult;
50  import org.htmlunit.SgmlPage;
51  import org.htmlunit.StatusHandler;
52  import org.htmlunit.StorageHolder.Type;
53  import org.htmlunit.TopLevelWindow;
54  import org.htmlunit.WebAssert;
55  import org.htmlunit.WebClient;
56  import org.htmlunit.WebConsole;
57  import org.htmlunit.WebWindow;
58  import org.htmlunit.WebWindowNotFoundException;
59  import org.htmlunit.corejs.javascript.AccessorSlot;
60  import org.htmlunit.corejs.javascript.Context;
61  import org.htmlunit.corejs.javascript.EcmaError;
62  import org.htmlunit.corejs.javascript.Function;
63  import org.htmlunit.corejs.javascript.JavaScriptException;
64  import org.htmlunit.corejs.javascript.NativeConsole.Level;
65  import org.htmlunit.corejs.javascript.NativeObject;
66  import org.htmlunit.corejs.javascript.Scriptable;
67  import org.htmlunit.corejs.javascript.ScriptableObject;
68  import org.htmlunit.corejs.javascript.Slot;
69  import org.htmlunit.css.ComputedCssStyleDeclaration;
70  import org.htmlunit.html.BaseFrameElement;
71  import org.htmlunit.html.DomElement;
72  import org.htmlunit.html.DomNode;
73  import org.htmlunit.html.FrameWindow;
74  import org.htmlunit.html.HtmlAnchor;
75  import org.htmlunit.html.HtmlAttributeChangeEvent;
76  import org.htmlunit.html.HtmlButton;
77  import org.htmlunit.html.HtmlElement;
78  import org.htmlunit.html.HtmlEmbed;
79  import org.htmlunit.html.HtmlForm;
80  import org.htmlunit.html.HtmlImage;
81  import org.htmlunit.html.HtmlInput;
82  import org.htmlunit.html.HtmlMap;
83  import org.htmlunit.html.HtmlObject;
84  import org.htmlunit.html.HtmlPage;
85  import org.htmlunit.html.HtmlSelect;
86  import org.htmlunit.html.HtmlTextArea;
87  import org.htmlunit.javascript.AbstractJavaScriptEngine;
88  import org.htmlunit.javascript.HtmlUnitContextFactory;
89  import org.htmlunit.javascript.HtmlUnitScriptable;
90  import org.htmlunit.javascript.JavaScriptEngine;
91  import org.htmlunit.javascript.PostponedAction;
92  import org.htmlunit.javascript.configuration.JsxClass;
93  import org.htmlunit.javascript.configuration.JsxConstant;
94  import org.htmlunit.javascript.configuration.JsxConstructor;
95  import org.htmlunit.javascript.configuration.JsxFunction;
96  import org.htmlunit.javascript.configuration.JsxGetter;
97  import org.htmlunit.javascript.configuration.JsxSetter;
98  import org.htmlunit.javascript.host.crypto.Crypto;
99  import org.htmlunit.javascript.host.css.ComputedCSSStyleDeclaration;
100 import org.htmlunit.javascript.host.css.MediaQueryList;
101 import org.htmlunit.javascript.host.css.StyleMedia;
102 import org.htmlunit.javascript.host.dom.AbstractList.EffectOnCache;
103 import org.htmlunit.javascript.host.dom.DOMException;
104 import org.htmlunit.javascript.host.dom.Document;
105 import org.htmlunit.javascript.host.dom.Node;
106 import org.htmlunit.javascript.host.dom.Selection;
107 import org.htmlunit.javascript.host.event.Event;
108 import org.htmlunit.javascript.host.event.EventTarget;
109 import org.htmlunit.javascript.host.event.MessageEvent;
110 import org.htmlunit.javascript.host.event.MouseEvent;
111 import org.htmlunit.javascript.host.event.UIEvent;
112 import org.htmlunit.javascript.host.html.DocumentProxy;
113 import org.htmlunit.javascript.host.html.HTMLCollection;
114 import org.htmlunit.javascript.host.html.HTMLDocument;
115 import org.htmlunit.javascript.host.html.HTMLElement;
116 import org.htmlunit.javascript.host.performance.Performance;
117 import org.htmlunit.javascript.host.speech.SpeechSynthesis;
118 import org.htmlunit.javascript.host.xml.XMLDocument;
119 import org.htmlunit.util.UrlUtils;
120 import org.htmlunit.xml.XmlPage;
121 
122 /**
123  * A JavaScript object for {@code Window}.
124  *
125  * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
126  * @author <a href="mailto:chen_jun@users.sourceforge.net">Chen Jun</a>
127  * @author David K. Taylor
128  * @author <a href="mailto:cse@dynabean.de">Christian Sell</a>
129  * @author Darrell DeBoer
130  * @author Marc Guillemot
131  * @author Dierk Koenig
132  * @author Daniel Gredler
133  * @author David D. Kilzer
134  * @author Chris Erskine
135  * @author Ahmed Ashour
136  * @author Ronald Brill
137  * @author Frank Danek
138  * @author Carsten Steul
139  * @author Colin Alworth
140  * @author Atsushi Nakagawa
141  * @author Sven Strickroth
142  *
143  * @see <a href="http://msdn.microsoft.com/en-us/library/ms535873.aspx">MSDN documentation</a>
144  */
145 @JsxClass
146 @SuppressWarnings("PMD.TooManyFields")
147 public class Window extends EventTarget implements WindowOrWorkerGlobalScope, AutoCloseable {
148 
149     private static final Log LOG = LogFactory.getLog(Window.class);
150 
151     /** To be documented. */
152     @JsxConstant({CHROME, EDGE})
153     public static final int TEMPORARY = 0;
154 
155     /** To be documented. */
156     @JsxConstant({CHROME, EDGE})
157     public static final int PERSISTENT = 1;
158 
159     private static final Method GETTER_LENGTH;
160     private static final Method SETTER_LENGTH;
161     private static final Method GETTER_SELF;
162     private static final Method SETTER_SELF;
163     private static final Method GETTER_PARENT;
164     private static final Method SETTER_PARENT;
165     private static final Method GETTER_FRAMES;
166     private static final Method SETTER_FRAMES;
167 
168     static {
169         try {
170             GETTER_LENGTH = Window.class.getDeclaredMethod("jsGetLength");
171             SETTER_LENGTH = Window.class.getDeclaredMethod("jsSetLength", Scriptable.class);
172 
173             GETTER_SELF = Window.class.getDeclaredMethod("jsGetSelf");
174             SETTER_SELF = Window.class.getDeclaredMethod("jsSetSelf", Scriptable.class);
175 
176             GETTER_PARENT = Window.class.getDeclaredMethod("jsGetParent");
177             SETTER_PARENT = Window.class.getDeclaredMethod("jsSetParent", Scriptable.class);
178 
179             GETTER_FRAMES = Window.class.getDeclaredMethod("jsGetFrames");
180             SETTER_FRAMES = Window.class.getDeclaredMethod("jsSetFrames", Scriptable.class);
181         }
182         catch (NoSuchMethodException | SecurityException e) {
183             throw new RuntimeException(e);
184         }
185     }
186 
187     private Scriptable lengthShadow_;
188     private Scriptable selfShadow_;
189     private Scriptable parentShadow_;
190     private Scriptable framesShadow_;
191 
192     private Document document_;
193     private DocumentProxy documentProxy_;
194     private Navigator navigator_;
195     private Object clientInformation_;
196     private WebWindow webWindow_;
197     private WindowProxy windowProxy_;
198     private Screen screen_;
199     private History history_;
200     private Location location_;
201     private Selection selection_;
202     private Event currentEvent_;
203     private String status_ = "";
204     private Map<Class<? extends Scriptable>, Scriptable> prototypes_ = new HashMap<>();
205     private Object controllers_;
206     private Object opener_;
207     private final Object top_ = NOT_FOUND; // top can be set from JS to any value!
208     private Crypto crypto_;
209     private Scriptable performance_;
210 
211     private final EnumMap<Type, Storage> storages_ = new EnumMap<>(Type.class);
212 
213     private transient List<AnimationFrame> animationFrames_ = new ArrayList<>();
214 
215     private static final class AnimationFrame {
216         private final long id_;
217         private final Function callback_;
218 
219         AnimationFrame(final long id, final Function callback) {
220             id_ = id;
221             callback_ = callback;
222         }
223     }
224 
225     /**
226      * Creates an instance.
227      *
228      * @param cx the current context
229      * @param scope the scope
230      * @param args the arguments
231      * @param ctorObj the function object
232      * @param inNewExpr Is new or not
233      * @return the java object to allow JavaScript to access
234      */
235     @JsxConstructor
236     public static Scriptable jsConstructor(final Context cx, final Scriptable scope,
237             final Object[] args, final Function ctorObj, final boolean inNewExpr) {
238         throw JavaScriptEngine.typeError("Illegal constructor");
239     }
240 
241     /**
242      * Restores the transient fields during deserialization.
243      * @param stream the stream to read the object from
244      * @throws IOException if an IO error occurs
245      * @throws ClassNotFoundException if a class is not found
246      */
247     private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException {
248         stream.defaultReadObject();
249         animationFrames_ = new ArrayList<>();
250     }
251 
252     /**
253      * Returns the prototype object corresponding to the specified HtmlUnit class inside the window scope.
254      * @param jsClass the class whose prototype is to be returned
255      * @return the prototype object corresponding to the specified class inside the specified scope
256      */
257     @Override
258     public Scriptable getPrototype(final Class<? extends HtmlUnitScriptable> jsClass) {
259         return prototypes_.get(jsClass);
260     }
261 
262     /**
263      * Sets the prototypes for HtmlUnit host classes.
264      * @param map a Map of ({@link Class}, {@link Scriptable})
265      */
266     public void setPrototypes(final Map<Class<? extends Scriptable>, Scriptable> map) {
267         prototypes_ = map;
268     }
269 
270     /**
271      * The JavaScript function {@code alert()}.
272      * @param message the message
273      */
274     @JsxFunction
275     public void alert(final Object message) {
276         // use Object as parameter and perform String conversion by ourself
277         // this allows to place breakpoint here and "see" the message object and its properties
278         final String stringMessage = JavaScriptEngine.toString(message);
279         final AlertHandler handler = getWebWindow().getWebClient().getAlertHandler();
280         if (handler == null) {
281             if (LOG.isWarnEnabled()) {
282                 LOG.warn("window.alert(\"" + stringMessage + "\") no alert handler installed");
283             }
284         }
285         else {
286             handler.handleAlert(document_.getPage(), stringMessage);
287         }
288     }
289 
290     /**
291      * Creates a base-64 encoded ASCII string from a string of binary data.
292      * @param stringToEncode string to encode
293      * @return the encoded string
294      */
295     @JsxFunction
296     @Override
297     public String btoa(final String stringToEncode) {
298         return WindowOrWorkerGlobalScopeMixin.btoa(stringToEncode, this);
299     }
300 
301     /**
302      * Decodes a string of data which has been encoded using base-64 encoding.
303      * @param encodedData the encoded string
304      * @return the decoded value
305      */
306     @JsxFunction
307     @Override
308     public String atob(final String encodedData) {
309         return WindowOrWorkerGlobalScopeMixin.atob(encodedData, this);
310     }
311 
312     /**
313      * The JavaScript function {@code confirm}.
314      * @param message the message
315      * @return true if ok was pressed, false if cancel was pressed
316      */
317     @JsxFunction
318     public boolean confirm(final String message) {
319         final ConfirmHandler handler = getWebWindow().getWebClient().getConfirmHandler();
320         if (handler == null) {
321             if (LOG.isWarnEnabled()) {
322                 LOG.warn("window.confirm(\""
323                         + message + "\") no confirm handler installed, simulating the OK button");
324             }
325             return true;
326         }
327         return handler.handleConfirm(document_.getPage(), message);
328     }
329 
330     /**
331      * The JavaScript function {@code prompt}.
332      * @param message the message
333      * @param defaultValue the default value displayed in the text input field
334      * @return the value typed in or {@code null} if the user pressed {@code cancel}
335      */
336     @JsxFunction
337     public String prompt(final String message, Object defaultValue) {
338         final PromptHandler handler = getWebWindow().getWebClient().getPromptHandler();
339         if (handler == null) {
340             if (LOG.isWarnEnabled()) {
341                 LOG.warn("window.prompt(\"" + message + "\") no prompt handler installed");
342             }
343             return null;
344         }
345         if (JavaScriptEngine.isUndefined(defaultValue)) {
346             defaultValue = null;
347         }
348         else {
349             defaultValue = JavaScriptEngine.toString(defaultValue);
350         }
351         return handler.handlePrompt(document_.getPage(), message, (String) defaultValue);
352     }
353 
354     /**
355      * Returns the JavaScript property {@code document}.
356      * @return the document
357      */
358     @JsxGetter(propertyName = "document")
359     public DocumentProxy getDocument_js() {
360         return documentProxy_;
361     }
362 
363     /**
364      * Returns the window's current document.
365      * @return the window's current document
366      */
367     public Document getDocument() {
368         return document_;
369     }
370 
371     /**
372      * Returns the current event.
373      * @return the current event, or {@code null} if no event is currently available
374      */
375     @JsxGetter
376     public Object getEvent() {
377         if (currentEvent_ == null) {
378             return JavaScriptEngine.UNDEFINED;
379         }
380         return currentEvent_;
381     }
382 
383     /**
384      * Returns the current event (used internally regardless of the emulation mode).
385      * @return the current event, or {@code null} if no event is currently available
386      */
387     public Event getCurrentEvent() {
388         return currentEvent_;
389     }
390 
391     /**
392      * Sets the current event.
393      * @param event the current event
394      */
395     public void setCurrentEvent(final Event event) {
396         currentEvent_ = event;
397     }
398 
399     /**
400      * Opens a new window.
401      *
402      * @param url when a new document is opened, <i>url</i> is a String that specifies a MIME type for the document.
403      *        When a new window is opened, <i>url</i> is a String that specifies the URL to render in the new window
404      * @param name the name
405      * @param features the features
406      * @param replace whether to replace in the history list or no
407      * @return the newly opened window, or {@code null} if popup windows have been disabled
408      * @see org.htmlunit.WebClientOptions#isPopupBlockerEnabled()
409      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536651.aspx">MSDN documentation</a>
410      */
411     @JsxFunction
412     public WindowProxy open(final Object url, final Object name, final Object features,
413             final Object replace) {
414         String urlString = null;
415         if (!JavaScriptEngine.isUndefined(url)) {
416             urlString = JavaScriptEngine.toString(url);
417         }
418         String windowName = "";
419         if (!JavaScriptEngine.isUndefined(name)) {
420             windowName = JavaScriptEngine.toString(name);
421         }
422         String featuresString = null;
423         if (!JavaScriptEngine.isUndefined(features)) {
424             featuresString = JavaScriptEngine.toString(features);
425         }
426         final WebClient webClient = getWebWindow().getWebClient();
427 
428         if (webClient.getOptions().isPopupBlockerEnabled()) {
429             LOG.debug("Ignoring window.open() invocation because popups are blocked.");
430             return null;
431         }
432 
433         boolean replaceCurrentEntryInBrowsingHistory = false;
434         if (!JavaScriptEngine.isUndefined(replace)) {
435             replaceCurrentEntryInBrowsingHistory = JavaScriptEngine.toBoolean(replace);
436         }
437         if ((featuresString != null || replaceCurrentEntryInBrowsingHistory) && LOG.isDebugEnabled()) {
438             LOG.debug(
439                    "window.open: features and replaceCurrentEntryInBrowsingHistory "
440                     + "not implemented: url=[" + urlString
441                     + "] windowName=[" + windowName
442                     + "] features=[" + featuresString
443                     + "] replaceCurrentEntry=[" + replaceCurrentEntryInBrowsingHistory
444                     + "]");
445         }
446 
447         // if specified name is the name of an existing window, then hold it
448         if (StringUtils.isEmpty(urlString) && !org.htmlunit.util.StringUtils.isEmptyString(windowName)) {
449             try {
450                 final WebWindow webWindow = webClient.getWebWindowByName(windowName);
451                 return getProxy(webWindow);
452             }
453             catch (final WebWindowNotFoundException ignored) {
454                 // nothing
455             }
456         }
457         final URL newUrl = makeUrlForOpenWindow(urlString);
458         final WebWindow newWebWindow = webClient.openWindow(newUrl, windowName, webWindow_);
459         return getProxy(newWebWindow);
460     }
461 
462     private URL makeUrlForOpenWindow(final String urlString) {
463         if (urlString.isEmpty()) {
464             return UrlUtils.URL_ABOUT_BLANK;
465         }
466 
467         try {
468             final Page page = getWebWindow().getEnclosedPage();
469             if (page != null && page.isHtmlPage()) {
470                 return ((HtmlPage) page).getFullyQualifiedUrl(urlString);
471             }
472             return new URL(urlString);
473         }
474         catch (final MalformedURLException e) {
475             if (LOG.isWarnEnabled()) {
476                 LOG.error("Unable to create URL for openWindow: relativeUrl=[" + urlString + "]", e);
477             }
478             return null;
479         }
480     }
481 
482     /**
483      * Sets a chunk of JavaScript to be invoked at some specified time later.
484      * The invocation occurs only if the window is opened after the delay
485      * and does not contain an other page than the one that originated the setTimeout.
486      *
487      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">
488      *     MDN web docs</a>
489      *
490      * @param context the JavaScript context
491      * @param scope the scope
492      * @param thisObj the scriptable
493      * @param args the arguments passed into the method
494      * @param function the function
495      * @return the id of the created timer
496      */
497     @JsxFunction
498     public static Object setTimeout(final Context context, final Scriptable scope,
499             final Scriptable thisObj, final Object[] args, final Function function) {
500         return WindowOrWorkerGlobalScopeMixin.setTimeout(context, thisObj, args, function);
501     }
502 
503     /**
504      * Sets a chunk of JavaScript to be invoked each time a specified number of milliseconds has elapsed.
505      *
506      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">
507      *     MDN web docs</a>
508      * @param context the JavaScript context
509      * @param scope the scope
510      * @param thisObj the scriptable
511      * @param args the arguments passed into the method
512      * @param function the function
513      * @return the id of the created interval
514      */
515     @JsxFunction
516     public static Object setInterval(final Context context, final Scriptable scope,
517             final Scriptable thisObj, final Object[] args, final Function function) {
518         return WindowOrWorkerGlobalScopeMixin.setInterval(context, thisObj, args, function);
519     }
520 
521     /**
522      * Cancels a time-out previously set with the
523      * {@link #setTimeout(Context, Scriptable, Scriptable, Object[], Function)} method.
524      *
525      * @param timeoutId identifier for the timeout to clear
526      *        as returned by {@link #setTimeout(Context, Scriptable, Scriptable, Object[], Function)}
527      */
528     @JsxFunction
529     public void clearTimeout(final int timeoutId) {
530         if (LOG.isDebugEnabled()) {
531             LOG.debug("clearTimeout(" + timeoutId + ")");
532         }
533         getWebWindow().getJobManager().removeJob(timeoutId);
534     }
535 
536     /**
537      * Cancels the interval previously started using the
538      * {@link #setInterval(Context, Scriptable, Scriptable, Object[], Function)} method.
539      * Current implementation does nothing.
540      * @param intervalID specifies the interval to cancel as returned by the
541      *        {@link #setInterval(Context, Scriptable, Scriptable, Object[], Function)} method
542      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536353.aspx">MSDN documentation</a>
543      */
544     @JsxFunction
545     public void clearInterval(final int intervalID) {
546         if (LOG.isDebugEnabled()) {
547             LOG.debug("clearInterval(" + intervalID + ")");
548         }
549         getWebWindow().getJobManager().removeJob(intervalID);
550     }
551 
552     /**
553      * Returns the JavaScript property {@code navigator}.
554      * @return the navigator
555      */
556     @JsxGetter
557     public Navigator getNavigator() {
558         return navigator_;
559     }
560 
561     /**
562      * Returns the JavaScript property {@code clientInformation}.
563      * @return the client information
564      */
565     @JsxGetter
566     public Object getClientInformation() {
567         if (clientInformation_ != null) {
568             return clientInformation_;
569         }
570         return navigator_;
571     }
572 
573     /**
574      * @param clientInformation the new value
575      */
576     @JsxSetter({CHROME, EDGE, FF})
577     public void setClientInformation(final Object clientInformation) {
578         clientInformation_ = clientInformation;
579     }
580 
581     /**
582      * Returns the window property. This is a synonym for {@code self}.
583      * @return the window property (a reference to <code>this</code>)
584      */
585     @JsxGetter(propertyName = "window")
586     public Window getWindow_js() {
587         return this;
588     }
589 
590     /**
591      * Returns the {@code localStorage} property.
592      * @return the {@code localStorage} property
593      */
594     @JsxGetter
595     public Storage getLocalStorage() {
596         return getStorage(Type.LOCAL_STORAGE);
597     }
598 
599     /**
600      * Returns the {@code sessionStorage} property.
601      * @return the {@code sessionStorage} property
602      */
603     @JsxGetter
604     public Storage getSessionStorage() {
605         return getStorage(Type.SESSION_STORAGE);
606     }
607 
608     /**
609      * Gets the storage of the specified type.
610      * @param storageType the type
611      * @return the storage
612      */
613     public Storage getStorage(final Type storageType) {
614         return storages_.computeIfAbsent(storageType,
615             k -> {
616                 final WebWindow webWindow = getWebWindow();
617                 final Map<String, String> store = webWindow.getWebClient().getStorageHolder().
618                         getStore(storageType, webWindow.getEnclosedPage());
619                 return new Storage(this, store);
620             }
621         );
622     }
623 
624     /**
625      * Returns the {@code location} property.
626      * @return the {@code location} property
627      */
628     @JsxGetter
629     public Location getLocation() {
630         return location_;
631     }
632 
633     /**
634      * Sets the {@code location} property. This will cause a reload of the window.
635      * @param newLocation the URL of the new content
636      * @throws IOException when location loading fails
637      */
638     @JsxSetter
639     public void setLocation(final String newLocation) throws IOException {
640         location_.setHref(newLocation);
641     }
642 
643     /**
644      * Logs messages to the browser's standard output (stdout). If the browser was started
645      * from a terminal, output sent to dump() will appear in the terminal.
646      * Output from dump() is not sent to the browser's developer tools console.
647      * To log to the developer tools console, use console.log().
648      * <p>
649      * HtmlUnit always uses the WebConsole.
650      *
651      * @param message the message to log
652      */
653     @JsxFunction({FF, FF_ESR})
654     public void dump(final String message) {
655         final WebConsole console = getWebWindow().getWebClient().getWebConsole();
656         console.print(Context.getCurrentContext(), this, Level.INFO, new String[] {message}, null);
657     }
658 
659     /**
660      * Invokes all the animation callbacks registered for this window by
661      * calling {@link #requestAnimationFrame(Object)} once.
662      * @return the number of pending animation callbacks
663      */
664     public int animateAnimationsFrames() {
665         final List<AnimationFrame> animationFrames = new ArrayList<>(animationFrames_);
666         animationFrames_.clear();
667 
668         final double now = System.nanoTime() / 1_000_000d;
669         final Object[] args = {now};
670 
671         final WebWindow ww = getWindow().getWebWindow();
672         final JavaScriptEngine jsEngine = (JavaScriptEngine) ww.getWebClient().getJavaScriptEngine();
673 
674         for (final AnimationFrame animationFrame : animationFrames) {
675             jsEngine.callFunction((HtmlPage) ww.getEnclosedPage(),
676                         animationFrame.callback_, this, getParentScope(), args);
677         }
678         return animationFrames_.size();
679     }
680 
681     /**
682      * Add callback to the list of animationFrames.
683      * @param callback the function to call when it's time to update the animation
684      * @return an identification id
685      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame">MDN Doc</a>
686      */
687     @JsxFunction
688     public int requestAnimationFrame(final Object callback) {
689         if (callback instanceof Function) {
690             final int id = animationFrames_.size();
691             final AnimationFrame animationFrame = new AnimationFrame(id, (Function) callback);
692             animationFrames_.add(animationFrame);
693             return id;
694         }
695         return -1;
696     }
697 
698     /**
699      * Remove the callback from the list of animationFrames.
700      * @param requestId the ID value returned by the call to window.requestAnimationFrame()
701      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame">MDN Doc</a>
702      */
703     @JsxFunction
704     public void cancelAnimationFrame(final Object requestId) {
705         final int id = (int) JavaScriptEngine.toNumber(requestId);
706 
707         animationFrames_.removeIf(animationFrame -> animationFrame.id_ == id);
708     }
709 
710     /**
711      * Returns the {@code screen} property.
712      * @return the {@code screen} property
713      */
714     @JsxGetter
715     public Screen getScreen() {
716         return screen_;
717     }
718 
719     /**
720      * Returns the {@code history} property.
721      * @return the {@code history} property
722      */
723     @JsxGetter
724     public History getHistory() {
725         return history_;
726     }
727 
728     /**
729      * Returns the {@code external} property.
730      * @return the {@code external} property
731      */
732     @JsxGetter
733     public External getExternal() {
734         final External external = new External();
735         external.setParentScope(this);
736         external.setPrototype(getPrototype(external.getClass()));
737         return external;
738     }
739 
740     /**
741      * Initializes this window.
742      * @param webWindow the web window corresponding to this window
743      * @param pageToEnclose the page that will become the enclosing page
744      */
745     public void initialize(final WebWindow webWindow, final Page pageToEnclose) {
746         webWindow_ = webWindow;
747         webWindow_.setScriptableObject(this);
748 
749         defineProperty("length", null, GETTER_LENGTH, SETTER_LENGTH, ScriptableObject.READONLY);
750         defineProperty("self", null, GETTER_SELF, SETTER_SELF, ScriptableObject.READONLY);
751         defineProperty("parent", null, GETTER_PARENT, SETTER_PARENT, ScriptableObject.READONLY);
752         defineProperty("frames", null, GETTER_FRAMES, SETTER_FRAMES, ScriptableObject.READONLY);
753 
754         windowProxy_ = new WindowProxy(webWindow_);
755 
756         if (pageToEnclose instanceof XmlPage) {
757             document_ = new XMLDocument();
758         }
759         else {
760             document_ = new HTMLDocument();
761         }
762         document_.setParentScope(this);
763         document_.setPrototype(getPrototype(document_.getClass()));
764         document_.setWindow(this);
765 
766         if (pageToEnclose instanceof SgmlPage) {
767             final SgmlPage page = (SgmlPage) pageToEnclose;
768             document_.setDomNode(page);
769 
770             if (page.isHtmlPage()) {
771                 final HtmlPage htmlPage = (HtmlPage) page;
772 
773                 htmlPage.addAutoCloseable(this);
774             }
775         }
776 
777         documentProxy_ = new DocumentProxy(webWindow_);
778 
779         navigator_ = new Navigator();
780         navigator_.setParentScope(this);
781         navigator_.setPrototype(getPrototype(navigator_.getClass()));
782 
783         screen_ = new Screen(getWebWindow().getScreen());
784         screen_.setParentScope(this);
785         screen_.setPrototype(getPrototype(screen_.getClass()));
786 
787         history_ = new History();
788         history_.setParentScope(this);
789         history_.setPrototype(getPrototype(history_.getClass()));
790 
791         location_ = new Location();
792         location_.setParentScope(this);
793         location_.setPrototype(getPrototype(location_.getClass()));
794         location_.jsConstructor();
795         location_.initialize(this, pageToEnclose);
796 
797         // like a JS new Object()
798         final Context ctx = Context.getCurrentContext();
799         controllers_ = ctx.newObject(this);
800 
801         if (webWindow_ instanceof TopLevelWindow) {
802             final WebWindow opener = ((TopLevelWindow) webWindow_).getOpener();
803             if (opener != null) {
804                 opener_ = opener.getScriptableObject();
805             }
806         }
807     }
808 
809     /**
810      * Initialize the object.
811      * @param enclosedPage the page containing the JavaScript
812      */
813     public void initialize(final Page enclosedPage) {
814         if (enclosedPage != null && enclosedPage.isHtmlPage()) {
815             final HtmlPage htmlPage = (HtmlPage) enclosedPage;
816 
817             // Windows don't have corresponding DomNodes so set the domNode
818             // variable to be the page. If this isn't set then HtmlUnitScriptable.get()
819             // won't work properly
820             setDomNode(htmlPage);
821             clearEventListenersContainer();
822 
823             WebAssert.notNull("document_", document_);
824             document_.setDomNode(htmlPage);
825         }
826     }
827 
828     /**
829      * Initializes the object. Only called for Windows with no contents.
830      */
831     public void initialize() {
832         // Empty.
833     }
834 
835     /**
836      * Returns the value of the {@code top} property.
837      * @return the value of {@code top}
838      */
839     @JsxGetter
840     public Object getTop() {
841         if (top_ != NOT_FOUND) {
842             return top_;
843         }
844 
845         final WebWindow top = getWebWindow().getTopWindow();
846         return top.getScriptableObject();
847     }
848 
849     /**
850      * Sets the value of the {@code top} property.
851      * @param o the new value
852      */
853     @JsxSetter
854     public void setTop(final Object o) {
855         // ignore
856     }
857 
858     /**
859      * Returns the value of the {@code opener} property.
860      * @return the value of the {@code opener}, or {@code null} for a top level window
861      */
862     @JsxGetter
863     public Object getOpener() {
864         Object opener = opener_;
865         if (opener instanceof Window) {
866             opener = ((Window) opener).windowProxy_;
867         }
868         return opener;
869     }
870 
871     /**
872      * Sets the {@code opener} property.
873      * @param newValue the new value
874      */
875     @JsxSetter
876     public void setOpener(final Object newValue) {
877         opener_ = newValue;
878     }
879 
880     /**
881      * Returns the (i)frame in which the window is contained.
882      * @return {@code null} for a top level window
883      */
884     @JsxGetter
885     public HtmlUnitScriptable getFrameElement() {
886         final WebWindow window = getWebWindow();
887         if (window instanceof FrameWindow) {
888             return ((FrameWindow) window).getFrameElement().getScriptableObject();
889         }
890         return null;
891     }
892 
893     /**
894      * Returns the number of frames contained by this window.
895      * @return the number of frames contained by this window
896      */
897     @JsxGetter
898     public Object getLength() {
899         return JavaScriptEngine.UNDEFINED;
900     }
901 
902     /**
903      * Gets the {@code length} property. Setting this shadows the
904      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
905      * @return the shadow value if set otherwise the number of frames
906      */
907     public Object jsGetLength() {
908         if (lengthShadow_ != null) {
909             return lengthShadow_;
910         }
911 
912         final HTMLCollection frames = getFrames();
913         if (frames != null) {
914             return frames.getLength();
915         }
916         return 0;
917     }
918 
919     /**
920      * Sets the {@code length} property. Setting this shadows the
921      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
922      * @param lengthShadow the value to overwrite the defined property value
923      */
924     public void jsSetLength(final Scriptable lengthShadow) {
925         lengthShadow_ = lengthShadow;
926     }
927 
928     /**
929      * Returns the {@code self} property.
930      * @return this
931      */
932     @JsxGetter
933     public Object getSelf() {
934         return JavaScriptEngine.UNDEFINED;
935     }
936 
937     /**
938      * Gets the {@code self} property. Setting this shadows the
939      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
940      * @return the shadow value if set otherwise the number of frames
941      */
942     public Object jsGetSelf() {
943         if (selfShadow_ != null) {
944             return selfShadow_;
945         }
946 
947         return this;
948     }
949 
950     /**
951      * Sets the {@code self} property. Setting this shadows the
952      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
953      * @param selfShadow the value to overwrite the defined property value
954      */
955     public void jsSetSelf(final Scriptable selfShadow) {
956         selfShadow_ = selfShadow;
957     }
958 
959     /**
960      * Returns the value of the {@code parent} property.
961      * @return the value of the {@code parent} property
962      */
963     @JsxGetter
964     public Object getParent() {
965         return JavaScriptEngine.UNDEFINED;
966     }
967 
968     /**
969      * Gets the {@code parent} property. Setting this shadows the
970      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
971      * @return the shadow value if set otherwise the number of frames
972      */
973     public Object jsGetParent() {
974         if (parentShadow_ != null) {
975             return parentShadow_;
976         }
977 
978         final WebWindow parent = getWebWindow().getParentWindow();
979         return parent.getScriptableObject();
980     }
981 
982     /**
983      * Sets the {@code parent} property. Setting this shadows the
984      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
985      * @param parentShadow the value to overwrite the defined property value
986      */
987     public void jsSetParent(final Scriptable parentShadow) {
988         parentShadow_ = parentShadow;
989     }
990 
991     /**
992      * Returns the value of the {@code frames} property.
993      * @return the value of the {@code frames} property
994      */
995     @JsxGetter(propertyName = "frames")
996     public Object getFrames_js() {
997         return JavaScriptEngine.UNDEFINED;
998     }
999 
1000     /**
1001      * Gets the {@code frames} property. Setting this shadows the
1002      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
1003      * @return the shadow value if set otherwise the number of frames
1004      */
1005     public Object jsGetFrames() {
1006         if (framesShadow_ != null) {
1007             return framesShadow_;
1008         }
1009 
1010         return this;
1011     }
1012 
1013     /**
1014      * Sets the {@code frames} property. Setting this shadows the
1015      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
1016      * @param framesShadow the value to overwrite the defined property value
1017      */
1018     public void jsSetFrames(final Scriptable framesShadow) {
1019         framesShadow_ = framesShadow;
1020     }
1021 
1022     /**
1023      * Returns the live collection of frames contained by this window.
1024      * @return the live collection of frames contained by this window
1025      */
1026     private HTMLCollection getFrames() {
1027         final Page page = getWebWindow().getEnclosedPage();
1028         if (page instanceof HtmlPage) {
1029             return new HTMLCollectionFrames((HtmlPage) page);
1030         }
1031         return null;
1032     }
1033 
1034     /**
1035      * Returns the WebWindow associated with this Window.
1036      * @return the WebWindow
1037      */
1038     public WebWindow getWebWindow() {
1039         return webWindow_;
1040     }
1041 
1042     /**
1043      * Sets the focus to this element.
1044      */
1045     @JsxFunction
1046     public void focus() {
1047         final WebWindow window = getWebWindow();
1048         window.getWebClient().setCurrentWindow(window);
1049     }
1050 
1051     /**
1052      * Removes focus from this element.
1053      */
1054     @JsxFunction
1055     public void blur() {
1056         LOG.debug("window.blur() not implemented");
1057     }
1058 
1059     /**
1060      * Closes this window.
1061      */
1062     @JsxFunction(functionName = "close")
1063     public void close_js() {
1064         final WebWindow webWindow = getWebWindow();
1065         if (webWindow instanceof TopLevelWindow) {
1066             ((TopLevelWindow) webWindow).close();
1067         }
1068         else {
1069             webWindow.getWebClient().deregisterWebWindow(webWindow);
1070         }
1071     }
1072 
1073     /**
1074      * Indicates if this window is closed.
1075      * @return {@code true} if this window is closed
1076      */
1077     @JsxGetter
1078     public boolean isClosed() {
1079         final WebWindow webWindow = getWebWindow();
1080         return !webWindow.getWebClient().containsWebWindow(webWindow);
1081     }
1082 
1083     /**
1084      * Does nothing.
1085      * @param x the horizontal position
1086      * @param y the vertical position
1087      */
1088     @JsxFunction
1089     public void moveTo(final int x, final int y) {
1090         LOG.debug("window.moveTo() not implemented");
1091     }
1092 
1093     /**
1094      * Does nothing.
1095      * @param x the horizontal position
1096      * @param y the vertical position
1097      */
1098     @JsxFunction
1099     public void moveBy(final int x, final int y) {
1100         LOG.debug("window.moveBy() not implemented");
1101     }
1102 
1103     /**
1104      * Does nothing.
1105      * @param width the width offset
1106      * @param height the height offset
1107      */
1108     @JsxFunction
1109     public void resizeBy(final int width, final int height) {
1110         LOG.debug("window.resizeBy() not implemented");
1111     }
1112 
1113     /**
1114      * Does nothing.
1115      * @param width the width of the Window in pixel after resize
1116      * @param height the height of the Window in pixel after resize
1117      */
1118     @JsxFunction
1119     public void resizeTo(final int width, final int height) {
1120         LOG.debug("window.resizeTo() not implemented");
1121     }
1122 
1123     /**
1124      * Scrolls to the specified location on the page.
1125      * @param x the horizontal position to scroll to
1126      * @param y the vertical position to scroll to
1127      */
1128     @JsxFunction
1129     public void scroll(final Scriptable x, final Scriptable y) {
1130         scrollTo(x, y);
1131     }
1132 
1133     /**
1134      * Scrolls the window content the specified distance.
1135      * @param x the horizontal distance to scroll by
1136      * @param y the vertical distance to scroll by
1137      */
1138     @JsxFunction
1139     public void scrollBy(final Scriptable x, final Scriptable y) {
1140         final HTMLElement body = document_.getBody();
1141         if (body != null) {
1142             int xOff = 0;
1143             int yOff = 0;
1144             if (y != null) {
1145                 xOff = JavaScriptEngine.toInt32(x);
1146                 yOff = JavaScriptEngine.toInt32(y);
1147             }
1148             else {
1149                 if (!(x instanceof NativeObject)) {
1150                     throw JavaScriptEngine.typeError("eee");
1151                 }
1152                 if (x.has("left", x)) {
1153                     xOff = JavaScriptEngine.toInt32(x.get("left", x));
1154                 }
1155                 if (x.has("top", x)) {
1156                     yOff = JavaScriptEngine.toInt32(x.get("top", x));
1157                 }
1158             }
1159 
1160             body.setScrollLeft(body.getScrollLeft() + xOff);
1161             body.setScrollTop(body.getScrollTop() + yOff);
1162 
1163             fireScrollEvent(body);
1164         }
1165 
1166         fireScrollEvent(document_);
1167     }
1168 
1169     private void fireScrollEvent(final Node node) {
1170         final Event event;
1171         if (getBrowserVersion().hasFeature(EVENT_SCROLL_UIEVENT)) {
1172             event = new UIEvent(node, Event.TYPE_SCROLL);
1173         }
1174         else {
1175             event = new Event(node, Event.TYPE_SCROLL);
1176             event.setCancelable(false);
1177         }
1178         node.fireEvent(event);
1179     }
1180 
1181     /**
1182      * Scrolls the window content down by the specified number of lines.
1183      * @param lines the number of lines to scroll down
1184      */
1185     @JsxFunction({FF, FF_ESR})
1186     public void scrollByLines(final int lines) {
1187         final HTMLElement body = document_.getBody();
1188         if (body != null) {
1189             body.setScrollTop(body.getScrollTop() + (19 * lines));
1190 
1191             fireScrollEvent(body);
1192         }
1193 
1194         fireScrollEvent(document_);
1195     }
1196 
1197     /**
1198      * Scrolls the window content down by the specified number of pages.
1199      * @param pages the number of pages to scroll down
1200      */
1201     @JsxFunction({FF, FF_ESR})
1202     public void scrollByPages(final int pages) {
1203         final HTMLElement body = document_.getBody();
1204         if (body != null) {
1205             body.setScrollTop(body.getScrollTop() + (getInnerHeight() * pages));
1206 
1207             fireScrollEvent(body);
1208         }
1209 
1210         fireScrollEvent(document_);
1211     }
1212 
1213     /**
1214      * Scrolls to the specified location on the page.
1215      * @param x the horizontal position to scroll to
1216      * @param y the vertical position to scroll to
1217      */
1218     @JsxFunction
1219     public void scrollTo(final Scriptable x, final Scriptable y) {
1220         final HTMLElement body = document_.getBody();
1221         if (body != null) {
1222             int xOff = 0;
1223             int yOff = 0;
1224             if (y != null) {
1225                 xOff = JavaScriptEngine.toInt32(x);
1226                 yOff = JavaScriptEngine.toInt32(y);
1227             }
1228             else {
1229                 if (!(x instanceof NativeObject)) {
1230                     throw JavaScriptEngine.typeError("eee");
1231                 }
1232 
1233                 xOff = body.getScrollLeft();
1234                 yOff = body.getScrollTop();
1235 
1236                 if (x.has("left", x)) {
1237                     xOff = JavaScriptEngine.toInt32(x.get("left", x));
1238                 }
1239                 if (x.has("top", x)) {
1240                     yOff = JavaScriptEngine.toInt32(x.get("top", x));
1241                 }
1242             }
1243             body.setScrollLeft(xOff);
1244             body.setScrollTop(yOff);
1245 
1246             fireScrollEvent(body);
1247         }
1248 
1249         fireScrollEvent(document_);
1250     }
1251 
1252     /**
1253      * Returns the {@code onload} property. Note that this is not necessarily a function if something else has been set.
1254      * @return the {@code onload} property
1255      */
1256     @JsxGetter
1257     public Function getOnload() {
1258         return getEventHandler(Event.TYPE_LOAD);
1259     }
1260 
1261     /**
1262      * Sets the value of the {@code onload} event handler.
1263      * @param onload the new handler
1264      */
1265     @JsxSetter
1266     public void setOnload(final Object onload) {
1267         setHandlerForJavaScript(Event.TYPE_LOAD, onload);
1268     }
1269 
1270     /**
1271      * Sets the value of the {@code onblur} event handler.
1272      * @param onblur the new handler
1273      */
1274     @JsxSetter
1275     public void setOnblur(final Object onblur) {
1276         setHandlerForJavaScript(Event.TYPE_BLUR, onblur);
1277     }
1278 
1279     /**
1280      * Returns the {@code onblur} property (not necessary a function if something else has been set).
1281      * @return the {@code onblur} property
1282      */
1283     @JsxGetter
1284     public Function getOnblur() {
1285         return getEventHandler(Event.TYPE_BLUR);
1286     }
1287 
1288     /**
1289      * Returns the {@code onclick} property (not necessary a function if something else has been set).
1290      * @return the {@code onclick} property
1291      */
1292     @JsxGetter
1293     public Function getOnclick() {
1294         return getEventHandler(MouseEvent.TYPE_CLICK);
1295     }
1296 
1297     /**
1298      * Sets the value of the {@code onclick} event handler.
1299      * @param onclick the new handler
1300      */
1301     @JsxSetter
1302     public void setOnclick(final Object onclick) {
1303         setHandlerForJavaScript(MouseEvent.TYPE_CLICK, onclick);
1304     }
1305 
1306     /**
1307      * Returns the {@code ondblclick} property (not necessary a function if something else has been set).
1308      * @return the {@code ondblclick} property
1309      */
1310     @JsxGetter
1311     public Function getOndblclick() {
1312         return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
1313     }
1314 
1315     /**
1316      * Sets the value of the {@code ondblclick} event handler.
1317      * @param ondblclick the new handler
1318      */
1319     @JsxSetter
1320     public void setOndblclick(final Object ondblclick) {
1321         setHandlerForJavaScript(MouseEvent.TYPE_DBL_CLICK, ondblclick);
1322     }
1323 
1324     /**
1325      * Returns the {@code onhashchange} property (not necessary a function if something else has been set).
1326      * @return the {@code onhashchange} property
1327      */
1328     @JsxGetter
1329     public Function getOnhashchange() {
1330         return getEventHandler(Event.TYPE_HASH_CHANGE);
1331     }
1332 
1333     /**
1334      * Sets the value of the {@code onhashchange} event handler.
1335      * @param onhashchange the new handler
1336      */
1337     @JsxSetter
1338     public void setOnhashchange(final Object onhashchange) {
1339         setHandlerForJavaScript(Event.TYPE_HASH_CHANGE, onhashchange);
1340     }
1341 
1342     /**
1343      * Returns the value of the window's {@code name} property.
1344      * @return the value of the window's {@code name} property
1345      */
1346     @JsxGetter
1347     public String getName() {
1348         return getWebWindow().getName();
1349     }
1350 
1351      /**
1352       * Sets the value of the window's {@code name} property.
1353       * @param name the value of the window's {@code name} property
1354       */
1355     @JsxSetter
1356     public void setName(final String name) {
1357         getWebWindow().setName(name);
1358     }
1359 
1360     /**
1361      * Returns the value of the window's {@code onbeforeunload} property.
1362      * @return the value of the window's {@code onbeforeunload} property
1363      */
1364     @JsxGetter
1365     public Function getOnbeforeunload() {
1366         return getEventHandler(Event.TYPE_BEFORE_UNLOAD);
1367     }
1368 
1369     /**
1370      * Sets the value of the window's {@code onbeforeunload} property.
1371      * @param onbeforeunload the value of the window's {@code onbeforeunload} property
1372      */
1373     @JsxSetter
1374     public void setOnbeforeunload(final Object onbeforeunload) {
1375         setHandlerForJavaScript(Event.TYPE_BEFORE_UNLOAD, onbeforeunload);
1376     }
1377 
1378     /**
1379      * Returns the value of the window's {@code onerror} property.
1380      * @return the value of the window's {@code onerror} property
1381      */
1382     @JsxGetter
1383     public Function getOnerror() {
1384         return getEventHandler(Event.TYPE_ERROR);
1385     }
1386 
1387     /**
1388      * Sets the value of the window's {@code onerror} property.
1389      * @param onerror the value of the window's {@code onerror} property
1390      */
1391     @JsxSetter
1392     public void setOnerror(final Object onerror) {
1393         setHandlerForJavaScript(Event.TYPE_ERROR, onerror);
1394     }
1395 
1396     /**
1397      * Returns the value of the window's {@code onmessage} property.
1398      * @return the value of the window's {@code onmessage} property
1399      */
1400     @JsxGetter
1401     public Function getOnmessage() {
1402         return getEventHandler(Event.TYPE_MESSAGE);
1403     }
1404 
1405     /**
1406      * Sets the value of the window's {@code onmessage} property.
1407      * @param onmessage the value of the window's {@code onmessage} property
1408      */
1409     @JsxSetter
1410     public void setOnmessage(final Object onmessage) {
1411         setHandlerForJavaScript(Event.TYPE_MESSAGE, onmessage);
1412     }
1413 
1414     /**
1415      * Triggers the {@code onerror} handler, if one has been set.
1416      * @param e the error that needs to be reported
1417      */
1418     public void triggerOnError(final ScriptException e) {
1419         final Function f = getOnerror();
1420         if (f != null) {
1421             String msg = e.getMessage();
1422             final String url = e.getPage().getUrl().toExternalForm();
1423 
1424             final int line = e.getFailingLineNumber();
1425             final int column = e.getFailingColumnNumber();
1426 
1427             Object jsError = e.getMessage();
1428             if (e.getCause() instanceof JavaScriptException) {
1429                 msg = "uncaught exception: " + e.getCause().getMessage();
1430                 jsError = ((JavaScriptException) e.getCause()).getValue();
1431             }
1432             else if (e.getCause() instanceof EcmaError) {
1433                 msg = "uncaught " + e.getCause().getMessage();
1434 
1435                 final EcmaError ecmaError = (EcmaError) e.getCause();
1436                 final Scriptable err = Context.getCurrentContext().newObject(this, "Error");
1437                 ScriptableObject.putProperty(err, "message", ecmaError.getMessage());
1438                 ScriptableObject.putProperty(err, "fileName", ecmaError.sourceName());
1439                 ScriptableObject.putProperty(err, "lineNumber", Integer.valueOf(ecmaError.lineNumber()));
1440                 jsError = err;
1441             }
1442 
1443             final Object[] args = {msg, url, Integer.valueOf(line), Integer.valueOf(column), jsError};
1444             f.call(Context.getCurrentContext(), this, this, args);
1445         }
1446     }
1447 
1448     private void setHandlerForJavaScript(final String eventName, final Object handler) {
1449         getEventListenersContainer().setEventHandler(eventName, handler);
1450     }
1451 
1452     /**
1453      * {@inheritDoc}
1454      */
1455     @Override
1456     protected Object getWithPreemption(final String name) {
1457         final DomNode domNode = getDomNodeOrNull();
1458         if (domNode == null) {
1459             return NOT_FOUND;
1460         }
1461 
1462         // May be attempting to retrieve a frame by name.
1463         final HtmlPage page = (HtmlPage) domNode.getPage();
1464         Object result = getFrameWindowByName(page, name);
1465 
1466         if (result == NOT_FOUND) {
1467             result = getElementsByName(page, name);
1468 
1469             if (result == NOT_FOUND) {
1470                 // May be attempting to retrieve element by ID (try map-backed operation again instead of XPath).
1471                 try {
1472                     final HtmlElement htmlElement = page.getHtmlElementById(name);
1473                     result = getScriptableFor(htmlElement);
1474                 }
1475                 catch (final ElementNotFoundException e) {
1476                     result = NOT_FOUND;
1477                 }
1478             }
1479         }
1480 
1481         if (result instanceof Window) {
1482             final WebWindow webWindow = ((Window) result).getWebWindow();
1483             result = getProxy(webWindow);
1484         }
1485 
1486         return result;
1487     }
1488 
1489     /**
1490      * {@inheritDoc}
1491      */
1492     @Override
1493     public Object get(final int index, final Scriptable start) {
1494         if (index < 0 || getWebWindow() == null) {
1495             return JavaScriptEngine.UNDEFINED;
1496         }
1497 
1498         final HTMLCollection frames = getFrames();
1499         if (frames == null || index >= frames.getLength()) {
1500             return JavaScriptEngine.UNDEFINED;
1501         }
1502         return frames.item(Integer.valueOf(index));
1503     }
1504 
1505     private static Object getFrameWindowByName(final HtmlPage page, final String name) {
1506         try {
1507             return page.getFrameByName(name).getScriptableObject();
1508         }
1509         catch (final ElementNotFoundException e) {
1510             return NOT_FOUND;
1511         }
1512     }
1513 
1514     private Object getElementsByName(final HtmlPage page, final String name) {
1515 
1516         // May be attempting to retrieve element(s) by name. IMPORTANT: We're using map-backed operations
1517         // like getHtmlElementsByName() and getHtmlElementById() as much as possible, so as to avoid XPath
1518         // overhead. We only use an XPath-based operation when we have to (where there is more than one
1519         // matching element). This optimization appears to improve performance in certain situations by ~15%
1520         // vs using XPath-based operations throughout.
1521         final List<DomElement> elements = page.getElementsByName(name);
1522 
1523         final Filter filter = new Filter(false);
1524 
1525         elements.removeIf(domElement -> !filter.matches(domElement));
1526 
1527         if (elements.isEmpty()) {
1528             return NOT_FOUND;
1529         }
1530 
1531         if (elements.size() == 1) {
1532             return getScriptableFor(elements.get(0));
1533         }
1534 
1535         // Null must be changed to '' for proper collection initialization.
1536         final String expElementName = "null".equals(name) ? "" : name;
1537 
1538         final HTMLCollection coll = new HTMLCollection(page, true);
1539         coll.setElementsSupplier(
1540                 (Supplier<List<DomNode>> & Serializable)
1541                 () -> {
1542                     final List<DomElement> expElements = page.getElementsByName(expElementName);
1543                     final List<DomNode> result = new ArrayList<>(expElements.size());
1544 
1545                     for (final DomElement domElement : expElements) {
1546                         if (filter.matches(domElement)) {
1547                             result.add(domElement);
1548                         }
1549                     }
1550                     return result;
1551                 });
1552 
1553         coll.setEffectOnCacheFunction(
1554                 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1555                 event -> {
1556                     if ("name".equals(event.getName())) {
1557                         return EffectOnCache.RESET;
1558                     }
1559                     return EffectOnCache.NONE;
1560                 });
1561 
1562         return coll;
1563     }
1564 
1565     /**
1566      * Returns the proxy for the specified window.
1567      * @param w the window whose proxy is to be returned
1568      * @return the proxy for the specified window
1569      */
1570     public static WindowProxy getProxy(final WebWindow w) {
1571         return ((Window) w.getScriptableObject()).windowProxy_;
1572     }
1573 
1574     /**
1575      * Returns the text from the status line.
1576      * @return the status line text
1577      */
1578     @JsxGetter
1579     public String getStatus() {
1580         return status_;
1581     }
1582 
1583     /**
1584      * Sets the text from the status line.
1585      * @param message the status line text
1586      */
1587     @JsxSetter
1588     public void setStatus(final String message) {
1589         status_ = message;
1590 
1591         final StatusHandler statusHandler = webWindow_.getWebClient().getStatusHandler();
1592         if (statusHandler != null) {
1593             statusHandler.statusMessageChanged(webWindow_.getEnclosedPage(), message);
1594         }
1595     }
1596 
1597     /**
1598      * Returns the {@code innerWidth}.
1599      * @return the {@code innerWidth}
1600      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref28.html">Mozilla doc</a>
1601      */
1602     @JsxGetter
1603     public int getInnerWidth() {
1604         return getWebWindow().getInnerWidth();
1605     }
1606 
1607     /**
1608      * Sets the {@code innerWidth}.
1609      * @param width the {@code innerWidth}
1610      */
1611     @JsxSetter
1612     public void setInnerWidth(final int width) {
1613         getWebWindow().setInnerWidth(width);
1614     }
1615 
1616     /**
1617      * Returns the {@code outerWidth}.
1618      * @return the {@code outerWidth}
1619      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref79.html">Mozilla doc</a>
1620      */
1621     @JsxGetter
1622     public int getOuterWidth() {
1623         return getWebWindow().getOuterWidth();
1624     }
1625 
1626     /**
1627      * Sets the {@code outerWidth}.
1628      * @param width the {@code outerWidth}
1629      */
1630     @JsxSetter
1631     public void setOuterWidth(final int width) {
1632         getWebWindow().setOuterWidth(width);
1633     }
1634 
1635     /**
1636      * Returns the {@code innerHeight}.
1637      * @return the {@code innerHeight}
1638      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref27.html">Mozilla doc</a>
1639      */
1640     @JsxGetter
1641     public int getInnerHeight() {
1642         return getWebWindow().getInnerHeight();
1643     }
1644 
1645     /**
1646      * Sets the {@code innerHeight}.
1647      * @param height the {@code innerHeight}
1648      */
1649     @JsxSetter
1650     public void setInnerHeight(final int height) {
1651         getWebWindow().setInnerHeight(height);
1652     }
1653 
1654     /**
1655      * Returns the {@code outerHeight}.
1656      * @return the {@code outerHeight}
1657      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref78.html">Mozilla doc</a>
1658      */
1659     @JsxGetter
1660     public int getOuterHeight() {
1661         return getWebWindow().getOuterHeight();
1662     }
1663 
1664     /**
1665      * Sets the {@code outerHeight}.
1666      * @param height the {@code outerHeight}
1667      */
1668     @JsxSetter
1669     public void setOuterHeight(final int height) {
1670         getWebWindow().setOuterHeight(height);
1671     }
1672 
1673     /**
1674      * Prints the current page. The current implementation uses the {@link PrintHandler}
1675      * defined for the {@link WebClient} to process the window.
1676      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref85.html">
1677      *     Mozilla documentation</a>
1678      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536672.aspx">MSDN documentation</a>
1679      */
1680     @JsxFunction
1681     public void print() {
1682         final PrintHandler handler = getWebWindow().getWebClient().getPrintHandler();
1683         if (handler == null) {
1684             LOG.info("No PrintHandler installed - window.print() ignored");
1685             return;
1686         }
1687 
1688         final SgmlPage sgmlPage = getDocument().getPage();
1689         if (!(sgmlPage instanceof HtmlPage)) {
1690             LOG.debug("Page is not an HtmlPage - window.print() ignored");
1691             return;
1692         }
1693 
1694         Event event = new Event(this, Event.TYPE_BEFOREPRINT);
1695         fireEvent(event);
1696 
1697         final HtmlPage page = (HtmlPage) sgmlPage;
1698         page.setPrinting(true);
1699         try {
1700             handler.handlePrint(page);
1701         }
1702         finally {
1703             page.setPrinting(false);
1704         }
1705         event = new Event(this, Event.TYPE_AFTERPRINT);
1706         fireEvent(event);
1707     }
1708 
1709     /**
1710      * Does nothing special anymore.
1711      * @param type the type of events to capture
1712      * @see HTMLDocument#captureEvents(String)
1713      */
1714     @JsxFunction
1715     public void captureEvents(final String type) {
1716         // Empty.
1717     }
1718 
1719     /**
1720      * Does nothing special anymore.
1721      * @param type the type of events to capture
1722      * @see HTMLDocument#releaseEvents(String)
1723      */
1724     @JsxFunction
1725     public void releaseEvents(final String type) {
1726         // Empty.
1727     }
1728 
1729     /**
1730      * Returns computed style of the element. Computed style represents the final computed values
1731      * of all CSS properties for the element. This method's return value is of the same type as
1732      * that of <code>element.style</code>, but the value returned by this method is read-only.
1733      *
1734      * @param element the element
1735      * @param pseudoElement a string specifying the pseudo-element to match (may be {@code null});
1736      *        e.g. ':before'
1737      * @return the computed style
1738      */
1739     @JsxFunction
1740     public ComputedCSSStyleDeclaration getComputedStyle(final Object element, final String pseudoElement) {
1741         if (!(element instanceof Element)) {
1742             throw JavaScriptEngine.typeError("parameter 1 is not of type 'Element'");
1743         }
1744         final Element e = (Element) element;
1745 
1746         final ComputedCssStyleDeclaration style = getWebWindow().getComputedStyle(e.getDomNodeOrDie(), pseudoElement);
1747         return new ComputedCSSStyleDeclaration(e, style);
1748     }
1749 
1750     /**
1751      * Returns the current selection.
1752      * @return the current selection
1753      */
1754     @JsxFunction
1755     public Selection getSelection() {
1756         final WebWindow webWindow = getWebWindow();
1757         // return null if the window is in a frame that is not displayed
1758         if (webWindow instanceof FrameWindow) {
1759             final FrameWindow frameWindow = (FrameWindow) webWindow;
1760             if (getBrowserVersion().hasFeature(JS_WINDOW_SELECTION_NULL_IF_INVISIBLE)
1761                     && !frameWindow.getFrameElement().isDisplayed()) {
1762                 return null;
1763             }
1764         }
1765         return getSelectionImpl();
1766     }
1767 
1768     /**
1769      * Returns the current selection.
1770      * @return the current selection
1771      */
1772     public Selection getSelectionImpl() {
1773         if (selection_ == null) {
1774             selection_ = new Selection();
1775             selection_.setParentScope(this);
1776             selection_.setPrototype(getPrototype(selection_.getClass()));
1777         }
1778         return selection_;
1779     }
1780 
1781     /**
1782      * Gets the {@code controllers}. The result doesn't currently matter but it is important to return an
1783      * object as some JavaScript libraries check it.
1784      * @see <a href="https://developer.mozilla.org/En/DOM/Window.controllers">Mozilla documentation</a>
1785      * @return some object
1786      */
1787     @JsxGetter({FF, FF_ESR})
1788     public Object getControllers() {
1789         return controllers_;
1790     }
1791 
1792     /**
1793      * Sets the {@code controllers}.
1794      * @param value the new value
1795      */
1796     @JsxSetter({FF, FF_ESR})
1797     public void setControllers(final Object value) {
1798         controllers_ = value;
1799     }
1800 
1801     /**
1802      * Returns the value of {@code mozInnerScreenX} property.
1803      * @return the value of {@code mozInnerScreenX} property
1804      */
1805     @JsxGetter(FF)
1806     public int getMozInnerScreenX() {
1807         return 12;
1808     }
1809 
1810     /**
1811      * Returns the value of {@code mozInnerScreenX} property.
1812      * @return the value of {@code mozInnerScreenX} property
1813      */
1814     @JsxGetter(value = FF_ESR, propertyName = "mozInnerScreenX")
1815     public int getMozInnerScreenXffesr_js() {
1816         return 10;
1817     }
1818 
1819     /**
1820      * Returns the value of {@code mozInnerScreenY} property.
1821      * @return the value of {@code mozInnerScreenY} property
1822      */
1823     @JsxGetter({FF, FF_ESR})
1824     public int getMozInnerScreenY() {
1825         return 89;
1826     }
1827 
1828     private static final class Filter {
1829         private final boolean includeFormFields_;
1830 
1831         Filter(final boolean includeFormFields) {
1832             includeFormFields_ = includeFormFields;
1833         }
1834 
1835         boolean matches(final Object object) {
1836             if (object instanceof HtmlEmbed
1837                 || object instanceof HtmlForm
1838                 || object instanceof HtmlImage
1839                 || object instanceof HtmlObject) {
1840                 return true;
1841             }
1842 
1843             return includeFormFields_
1844                     && (object instanceof HtmlAnchor
1845                         || object instanceof HtmlButton
1846                         || object instanceof HtmlInput
1847                         || object instanceof HtmlMap
1848                         || object instanceof HtmlSelect
1849                         || object instanceof HtmlTextArea);
1850         }
1851     }
1852 
1853     /**
1854      * Should implement the stop() function on the window object.
1855      * (currently empty implementation)
1856      * @see <a href="https://developer.mozilla.org/en/DOM/window.stop">window.stop</a>
1857      */
1858     @JsxFunction
1859     public void stop() {
1860         //empty
1861     }
1862 
1863     /**
1864      * Returns the value of {@code pageXOffset} property.
1865      * @return the value of {@code pageXOffset} property
1866      */
1867     @JsxGetter
1868     public int getPageXOffset() {
1869         return 0;
1870     }
1871 
1872     /**
1873      * Returns the value of {@code pageYOffset} property.
1874      * @return the value of {@code pageYOffset} property
1875      */
1876     @JsxGetter
1877     public int getPageYOffset() {
1878         return 0;
1879     }
1880 
1881     /**
1882      * Returns the value of {@code scrollX} property.
1883      * @return the value of {@code scrollX} property
1884      */
1885     @JsxGetter
1886     public int getScrollX() {
1887         return 0;
1888     }
1889 
1890     /**
1891      * Returns the value of {@code scrollY} property.
1892      * @return the value of {@code scrollY} property
1893      */
1894     @JsxGetter
1895     public int getScrollY() {
1896         return 0;
1897     }
1898 
1899     /**
1900      * @return the value of {@code netscape} property
1901      */
1902     @JsxGetter({FF, FF_ESR})
1903     public Netscape getNetscape() {
1904         return new Netscape(this);
1905     }
1906 
1907     /**
1908      * {@inheritDoc}
1909      * Used to allow re-declaration of constants (eg: "var undefined;").
1910      */
1911     @Override
1912     public boolean isConst(final String name) {
1913         if ("undefined".equals(name) || "Infinity".equals(name) || "NaN".equals(name)) {
1914             return false;
1915         }
1916 
1917         return super.isConst(name);
1918     }
1919 
1920     /**
1921      * {@inheritDoc}
1922      */
1923     @Override
1924     public boolean dispatchEvent(final Event event) {
1925         event.setTarget(this);
1926         final ScriptResult result = fireEvent(event);
1927         return !event.isAborted(result);
1928     }
1929 
1930     /**
1931      * Getter for the {@code onchange} event handler.
1932      * @return the handler
1933      */
1934     @JsxGetter
1935     public Function getOnchange() {
1936         return getEventHandler(Event.TYPE_CHANGE);
1937     }
1938 
1939     /**
1940      * Setter for the {@code onchange} event handler.
1941      * @param onchange the handler
1942      */
1943     @JsxSetter
1944     public void setOnchange(final Object onchange) {
1945         setHandlerForJavaScript(Event.TYPE_CHANGE, onchange);
1946     }
1947 
1948     /**
1949      * Getter for the {@code onsubmit} event handler.
1950      * @return the handler
1951      */
1952     @JsxGetter
1953     public Function getOnsubmit() {
1954         return getEventHandler(Event.TYPE_SUBMIT);
1955     }
1956 
1957     /**
1958      * Setter for the {@code onsubmit} event handler.
1959      * @param onsubmit the handler
1960      */
1961     @JsxSetter
1962     public void setOnsubmit(final Object onsubmit) {
1963         setHandlerForJavaScript(Event.TYPE_SUBMIT, onsubmit);
1964     }
1965 
1966     /**
1967      * Posts a message.
1968      * @param context the current context
1969      * @param scope the scope
1970      * @param thisObj this object
1971      * @param args the script(s) to import
1972      * @param funObj the JS function called
1973      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage">MDN documentation</a>
1974      */
1975     @JsxFunction
1976     public static void postMessage(final Context context, final Scriptable scope,
1977             final Scriptable thisObj, final Object[] args, final Function funObj) {
1978 
1979         // support the structured clone algorithm
1980         if (args.length < 1) {
1981             throw JavaScriptEngine.typeError("message not provided");
1982         }
1983         final Object message = args[0];
1984 
1985         String targetOrigin = "*";
1986         if (args.length > 1) {
1987             targetOrigin = JavaScriptEngine.toString(args[1]);
1988         }
1989 
1990         Object transfer = JavaScriptEngine.UNDEFINED;
1991         if (args.length > 2) {
1992             transfer = args[2];
1993         }
1994 
1995         final Window sender = (Window) scope;
1996         final Window receiver = (Window) thisObj;
1997         final URL receiverURL = receiver.getWebWindow().getEnclosedPage().getUrl();
1998 
1999         final WebWindow webWindow = sender.getWebWindow();
2000         final Page page = webWindow.getEnclosedPage();
2001         final URL senderURL = page.getUrl();
2002 
2003         if (!org.htmlunit.util.StringUtils.equalsChar('*', targetOrigin)) {
2004             final URL targetURL;
2005             if (org.htmlunit.util.StringUtils.equalsChar('/', targetOrigin)) {
2006                 targetURL = senderURL;
2007             }
2008             else {
2009                 try {
2010                     targetURL = new URL(targetOrigin);
2011                 }
2012                 catch (final Exception e) {
2013                     throw JavaScriptEngine.asJavaScriptException(
2014                             (HtmlUnitScriptable) getTopLevelScope(thisObj),
2015                             "Failed to execute 'postMessage' on 'Window': Invalid target origin '"
2016                                     + targetOrigin + "' was specified (reason: " + e.getMessage() + ".",
2017                             DOMException.SYNTAX_ERR);
2018                 }
2019             }
2020 
2021             if (getPort(targetURL) != getPort(receiverURL)) {
2022                 return;
2023             }
2024             if (!targetURL.getHost().equals(receiverURL.getHost())) {
2025                 return;
2026             }
2027             if (!targetURL.getProtocol().equals(receiverURL.getProtocol())) {
2028                 return;
2029             }
2030         }
2031 
2032         String origin = "";
2033         try {
2034             final URL originUrl = UrlUtils.getUrlWithoutPathRefQuery(senderURL);
2035             origin = UrlUtils.removeRedundantPort(originUrl).toExternalForm();
2036         }
2037         catch (final MalformedURLException e) {
2038             throw JavaScriptEngine.throwAsScriptRuntimeEx(e);
2039         }
2040 
2041         final MessageEvent event = new MessageEvent();
2042         event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin, "", sender, transfer);
2043         event.setParentScope(scope);
2044         event.setPrototype(receiver.getPrototype(event.getClass()));
2045 
2046         final AbstractJavaScriptEngine<?> jsEngine = webWindow.getWebClient().getJavaScriptEngine();
2047         final PostponedAction action = new PostponedAction(page, "Window.postMessage") {
2048             @Override
2049             public void execute() {
2050                 final HtmlUnitContextFactory cf = jsEngine.getContextFactory();
2051                 cf.call(cx -> receiver.dispatchEvent(event));
2052             }
2053         };
2054         jsEngine.addPostponedAction(action);
2055     }
2056 
2057     /**
2058      * Returns the port of the specified URL.
2059      * @param url the URL
2060      * @return the port
2061      */
2062     public static int getPort(final URL url) {
2063         int port = url.getPort();
2064         if (port == -1) {
2065             if ("http".equals(url.getProtocol())) {
2066                 port = 80;
2067             }
2068             else {
2069                 port = 443;
2070             }
2071         }
2072         return port;
2073     }
2074 
2075     /**
2076      * The performance attribute is defined as replacable
2077      * (https://w3c.github.io/hr-time/#the-performance-attribute) but not implemented
2078      * as that.
2079      * @return the value of the {@code performance} property
2080      */
2081     @JsxGetter
2082     public Scriptable getPerformance() {
2083         if (performance_ == null) {
2084             final Performance performance = new Performance();
2085             performance.setParentScope(this);
2086             performance.setPrototype(getPrototype(performance.getClass()));
2087             performance_ = performance;
2088         }
2089         return performance_;
2090     }
2091 
2092     /**
2093      * The performance attribute is defined as replacable
2094      * (https://w3c.github.io/hr-time/#the-performance-attribute) but not implemented
2095      * as that.
2096      *
2097      * Sets the {@code performance} property.
2098      * @param performance the value to overwrite the defined property value
2099      */
2100     @JsxSetter
2101     public void setPerformance(final Scriptable performance) {
2102         performance_ = performance;
2103     }
2104 
2105     /**
2106      * Returns the {@code devicePixelRatio} property.
2107      * @return the {@code devicePixelRatio} property
2108      */
2109     @JsxGetter
2110     public int getDevicePixelRatio() {
2111         return 1;
2112     }
2113 
2114     /**
2115      * Returns the {@code styleMedia} property.
2116      * @return the {@code styleMedia} property
2117      */
2118     @JsxGetter({CHROME, EDGE})
2119     public StyleMedia getStyleMedia() {
2120         final StyleMedia styleMedia = new StyleMedia();
2121         styleMedia.setParentScope(this);
2122         styleMedia.setPrototype(getPrototype(styleMedia.getClass()));
2123         return styleMedia;
2124     }
2125 
2126     /**
2127      * Returns a new MediaQueryList object representing the parsed results of the specified media query string.
2128      *
2129      * @param mediaQueryString the media query
2130      * @return a new MediaQueryList object
2131      */
2132     @JsxFunction
2133     public MediaQueryList matchMedia(final String mediaQueryString) {
2134         final MediaQueryList mediaQueryList = new MediaQueryList(mediaQueryString);
2135         mediaQueryList.setParentScope(this);
2136         mediaQueryList.setPrototype(getPrototype(mediaQueryList.getClass()));
2137         return mediaQueryList;
2138     }
2139 
2140     /**
2141      * Stub only at the moment.
2142      * @param search the text string for which to search
2143      * @param caseSensitive if true, specifies a case-sensitive search
2144      * @param backwards if true, specifies a backward search
2145      * @param wrapAround if true, specifies a wrap around search
2146      * @param wholeWord if true, specifies a whole word search
2147      * @param searchInFrames if true, specifies a search in frames
2148      * @param showDialog if true, specifies a show Dialog.
2149      * @return false
2150      */
2151     @JsxFunction
2152     public boolean find(final String search, final boolean caseSensitive,
2153             final boolean backwards, final boolean wrapAround,
2154             final boolean wholeWord, final boolean searchInFrames, final boolean showDialog) {
2155         return false;
2156     }
2157 
2158     /**
2159      * Returns the {@code speechSynthesis} property.
2160      * @return the {@code speechSynthesis} property
2161      */
2162     @JsxGetter({CHROME, EDGE})
2163     public SpeechSynthesis getSpeechSynthesis() {
2164         final SpeechSynthesis speechSynthesis = new SpeechSynthesis();
2165         speechSynthesis.setParentScope(this);
2166         speechSynthesis.setPrototype(getPrototype(speechSynthesis.getClass()));
2167         return speechSynthesis;
2168     }
2169 
2170     /**
2171      * Returns the {@code offscreenBuffering} property.
2172      * @return the {@code offscreenBuffering} property
2173      */
2174     @JsxGetter({CHROME, EDGE})
2175     public boolean getOffscreenBuffering() {
2176         return true;
2177     }
2178 
2179     /**
2180      * Returns the {@code crypto} property.
2181      * @return the {@code crypto} property
2182      */
2183     @JsxGetter
2184     public Crypto getCrypto() {
2185         if (crypto_ == null) {
2186             crypto_ = new Crypto(this);
2187         }
2188         return crypto_;
2189     }
2190 
2191     /**
2192      * {@inheritDoc}
2193      */
2194     @Override
2195     public void close() {
2196         // nothing to do
2197     }
2198 
2199     /**
2200      * Does nothing.
2201      * @param parent the new parent scope
2202      */
2203     @Override
2204     public void setParentScope(final Scriptable parent) {
2205         // nothing as the window is the top level scope and its parent scope should stay null
2206     }
2207 
2208     /**
2209      * Returns the {@code onfocus} event handler.
2210      * @return the {@code onfocus} event handler
2211      */
2212     @JsxGetter
2213     public Function getOnfocus() {
2214         return getEventHandler(Event.TYPE_FOCUS);
2215     }
2216 
2217     /**
2218      * Sets the {@code onfocus} event handler.
2219      * @param onfocus the {@code onfocus} event handler
2220      */
2221     @JsxSetter
2222     public void setOnfocus(final Object onfocus) {
2223         setHandlerForJavaScript(Event.TYPE_FOCUS, onfocus);
2224     }
2225 
2226     /**
2227      * Returns the {@code ondragend} event handler.
2228      * @return the {@code ondragend} event handler
2229      */
2230     @JsxGetter
2231     public Function getOndragend() {
2232         return getEventHandler(Event.TYPE_DRAGEND);
2233     }
2234 
2235     /**
2236      * Sets the {@code ondragend} event handler.
2237      * @param ondragend the {@code ondragend} event handler
2238      */
2239     @JsxSetter
2240     public void setOndragend(final Object ondragend) {
2241         setHandlerForJavaScript(Event.TYPE_DRAGEND, ondragend);
2242     }
2243 
2244     /**
2245      * Returns the {@code oninvalid} event handler.
2246      * @return the {@code oninvalid} event handler
2247      */
2248     @JsxGetter
2249     public Function getOninvalid() {
2250         return getEventHandler(Event.TYPE_INVALID);
2251     }
2252 
2253     /**
2254      * Sets the {@code oninvalid} event handler.
2255      * @param oninvalid the {@code oninvalid} event handler
2256      */
2257     @JsxSetter
2258     public void setOninvalid(final Object oninvalid) {
2259         setHandlerForJavaScript(Event.TYPE_INVALID, oninvalid);
2260     }
2261 
2262     /**
2263      * Returns the {@code onpointerout} event handler.
2264      * @return the {@code onpointerout} event handler
2265      */
2266     @JsxGetter({CHROME, EDGE})
2267     public Function getOnpointerout() {
2268         return getEventHandler(Event.TYPE_POINTEROUT);
2269     }
2270 
2271     /**
2272      * Sets the {@code onpointerout} event handler.
2273      * @param onpointerout the {@code onpointerout} event handler
2274      */
2275     @JsxSetter({CHROME, EDGE})
2276     public void setOnpointerout(final Object onpointerout) {
2277         setHandlerForJavaScript(Event.TYPE_POINTEROUT, onpointerout);
2278     }
2279 
2280     /**
2281      * Returns the {@code onratechange} event handler.
2282      * @return the {@code onratechange} event handler
2283      */
2284     @JsxGetter
2285     public Function getOnratechange() {
2286         return getEventHandler(Event.TYPE_RATECHANGE);
2287     }
2288 
2289     /**
2290      * Sets the {@code onratechange} event handler.
2291      * @param onratechange the {@code onratechange} event handler
2292      */
2293     @JsxSetter
2294     public void setOnratechange(final Object onratechange) {
2295         setHandlerForJavaScript(Event.TYPE_RATECHANGE, onratechange);
2296     }
2297 
2298     /**
2299      * Returns the {@code onanimationiteration} event handler.
2300      * @return the {@code onanimationiteration} event handler
2301      */
2302     @JsxGetter
2303     public Function getOnanimationiteration() {
2304         return getEventHandler(Event.TYPE_ANIMATIONITERATION);
2305     }
2306 
2307     /**
2308      * Sets the {@code onanimationiteration} event handler.
2309      * @param onanimationiteration the {@code onanimationiteration} event handler
2310      */
2311     @JsxSetter
2312     public void setOnanimationiteration(final Object onanimationiteration) {
2313         setHandlerForJavaScript(Event.TYPE_ANIMATIONITERATION, onanimationiteration);
2314     }
2315 
2316     /**
2317      * Returns the {@code oncanplaythrough} event handler.
2318      * @return the {@code oncanplaythrough} event handler
2319      */
2320     @JsxGetter
2321     public Function getOncanplaythrough() {
2322         return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2323     }
2324 
2325     /**
2326      * Sets the {@code oncanplaythrough} event handler.
2327      * @param oncanplaythrough the {@code oncanplaythrough} event handler
2328      */
2329     @JsxSetter
2330     public void setOncanplaythrough(final Object oncanplaythrough) {
2331         setHandlerForJavaScript(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2332     }
2333 
2334     /**
2335      * Returns the {@code oncancel} event handler.
2336      * @return the {@code oncancel} event handler
2337      */
2338     @JsxGetter({CHROME, EDGE})
2339     public Function getOncancel() {
2340         return getEventHandler(Event.TYPE_CANCEL);
2341     }
2342 
2343     /**
2344      * Sets the {@code oncancel} event handler.
2345      * @param oncancel the {@code oncancel} event handler
2346      */
2347     @JsxSetter({CHROME, EDGE})
2348     public void setOncancel(final Object oncancel) {
2349         setHandlerForJavaScript(Event.TYPE_CANCEL, oncancel);
2350     }
2351 
2352     /**
2353      * Returns the {@code onpointerenter} event handler.
2354      * @return the {@code onpointerenter} event handler
2355      */
2356     @JsxGetter({CHROME, EDGE})
2357     public Function getOnpointerenter() {
2358         return getEventHandler(Event.TYPE_POINTERENTER);
2359     }
2360 
2361     /**
2362      * Sets the {@code onpointerenter} event handler.
2363      * @param onpointerenter the {@code onpointerenter} event handler
2364      */
2365     @JsxSetter({CHROME, EDGE})
2366     public void setOnpointerenter(final Object onpointerenter) {
2367         setHandlerForJavaScript(Event.TYPE_POINTERENTER, onpointerenter);
2368     }
2369 
2370     /**
2371      * Returns the {@code onselect} event handler.
2372      * @return the {@code onselect} event handler
2373      */
2374     @JsxGetter
2375     public Function getOnselect() {
2376         return getEventHandler(Event.TYPE_SELECT);
2377     }
2378 
2379     /**
2380      * Sets the {@code onselect} event handler.
2381      * @param onselect the {@code onselect} event handler
2382      */
2383     @JsxSetter
2384     public void setOnselect(final Object onselect) {
2385         setHandlerForJavaScript(Event.TYPE_SELECT, onselect);
2386     }
2387 
2388     /**
2389      * Returns the {@code onauxclick} event handler.
2390      * @return the {@code onauxclick} event handler
2391      */
2392     @JsxGetter({CHROME, EDGE})
2393     public Function getOnauxclick() {
2394         return getEventHandler(Event.TYPE_AUXCLICK);
2395     }
2396 
2397     /**
2398      * Sets the {@code onauxclick} event handler.
2399      * @param onauxclick the {@code onauxclick} event handler
2400      */
2401     @JsxSetter({CHROME, EDGE})
2402     public void setOnauxclick(final Object onauxclick) {
2403         setHandlerForJavaScript(Event.TYPE_AUXCLICK, onauxclick);
2404     }
2405 
2406     /**
2407      * Returns the {@code onscroll} event handler.
2408      * @return the {@code onscroll} event handler
2409      */
2410     @JsxGetter
2411     public Function getOnscroll() {
2412         return getEventHandler(Event.TYPE_SCROLL);
2413     }
2414 
2415     /**
2416      * Sets the {@code onscroll} event handler.
2417      * @param onscroll the {@code onscroll} event handler
2418      */
2419     @JsxSetter
2420     public void setOnscroll(final Object onscroll) {
2421         setHandlerForJavaScript(Event.TYPE_SCROLL, onscroll);
2422     }
2423 
2424     /**
2425      * Returns the {@code onkeydown} event handler.
2426      * @return the {@code onkeydown} event handler
2427      */
2428     @JsxGetter
2429     public Function getOnkeydown() {
2430         return getEventHandler(Event.TYPE_KEY_DOWN);
2431     }
2432 
2433     /**
2434      * Sets the {@code onkeydown} event handler.
2435      * @param onkeydown the {@code onkeydown} event handler
2436      */
2437     @JsxSetter
2438     public void setOnkeydown(final Object onkeydown) {
2439         setHandlerForJavaScript(Event.TYPE_KEY_DOWN, onkeydown);
2440     }
2441 
2442     /**
2443      * Returns the {@code onwebkitanimationstart} event handler.
2444      * @return the {@code onwebkitanimationstart} event handler
2445      */
2446     @JsxGetter({CHROME, EDGE})
2447     public Function getOnwebkitanimationstart() {
2448         return getEventHandler(Event.TYPE_WEBANIMATIONSTART);
2449     }
2450 
2451     /**
2452      * Sets the {@code onwebkitanimationstart} event handler.
2453      * @param onwebkitanimationstart the {@code onwebkitanimationstart} event handler
2454      */
2455     @JsxSetter({CHROME, EDGE})
2456     public void setOnwebkitanimationstart(final Object onwebkitanimationstart) {
2457         setHandlerForJavaScript(Event.TYPE_WEBANIMATIONSTART, onwebkitanimationstart);
2458     }
2459 
2460     /**
2461      * Returns the {@code onkeyup} event handler.
2462      * @return the {@code onkeyup} event handler
2463      */
2464     @JsxGetter
2465     public Function getOnkeyup() {
2466         return getEventHandler(Event.TYPE_KEY_UP);
2467     }
2468 
2469     /**
2470      * Sets the {@code onkeyup} event handler.
2471      * @param onkeyup the {@code onkeyup} event handler
2472      */
2473     @JsxSetter
2474     public void setOnkeyup(final Object onkeyup) {
2475         setHandlerForJavaScript(Event.TYPE_KEY_UP, onkeyup);
2476     }
2477 
2478     /**
2479      * Returns the {@code onreset} event handler.
2480      * @return the {@code onreset} event handler
2481      */
2482     @JsxGetter
2483     public Function getOnreset() {
2484         return getEventHandler(Event.TYPE_RESET);
2485     }
2486 
2487     /**
2488      * Sets the {@code onreset} event handler.
2489      * @param onreset the {@code onreset} event handler
2490      */
2491     @JsxSetter
2492     public void setOnreset(final Object onreset) {
2493         setHandlerForJavaScript(Event.TYPE_RESET, onreset);
2494     }
2495 
2496     /**
2497      * Returns the {@code onkeypress} event handler.
2498      * @return the {@code onkeypress} event handler
2499      */
2500     @JsxGetter
2501     public Function getOnkeypress() {
2502         return getEventHandler(Event.TYPE_KEY_PRESS);
2503     }
2504 
2505     /**
2506      * Sets the {@code onkeypress} event handler.
2507      * @param onkeypress the {@code onkeypress} event handler
2508      */
2509     @JsxSetter
2510     public void setOnkeypress(final Object onkeypress) {
2511         setHandlerForJavaScript(Event.TYPE_KEY_PRESS, onkeypress);
2512     }
2513 
2514     /**
2515      * Returns the {@code ondrag} event handler.
2516      * @return the {@code ondrag} event handler
2517      */
2518     @JsxGetter
2519     public Function getOndrag() {
2520         return getEventHandler(Event.TYPE_DRAG);
2521     }
2522 
2523     /**
2524      * Sets the {@code ondrag} event handler.
2525      * @param ondrag the {@code ondrag} event handler
2526      */
2527     @JsxSetter
2528     public void setOndrag(final Object ondrag) {
2529         setHandlerForJavaScript(Event.TYPE_DRAG, ondrag);
2530     }
2531 
2532     /**
2533      * Returns the {@code onseeked} event handler.
2534      * @return the {@code onseeked} event handler
2535      */
2536     @JsxGetter
2537     public Function getOnseeked() {
2538         return getEventHandler(Event.TYPE_SEEKED);
2539     }
2540 
2541     /**
2542      * Sets the {@code onseeked} event handler.
2543      * @param onseeked the {@code onseeked} event handler
2544      */
2545     @JsxSetter
2546     public void setOnseeked(final Object onseeked) {
2547         setHandlerForJavaScript(Event.TYPE_SEEKED, onseeked);
2548     }
2549 
2550     /**
2551      * Returns the {@code onoffline} event handler.
2552      * @return the {@code onoffline} event handler
2553      */
2554     @JsxGetter
2555     public Function getOnoffline() {
2556         return getEventHandler(Event.TYPE_OFFLINE);
2557     }
2558 
2559     /**
2560      * Sets the {@code onoffline} event handler.
2561      * @param onoffline the {@code onoffline} event handler
2562      */
2563     @JsxSetter
2564     public void setOnoffline(final Object onoffline) {
2565         setHandlerForJavaScript(Event.TYPE_OFFLINE, onoffline);
2566     }
2567 
2568     /**
2569      * Returns the {@code ondeviceorientation} event handler.
2570      * @return the {@code ondeviceorientation} event handler
2571      */
2572     @JsxGetter
2573     public Function getOndeviceorientation() {
2574         return getEventHandler(Event.TYPE_DEVICEORIENTATION);
2575     }
2576 
2577     /**
2578      * Sets the {@code ondeviceorientation} event handler.
2579      * @param ondeviceorientation the {@code ondeviceorientation} event handler
2580      */
2581     @JsxSetter
2582     public void setOndeviceorientation(final Object ondeviceorientation) {
2583         setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATION, ondeviceorientation);
2584     }
2585 
2586     /**
2587      * Returns the {@code ontoggle} event handler.
2588      * @return the {@code ontoggle} event handler
2589      */
2590     @JsxGetter({CHROME, EDGE})
2591     public Function getOntoggle() {
2592         return getEventHandler(Event.TYPE_TOGGLE);
2593     }
2594 
2595     /**
2596      * Sets the {@code ontoggle} event handler.
2597      * @param ontoggle the {@code ontoggle} event handler
2598      */
2599     @JsxSetter({CHROME, EDGE})
2600     public void setOntoggle(final Object ontoggle) {
2601         setHandlerForJavaScript(Event.TYPE_TOGGLE, ontoggle);
2602     }
2603 
2604     /**
2605      * Returns the {@code onplay} event handler.
2606      * @return the {@code onplay} event handler
2607      */
2608     @JsxGetter
2609     public Function getOnplay() {
2610         return getEventHandler(Event.TYPE_PLAY);
2611     }
2612 
2613     /**
2614      * Sets the {@code onplay} event handler.
2615      * @param onplay the {@code onplay} event handler
2616      */
2617     @JsxSetter
2618     public void setOnplay(final Object onplay) {
2619         setHandlerForJavaScript(Event.TYPE_PLAY, onplay);
2620     }
2621 
2622     /**
2623      * Returns the {@code oncontextmenu} event handler.
2624      * @return the {@code oncontextmenu} event handler
2625      */
2626     @JsxGetter
2627     public Function getOncontextmenu() {
2628         return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
2629     }
2630 
2631     /**
2632      * Sets the {@code oncontextmenu} event handler.
2633      * @param oncontextmenu the {@code oncontextmenu} event handler
2634      */
2635     @JsxSetter
2636     public void setOncontextmenu(final Object oncontextmenu) {
2637         setHandlerForJavaScript(MouseEvent.TYPE_CONTEXT_MENU, oncontextmenu);
2638     }
2639 
2640     /**
2641      * Returns the {@code onmousemove} event handler.
2642      * @return the {@code onmousemove} event handler
2643      */
2644     @JsxGetter
2645     public Function getOnmousemove() {
2646         return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
2647     }
2648 
2649     /**
2650      * Sets the {@code onmousemove} event handler.
2651      * @param onmousemove the {@code onmousemove} event handler
2652      */
2653     @JsxSetter
2654     public void setOnmousemove(final Object onmousemove) {
2655         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_MOVE, onmousemove);
2656     }
2657 
2658     /**
2659      * Returns the {@code onpointermove} event handler.
2660      * @return the {@code onpointermove} event handler
2661      */
2662     @JsxGetter({CHROME, EDGE})
2663     public Function getOnpointermove() {
2664         return getEventHandler(Event.TYPE_POINTERMOVE);
2665     }
2666 
2667     /**
2668      * Sets the {@code onpointermove} event handler.
2669      * @param onpointermove the {@code onpointermove} event handler
2670      */
2671     @JsxSetter({CHROME, EDGE})
2672     public void setOnpointermove(final Object onpointermove) {
2673         setHandlerForJavaScript(Event.TYPE_POINTERMOVE, onpointermove);
2674     }
2675 
2676     /**
2677      * Returns the {@code onmouseover} event handler.
2678      * @return the {@code onmouseover} event handler
2679      */
2680     @JsxGetter
2681     public Function getOnmouseover() {
2682         return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
2683     }
2684 
2685     /**
2686      * Sets the {@code onmouseover} event handler.
2687      * @param onmouseover the {@code onmouseover} event handler
2688      */
2689     @JsxSetter
2690     public void setOnmouseover(final Object onmouseover) {
2691         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OVER, onmouseover);
2692     }
2693 
2694     /**
2695      * Returns the {@code onlostpointercapture} event handler.
2696      * @return the {@code onlostpointercapture} event handler
2697      */
2698     @JsxGetter({CHROME, EDGE})
2699     public Function getOnlostpointercapture() {
2700         return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2701     }
2702 
2703     /**
2704      * Sets the {@code onlostpointercapture} event handler.
2705      * @param onlostpointercapture the {@code onlostpointercapture} event handler
2706      */
2707     @JsxSetter({CHROME, EDGE})
2708     public void setOnlostpointercapture(final Object onlostpointercapture) {
2709         setHandlerForJavaScript(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2710     }
2711 
2712     /**
2713      * Returns the {@code onpointerover} event handler.
2714      * @return the {@code onpointerover} event handler
2715      */
2716     @JsxGetter({CHROME, EDGE})
2717     public Function getOnpointerover() {
2718         return getEventHandler(Event.TYPE_POINTEROVER);
2719     }
2720 
2721     /**
2722      * Sets the {@code onpointerover} event handler.
2723      * @param onpointerover the {@code onpointerover} event handler
2724      */
2725     @JsxSetter({CHROME, EDGE})
2726     public void setOnpointerover(final Object onpointerover) {
2727         setHandlerForJavaScript(Event.TYPE_POINTEROVER, onpointerover);
2728     }
2729 
2730     /**
2731      * Returns the {@code onclose} event handler.
2732      * @return the {@code onclose} event handler
2733      */
2734     @JsxGetter({CHROME, EDGE})
2735     public Function getOnclose() {
2736         return getEventHandler(Event.TYPE_CLOSE);
2737     }
2738 
2739     /**
2740      * Sets the {@code onclose} event handler.
2741      * @param onclose the {@code onclose} event handler
2742      */
2743     @JsxSetter({CHROME, EDGE})
2744     public void setOnclose(final Object onclose) {
2745         setHandlerForJavaScript(Event.TYPE_CLOSE, onclose);
2746     }
2747 
2748     /**
2749      * Returns the {@code onanimationend} event handler.
2750      * @return the {@code onanimationend} event handler
2751      */
2752     @JsxGetter
2753     public Function getOnanimationend() {
2754         return getEventHandler(Event.TYPE_ANIMATIONEND);
2755     }
2756 
2757     /**
2758      * Sets the {@code onanimationend} event handler.
2759      * @param onanimationend the {@code onanimationend} event handler
2760      */
2761     @JsxSetter
2762     public void setOnanimationend(final Object onanimationend) {
2763         setHandlerForJavaScript(Event.TYPE_ANIMATIONEND, onanimationend);
2764     }
2765 
2766     /**
2767      * Returns the {@code ondragenter} event handler.
2768      * @return the {@code ondragenter} event handler
2769      */
2770     @JsxGetter
2771     public Function getOndragenter() {
2772         return getEventHandler(Event.TYPE_DRAGENTER);
2773     }
2774 
2775     /**
2776      * Sets the {@code ondragenter} event handler.
2777      * @param ondragenter the {@code ondragenter} event handler
2778      */
2779     @JsxSetter
2780     public void setOndragenter(final Object ondragenter) {
2781         setHandlerForJavaScript(Event.TYPE_DRAGENTER, ondragenter);
2782     }
2783 
2784     /**
2785      * Returns the {@code onafterprint} event handler.
2786      * @return the {@code onafterprint} event handler
2787      */
2788     @JsxGetter({FF, FF_ESR})
2789     public Function getOnafterprint() {
2790         return getEventHandler(Event.TYPE_AFTERPRINT);
2791     }
2792 
2793     /**
2794      * Sets the {@code onafterprint} event handler.
2795      * @param onafterprint the {@code onafterprint} event handler
2796      */
2797     @JsxSetter({FF, FF_ESR})
2798     public void setOnafterprint(final Object onafterprint) {
2799         setHandlerForJavaScript(Event.TYPE_AFTERPRINT, onafterprint);
2800     }
2801 
2802     /**
2803      * Returns the {@code onmozfullscreenerror} event handler.
2804      * @return the {@code onmozfullscreenerror} event handler
2805      */
2806     @JsxGetter({FF, FF_ESR})
2807     public Function getOnmozfullscreenerror() {
2808         return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
2809     }
2810 
2811     /**
2812      * Sets the {@code onmozfullscreenerror} event handler.
2813      * @param onmozfullscreenerror the {@code onmozfullscreenerror} event handler
2814      */
2815     @JsxSetter({FF, FF_ESR})
2816     public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
2817         setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
2818     }
2819 
2820     /**
2821      * Returns the {@code onmouseleave} event handler.
2822      * @return the {@code onmouseleave} event handler
2823      */
2824     @JsxGetter
2825     public Function getOnmouseleave() {
2826         return getEventHandler(Event.TYPE_MOUSELEAVE);
2827     }
2828 
2829     /**
2830      * Sets the {@code onmouseleave} event handler.
2831      * @param onmouseleave the {@code onmouseleave} event handler
2832      */
2833     @JsxSetter
2834     public void setOnmouseleave(final Object onmouseleave) {
2835         setHandlerForJavaScript(Event.TYPE_MOUSELEAVE, onmouseleave);
2836     }
2837 
2838     /**
2839      * Returns the {@code onmousewheel} event handler.
2840      * @return the {@code onmousewheel} event handler
2841      */
2842     @JsxGetter({CHROME, EDGE})
2843     public Function getOnmousewheel() {
2844         return getEventHandler(Event.TYPE_MOUSEWHEEL);
2845     }
2846 
2847     /**
2848      * Sets the {@code onmousewheel} event handler.
2849      * @param onmousewheel the {@code onmousewheel} event handler
2850      */
2851     @JsxSetter({CHROME, EDGE})
2852     public void setOnmousewheel(final Object onmousewheel) {
2853         setHandlerForJavaScript(Event.TYPE_MOUSEWHEEL, onmousewheel);
2854     }
2855 
2856     /**
2857      * Returns the {@code onseeking} event handler.
2858      * @return the {@code onseeking} event handler
2859      */
2860     @JsxGetter
2861     public Function getOnseeking() {
2862         return getEventHandler(Event.TYPE_SEEKING);
2863     }
2864 
2865     /**
2866      * Sets the {@code onseeking} event handler.
2867      * @param onseeking the {@code onseeking} event handler
2868      */
2869     @JsxSetter
2870     public void setOnseeking(final Object onseeking) {
2871         setHandlerForJavaScript(Event.TYPE_SEEKING, onseeking);
2872     }
2873 
2874     /**
2875      * Returns the {@code oncuechange} event handler.
2876      * @return the {@code oncuechange} event handler
2877      */
2878     @JsxGetter({CHROME, EDGE})
2879     public Function getOncuechange() {
2880         return getEventHandler(Event.TYPE_CUECHANGE);
2881     }
2882 
2883     /**
2884      * Sets the {@code oncuechange} event handler.
2885      * @param oncuechange the {@code oncuechange} event handler
2886      */
2887     @JsxSetter({CHROME, EDGE})
2888     public void setOncuechange(final Object oncuechange) {
2889         setHandlerForJavaScript(Event.TYPE_CUECHANGE, oncuechange);
2890     }
2891 
2892     /**
2893      * Returns the {@code onpageshow} event handler.
2894      * @return the {@code onpageshow} event handler
2895      */
2896     @JsxGetter
2897     public Function getOnpageshow() {
2898         return getEventHandler(Event.TYPE_PAGESHOW);
2899     }
2900 
2901     /**
2902      * Sets the {@code onpageshow} event handler.
2903      * @param onpageshow the {@code onpageshow} event handler
2904      */
2905     @JsxSetter
2906     public void setOnpageshow(final Object onpageshow) {
2907         setHandlerForJavaScript(Event.TYPE_PAGESHOW, onpageshow);
2908     }
2909 
2910     /**
2911      * Returns the {@code onmozfullscreenchange} event handler.
2912      * @return the {@code onmozfullscreenchange} event handler
2913      */
2914     @JsxGetter({FF, FF_ESR})
2915     public Function getOnmozfullscreenchange() {
2916         return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
2917     }
2918 
2919     /**
2920      * Sets the {@code onmozfullscreenchange} event handler.
2921      * @param onmozfullscreenchange the {@code onmozfullscreenchange} event handler
2922      */
2923     @JsxSetter({FF, FF_ESR})
2924     public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
2925         setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
2926     }
2927 
2928     /**
2929      * Returns the {@code ondurationchange} event handler.
2930      * @return the {@code ondurationchange} event handler
2931      */
2932     @JsxGetter
2933     public Function getOndurationchange() {
2934         return getEventHandler(Event.TYPE_DURATIONCHANGE);
2935     }
2936 
2937     /**
2938      * Sets the {@code ondurationchange} event handler.
2939      * @param ondurationchange the {@code ondurationchange} event handler
2940      */
2941     @JsxSetter
2942     public void setOndurationchange(final Object ondurationchange) {
2943         setHandlerForJavaScript(Event.TYPE_DURATIONCHANGE, ondurationchange);
2944     }
2945 
2946     /**
2947      * Returns the {@code onplaying} event handler.
2948      * @return the {@code onplaying} event handler
2949      */
2950     @JsxGetter
2951     public Function getOnplaying() {
2952         return getEventHandler(Event.TYPE_PLAYING);
2953     }
2954 
2955     /**
2956      * Sets the {@code onplaying} event handler.
2957      * @param onplaying the {@code onplaying} event handler
2958      */
2959     @JsxSetter
2960     public void setOnplaying(final Object onplaying) {
2961         setHandlerForJavaScript(Event.TYPE_PLAYING, onplaying);
2962     }
2963 
2964     /**
2965      * Returns the {@code onended} event handler.
2966      * @return the {@code onended} event handler
2967      */
2968     @JsxGetter
2969     public Function getOnended() {
2970         return getEventHandler(Event.TYPE_ENDED);
2971     }
2972 
2973     /**
2974      * Sets the {@code onended} event handler.
2975      * @param onended the {@code onended} event handler
2976      */
2977     @JsxSetter
2978     public void setOnended(final Object onended) {
2979         setHandlerForJavaScript(Event.TYPE_ENDED, onended);
2980     }
2981 
2982     /**
2983      * Returns the {@code onloadeddata} event handler.
2984      * @return the {@code onloadeddata} event handler
2985      */
2986     @JsxGetter
2987     public Function getOnloadeddata() {
2988         return getEventHandler(Event.TYPE_LOADEDDATA);
2989     }
2990 
2991     /**
2992      * Sets the {@code onloadeddata} event handler.
2993      * @param onloadeddata the {@code onloadeddata} event handler
2994      */
2995     @JsxSetter
2996     public void setOnloadeddata(final Object onloadeddata) {
2997         setHandlerForJavaScript(Event.TYPE_LOADEDDATA, onloadeddata);
2998     }
2999 
3000     /**
3001      * Returns the {@code onunhandledrejection} event handler.
3002      * @return the {@code onunhandledrejection} event handler
3003      */
3004     @JsxGetter({CHROME, EDGE})
3005     public Function getOnunhandledrejection() {
3006         return getEventHandler(Event.TYPE_UNHANDLEDREJECTION);
3007     }
3008 
3009     /**
3010      * Sets the {@code onunhandledrejection} event handler.
3011      * @param onunhandledrejection the {@code onunhandledrejection} event handler
3012      */
3013     @JsxSetter({CHROME, EDGE})
3014     public void setOnunhandledrejection(final Object onunhandledrejection) {
3015         setHandlerForJavaScript(Event.TYPE_UNHANDLEDREJECTION, onunhandledrejection);
3016     }
3017 
3018     /**
3019      * Returns the {@code onmouseout} event handler.
3020      * @return the {@code onmouseout} event handler
3021      */
3022     @JsxGetter
3023     public Function getOnmouseout() {
3024         return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
3025     }
3026 
3027     /**
3028      * Sets the {@code onmouseout} event handler.
3029      * @param onmouseout the {@code onmouseout} event handler
3030      */
3031     @JsxSetter
3032     public void setOnmouseout(final Object onmouseout) {
3033         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OUT, onmouseout);
3034     }
3035 
3036     /**
3037      * Returns the {@code onsuspend} event handler.
3038      * @return the {@code onsuspend} event handler
3039      */
3040     @JsxGetter
3041     public Function getOnsuspend() {
3042         return getEventHandler(Event.TYPE_SUSPEND);
3043     }
3044 
3045     /**
3046      * Sets the {@code onsuspend} event handler.
3047      * @param onsuspend the {@code onsuspend} event handler
3048      */
3049     @JsxSetter
3050     public void setOnsuspend(final Object onsuspend) {
3051         setHandlerForJavaScript(Event.TYPE_SUSPEND, onsuspend);
3052     }
3053 
3054     /**
3055      * Returns the {@code onwaiting} event handler.
3056      * @return the {@code onwaiting} event handler
3057      */
3058     @JsxGetter
3059     public Function getOnwaiting() {
3060         return getEventHandler(Event.TYPE_WAITING);
3061     }
3062 
3063     /**
3064      * Sets the {@code onwaiting} event handler.
3065      * @param onwaiting the {@code onwaiting} event handler
3066      */
3067     @JsxSetter
3068     public void setOnwaiting(final Object onwaiting) {
3069         setHandlerForJavaScript(Event.TYPE_WAITING, onwaiting);
3070     }
3071 
3072     /**
3073      * Returns the {@code oncanplay} event handler.
3074      * @return the {@code oncanplay} event handler
3075      */
3076     @JsxGetter
3077     public Function getOncanplay() {
3078         return getEventHandler(Event.TYPE_CANPLAY);
3079     }
3080 
3081     /**
3082      * Sets the {@code oncanplay} event handler.
3083      * @param oncanplay the {@code oncanplay} event handler
3084      */
3085     @JsxSetter
3086     public void setOncanplay(final Object oncanplay) {
3087         setHandlerForJavaScript(Event.TYPE_CANPLAY, oncanplay);
3088     }
3089 
3090     /**
3091      * Returns the {@code onmousedown} event handler.
3092      * @return the {@code onmousedown} event handler
3093      */
3094     @JsxGetter
3095     public Function getOnmousedown() {
3096         return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
3097     }
3098 
3099     /**
3100      * Sets the {@code onmousedown} event handler.
3101      * @param onmousedown the {@code onmousedown} event handler
3102      */
3103     @JsxSetter
3104     public void setOnmousedown(final Object onmousedown) {
3105         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_DOWN, onmousedown);
3106     }
3107 
3108     /**
3109      * Returns the {@code onlanguagechange} event handler.
3110      * @return the {@code onlanguagechange} event handler
3111      */
3112     @JsxGetter
3113     public Function getOnlanguagechange() {
3114         return getEventHandler(Event.TYPE_LANGUAGECHANGE);
3115     }
3116 
3117     /**
3118      * Sets the {@code onlanguagechange} event handler.
3119      * @param onlanguagechange the {@code onlanguagechange} event handler
3120      */
3121     @JsxSetter
3122     public void setOnlanguagechange(final Object onlanguagechange) {
3123         setHandlerForJavaScript(Event.TYPE_LANGUAGECHANGE, onlanguagechange);
3124     }
3125 
3126     /**
3127      * Returns the {@code onemptied} event handler.
3128      * @return the {@code onemptied} event handler
3129      */
3130     @JsxGetter
3131     public Function getOnemptied() {
3132         return getEventHandler(Event.TYPE_EMPTIED);
3133     }
3134 
3135     /**
3136      * Sets the {@code onemptied} event handler.
3137      * @param onemptied the {@code onemptied} event handler
3138      */
3139     @JsxSetter
3140     public void setOnemptied(final Object onemptied) {
3141         setHandlerForJavaScript(Event.TYPE_EMPTIED, onemptied);
3142     }
3143 
3144     /**
3145      * Returns the {@code onrejectionhandled} event handler.
3146      * @return the {@code onrejectionhandled} event handler
3147      */
3148     @JsxGetter({CHROME, EDGE})
3149     public Function getOnrejectionhandled() {
3150         return getEventHandler(Event.TYPE_REJECTIONHANDLED);
3151     }
3152 
3153     /**
3154      * Sets the {@code onrejectionhandled} event handler.
3155      * @param onrejectionhandled the {@code onrejectionhandled} event handler
3156      */
3157     @JsxSetter({CHROME, EDGE})
3158     public void setOnrejectionhandled(final Object onrejectionhandled) {
3159         setHandlerForJavaScript(Event.TYPE_REJECTIONHANDLED, onrejectionhandled);
3160     }
3161 
3162     /**
3163      * Returns the {@code onpointercancel} event handler.
3164      * @return the {@code onpointercancel} event handler
3165      */
3166     @JsxGetter({CHROME, EDGE})
3167     public Function getOnpointercancel() {
3168         return getEventHandler(Event.TYPE_POINTERCANCEL);
3169     }
3170 
3171     /**
3172      * Sets the {@code onpointercancel} event handler.
3173      * @param onpointercancel the {@code onpointercancel} event handler
3174      */
3175     @JsxSetter({CHROME, EDGE})
3176     public void setOnpointercancel(final Object onpointercancel) {
3177         setHandlerForJavaScript(Event.TYPE_POINTERCANCEL, onpointercancel);
3178     }
3179 
3180     /**
3181      * Returns the {@code onresize} event handler.
3182      * @return the {@code onresize} event handler
3183      */
3184     @JsxGetter
3185     public Function getOnresize() {
3186         return getEventHandler(Event.TYPE_RESIZE);
3187     }
3188 
3189     /**
3190      * Sets the {@code onresize} event handler.
3191      * @param onresize the {@code onresize} event handler
3192      */
3193     @JsxSetter
3194     public void setOnresize(final Object onresize) {
3195         setHandlerForJavaScript(Event.TYPE_RESIZE, onresize);
3196     }
3197 
3198     /**
3199      * Returns the {@code onpause} event handler.
3200      * @return the {@code onpause} event handler
3201      */
3202     @JsxGetter
3203     public Function getOnpause() {
3204         return getEventHandler(Event.TYPE_PAUSE);
3205     }
3206 
3207     /**
3208      * Sets the {@code onpause} event handler.
3209      * @param onpause the {@code onpause} event handler
3210      */
3211     @JsxSetter
3212     public void setOnpause(final Object onpause) {
3213         setHandlerForJavaScript(Event.TYPE_PAUSE, onpause);
3214     }
3215 
3216     /**
3217      * Returns the {@code onloadstart} event handler.
3218      * @return the {@code onloadstart} event handler
3219      */
3220     @JsxGetter
3221     public Function getOnloadstart() {
3222         return getEventHandler(Event.TYPE_LOAD_START);
3223     }
3224 
3225     /**
3226      * Sets the {@code onloadstart} event handler.
3227      * @param onloadstart the {@code onloadstart} event handler
3228      */
3229     @JsxSetter
3230     public void setOnloadstart(final Object onloadstart) {
3231         setHandlerForJavaScript(Event.TYPE_LOAD_START, onloadstart);
3232     }
3233 
3234     /**
3235      * Returns the {@code onprogress} event handler.
3236      * @return the {@code onprogress} event handler
3237      */
3238     @JsxGetter
3239     public Function getOnprogress() {
3240         return getEventHandler(Event.TYPE_PROGRESS);
3241     }
3242 
3243     /**
3244      * Sets the {@code onprogress} event handler.
3245      * @param onprogress the {@code onprogress} event handler
3246      */
3247     @JsxSetter
3248     public void setOnprogress(final Object onprogress) {
3249         setHandlerForJavaScript(Event.TYPE_PROGRESS, onprogress);
3250     }
3251 
3252     /**
3253      * Returns the {@code onpointerup} event handler.
3254      * @return the {@code onpointerup} event handler
3255      */
3256     @JsxGetter({CHROME, EDGE})
3257     public Function getOnpointerup() {
3258         return getEventHandler(Event.TYPE_POINTERUP);
3259     }
3260 
3261     /**
3262      * Sets the {@code onpointerup} event handler.
3263      * @param onpointerup the {@code onpointerup} event handler
3264      */
3265     @JsxSetter({CHROME, EDGE})
3266     public void setOnpointerup(final Object onpointerup) {
3267         setHandlerForJavaScript(Event.TYPE_POINTERUP, onpointerup);
3268     }
3269 
3270     /**
3271      * Returns the {@code onwheel} event handler.
3272      * @return the {@code onwheel} event handler
3273      */
3274     @JsxGetter
3275     public Function getOnwheel() {
3276         return getEventHandler(Event.TYPE_WHEEL);
3277     }
3278 
3279     /**
3280      * Sets the {@code onwheel} event handler.
3281      * @param onwheel the {@code onwheel} event handler
3282      */
3283     @JsxSetter
3284     public void setOnwheel(final Object onwheel) {
3285         setHandlerForJavaScript(Event.TYPE_WHEEL, onwheel);
3286     }
3287 
3288     /**
3289      * Returns the {@code onpointerleave} event handler.
3290      * @return the {@code onpointerleave} event handler
3291      */
3292     @JsxGetter({CHROME, EDGE})
3293     public Function getOnpointerleave() {
3294         return getEventHandler(Event.TYPE_POINTERLEAVE);
3295     }
3296 
3297     /**
3298      * Sets the {@code onpointerleave} event handler.
3299      * @param onpointerleave the {@code onpointerleave} event handler
3300      */
3301     @JsxSetter({CHROME, EDGE})
3302     public void setOnpointerleave(final Object onpointerleave) {
3303         setHandlerForJavaScript(Event.TYPE_POINTERLEAVE, onpointerleave);
3304     }
3305 
3306     /**
3307      * Returns the {@code onbeforeprint} event handler.
3308      * @return the {@code onbeforeprint} event handler
3309      */
3310     @JsxGetter({FF, FF_ESR})
3311     public Function getOnbeforeprint() {
3312         return getEventHandler(Event.TYPE_BEFOREPRINT);
3313     }
3314 
3315     /**
3316      * Sets the {@code onbeforeprint} event handler.
3317      * @param onbeforeprint the {@code onbeforeprint} event handler
3318      */
3319     @JsxSetter({FF, FF_ESR})
3320     public void setOnbeforeprint(final Object onbeforeprint) {
3321         setHandlerForJavaScript(Event.TYPE_BEFOREPRINT, onbeforeprint);
3322     }
3323 
3324     /**
3325      * Returns the {@code onstorage} event handler.
3326      * @return the {@code onstorage} event handler
3327      */
3328     @JsxGetter
3329     public Function getOnstorage() {
3330         return getEventHandler(Event.TYPE_STORAGE);
3331     }
3332 
3333     /**
3334      * Sets the {@code onstorage} event handler.
3335      * @param onstorage the {@code onstorage} event handler
3336      */
3337     @JsxSetter
3338     public void setOnstorage(final Object onstorage) {
3339         setHandlerForJavaScript(Event.TYPE_STORAGE, onstorage);
3340     }
3341 
3342     /**
3343      * Returns the {@code onanimationstart} event handler.
3344      * @return the {@code onanimationstart} event handler
3345      */
3346     @JsxGetter
3347     public Function getOnanimationstart() {
3348         return getEventHandler(Event.TYPE_ANIMATIONSTART);
3349     }
3350 
3351     /**
3352      * Sets the {@code onanimationstart} event handler.
3353      * @param onanimationstart the {@code onanimationstart} event handler
3354      */
3355     @JsxSetter
3356     public void setOnanimationstart(final Object onanimationstart) {
3357         setHandlerForJavaScript(Event.TYPE_ANIMATIONSTART, onanimationstart);
3358     }
3359 
3360     /**
3361      * Returns the {@code ontimeupdate} event handler.
3362      * @return the {@code ontimeupdate} event handler
3363      */
3364     @JsxGetter
3365     public Function getOntimeupdate() {
3366         return getEventHandler(Event.TYPE_TIMEUPDATE);
3367     }
3368 
3369     /**
3370      * Sets the {@code ontimeupdate} event handler.
3371      * @param ontimeupdate the {@code ontimeupdate} event handler
3372      */
3373     @JsxSetter
3374     public void setOntimeupdate(final Object ontimeupdate) {
3375         setHandlerForJavaScript(Event.TYPE_TIMEUPDATE, ontimeupdate);
3376     }
3377 
3378     /**
3379      * Returns the {@code onpagehide} event handler.
3380      * @return the {@code onpagehide} event handler
3381      */
3382     @JsxGetter
3383     public Function getOnpagehide() {
3384         return getEventHandler(Event.TYPE_PAGEHIDE);
3385     }
3386 
3387     /**
3388      * Sets the {@code onpagehide} event handler.
3389      * @param onpagehide the {@code onpagehide} event handler
3390      */
3391     @JsxSetter
3392     public void setOnpagehide(final Object onpagehide) {
3393         setHandlerForJavaScript(Event.TYPE_PAGEHIDE, onpagehide);
3394     }
3395 
3396     /**
3397      * Returns the {@code onwebkitanimationiteration} event handler.
3398      * @return the {@code onwebkitanimationiteration} event handler
3399      */
3400     @JsxGetter({CHROME, EDGE})
3401     public Function getOnwebkitanimationiteration() {
3402         return getEventHandler(Event.TYPE_WEBKITANIMATIONITERATION);
3403     }
3404 
3405     /**
3406      * Sets the {@code onwebkitanimationiteration} event handler.
3407      * @param onwebkitanimationiteration the {@code onwebkitanimationiteration} event handler
3408      */
3409     @JsxSetter({CHROME, EDGE})
3410     public void setOnwebkitanimationiteration(final Object onwebkitanimationiteration) {
3411         setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONITERATION, onwebkitanimationiteration);
3412     }
3413 
3414     /**
3415      * Returns the {@code onabort} event handler.
3416      * @return the {@code onabort} event handler
3417      */
3418     @JsxGetter
3419     public Function getOnabort() {
3420         return getEventHandler(Event.TYPE_ABORT);
3421     }
3422 
3423     /**
3424      * Sets the {@code onabort} event handler.
3425      * @param onabort the {@code onabort} event handler
3426      */
3427     @JsxSetter
3428     public void setOnabort(final Object onabort) {
3429         setHandlerForJavaScript(Event.TYPE_ABORT, onabort);
3430     }
3431 
3432     /**
3433      * Returns the {@code onloadedmetadata} event handler.
3434      * @return the {@code onloadedmetadata} event handler
3435      */
3436     @JsxGetter
3437     public Function getOnloadedmetadata() {
3438         return getEventHandler(Event.TYPE_LOADEDMETADATA);
3439     }
3440 
3441     /**
3442      * Sets the {@code onloadedmetadata} event handler.
3443      * @param onloadedmetadata the {@code onloadedmetadata} event handler
3444      */
3445     @JsxSetter
3446     public void setOnloadedmetadata(final Object onloadedmetadata) {
3447         setHandlerForJavaScript(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
3448     }
3449 
3450     /**
3451      * Returns the {@code onmouseup} event handler.
3452      * @return the {@code onmouseup} event handler
3453      */
3454     @JsxGetter
3455     public Function getOnmouseup() {
3456         return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
3457     }
3458 
3459     /**
3460      * Sets the {@code onmouseup} event handler.
3461      * @param onmouseup the {@code onmouseup} event handler
3462      */
3463     @JsxSetter
3464     public void setOnmouseup(final Object onmouseup) {
3465         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_UP, onmouseup);
3466     }
3467 
3468     /**
3469      * Returns the {@code ondragover} event handler.
3470      * @return the {@code ondragover} event handler
3471      */
3472     @JsxGetter
3473     public Function getOndragover() {
3474         return getEventHandler(Event.TYPE_DRAGOVER);
3475     }
3476 
3477     /**
3478      * Sets the {@code ondragover} event handler.
3479      * @param ondragover the {@code ondragover} event handler
3480      */
3481     @JsxSetter
3482     public void setOndragover(final Object ondragover) {
3483         setHandlerForJavaScript(Event.TYPE_DRAGOVER, ondragover);
3484     }
3485 
3486     /**
3487      * Returns the {@code ononline} event handler.
3488      * @return the {@code ononline} event handler
3489      */
3490     @JsxGetter
3491     public Function getOnonline() {
3492         return getEventHandler(Event.TYPE_ONLINE);
3493     }
3494 
3495     /**
3496      * Sets the {@code ononline} event handler.
3497      * @param ononline the {@code ononline} event handler
3498      */
3499     @JsxSetter
3500     public void setOnonline(final Object ononline) {
3501         setHandlerForJavaScript(Event.TYPE_ONLINE, ononline);
3502     }
3503 
3504     /**
3505      * Returns the {@code onsearch} event handler.
3506      * @return the {@code onsearch} event handler
3507      */
3508     @JsxGetter({CHROME, EDGE})
3509     public Function getOnsearch() {
3510         return getEventHandler(Event.TYPE_SEARCH);
3511     }
3512 
3513     /**
3514      * Sets the {@code onsearch} event handler.
3515      * @param onsearch the {@code onsearch} event handler
3516      */
3517     @JsxSetter({CHROME, EDGE})
3518     public void setOnsearch(final Object onsearch) {
3519         setHandlerForJavaScript(Event.TYPE_SEARCH, onsearch);
3520     }
3521 
3522     /**
3523      * Returns the {@code oninput} event handler.
3524      * @return the {@code oninput} event handler
3525      */
3526     @JsxGetter
3527     public Function getOninput() {
3528         return getEventHandler(Event.TYPE_INPUT);
3529     }
3530 
3531     /**
3532      * Sets the {@code oninput} event handler.
3533      * @param oninput the {@code oninput} event handler
3534      */
3535     @JsxSetter
3536     public void setOninput(final Object oninput) {
3537         setHandlerForJavaScript(Event.TYPE_INPUT, oninput);
3538     }
3539 
3540     /**
3541      * Returns the {@code onwebkittransitionend} event handler.
3542      * @return the {@code onwebkittransitionend} event handler
3543      */
3544     @JsxGetter({CHROME, EDGE})
3545     public Function getOnwebkittransitionend() {
3546         return getEventHandler(Event.TYPE_WEBKITTRANSITIONEND);
3547     }
3548 
3549     /**
3550      * Sets the {@code onwebkittransitionend} event handler.
3551      * @param onwebkittransitionend the {@code onwebkittransitionend} event handler
3552      */
3553     @JsxSetter({CHROME, EDGE})
3554     public void setOnwebkittransitionend(final Object onwebkittransitionend) {
3555         setHandlerForJavaScript(Event.TYPE_WEBKITTRANSITIONEND, onwebkittransitionend);
3556     }
3557 
3558     /**
3559      * Returns the {@code ondevicemotion} event handler.
3560      * @return the {@code ondevicemotion} event handler
3561      */
3562     @JsxGetter
3563     public Function getOndevicemotion() {
3564         return getEventHandler(Event.TYPE_DEVICEMOTION);
3565     }
3566 
3567     /**
3568      * Sets the {@code ondevicemotion} event handler.
3569      * @param ondevicemotion the {@code ondevicemotion} event handler
3570      */
3571     @JsxSetter
3572     public void setOndevicemotion(final Object ondevicemotion) {
3573         setHandlerForJavaScript(Event.TYPE_DEVICEMOTION, ondevicemotion);
3574     }
3575 
3576     /**
3577      * Returns the {@code onstalled} event handler.
3578      * @return the {@code onstalled} event handler
3579      */
3580     @JsxGetter
3581     public Function getOnstalled() {
3582         return getEventHandler(Event.TYPE_STALLED);
3583     }
3584 
3585     /**
3586      * Sets the {@code onstalled} event handler.
3587      * @param onstalled the {@code onstalled} event handler
3588      */
3589     @JsxSetter
3590     public void setOnstalled(final Object onstalled) {
3591         setHandlerForJavaScript(Event.TYPE_STALLED, onstalled);
3592     }
3593 
3594     /**
3595      * Returns the {@code onmouseenter} event handler.
3596      * @return the {@code onmouseenter} event handler
3597      */
3598     @JsxGetter
3599     public Function getOnmouseenter() {
3600         return getEventHandler(Event.TYPE_MOUDEENTER);
3601     }
3602 
3603     /**
3604      * Sets the {@code onmouseenter} event handler.
3605      * @param onmouseenter the {@code onmouseenter} event handler
3606      */
3607     @JsxSetter
3608     public void setOnmouseenter(final Object onmouseenter) {
3609         setHandlerForJavaScript(Event.TYPE_MOUDEENTER, onmouseenter);
3610     }
3611 
3612     /**
3613      * Returns the {@code ondragleave} event handler.
3614      * @return the {@code ondragleave} event handler
3615      */
3616     @JsxGetter
3617     public Function getOndragleave() {
3618         return getEventHandler(Event.TYPE_DRAGLEAVE);
3619     }
3620 
3621     /**
3622      * Sets the {@code ondragleave} event handler.
3623      * @param ondragleave the {@code ondragleave} event handler
3624      */
3625     @JsxSetter
3626     public void setOndragleave(final Object ondragleave) {
3627         setHandlerForJavaScript(Event.TYPE_DRAGLEAVE, ondragleave);
3628     }
3629 
3630     /**
3631      * Returns the {@code onpointerdown} event handler.
3632      * @return the {@code onpointerdown} event handler
3633      */
3634     @JsxGetter({CHROME, EDGE})
3635     public Function getOnpointerdown() {
3636         return getEventHandler(Event.TYPE_POINTERDOWN);
3637     }
3638 
3639     /**
3640      * Sets the {@code onpointerdown} event handler.
3641      * @param onpointerdown the {@code onpointerdown} event handler
3642      */
3643     @JsxSetter({CHROME, EDGE})
3644     public void setOnpointerdown(final Object onpointerdown) {
3645         setHandlerForJavaScript(Event.TYPE_POINTERDOWN, onpointerdown);
3646     }
3647 
3648     /**
3649      * Returns the {@code ondrop} event handler.
3650      * @return the {@code ondrop} event handler
3651      */
3652     @JsxGetter
3653     public Function getOndrop() {
3654         return getEventHandler(Event.TYPE_DROP);
3655     }
3656 
3657     /**
3658      * Sets the {@code ondrop} event handler.
3659      * @param ondrop the {@code ondrop} event handler
3660      */
3661     @JsxSetter
3662     public void setOndrop(final Object ondrop) {
3663         setHandlerForJavaScript(Event.TYPE_DROP, ondrop);
3664     }
3665 
3666     /**
3667      * Returns the {@code onunload} event handler.
3668      * @return the {@code onunload} event handler
3669      */
3670     @JsxGetter
3671     public Function getOnunload() {
3672         return getEventHandler(Event.TYPE_UNLOAD);
3673     }
3674 
3675     /**
3676      * Sets the {@code onunload} event handler.
3677      * @param onunload the {@code onunload} event handler
3678      */
3679     @JsxSetter
3680     public void setOnunload(final Object onunload) {
3681         setHandlerForJavaScript(Event.TYPE_UNLOAD, onunload);
3682     }
3683 
3684     /**
3685      * Returns the {@code onwebkitanimationend} event handler.
3686      * @return the {@code onwebkitanimationend} event handler
3687      */
3688     @JsxGetter({CHROME, EDGE})
3689     public Function getOnwebkitanimationend() {
3690         return getEventHandler(Event.TYPE_WEBKITANIMATIONEND);
3691     }
3692 
3693     /**
3694      * Sets the {@code onwebkitanimationend} event handler.
3695      * @param onwebkitanimationend the {@code onwebkitanimationend} event handler
3696      */
3697     @JsxSetter({CHROME, EDGE})
3698     public void setOnwebkitanimationend(final Object onwebkitanimationend) {
3699         setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONEND, onwebkitanimationend);
3700     }
3701 
3702     /**
3703      * Returns the {@code ondragstart} event handler.
3704      * @return the {@code ondragstart} event handler
3705      */
3706     @JsxGetter
3707     public Function getOndragstart() {
3708         return getEventHandler(Event.TYPE_DRAGSTART);
3709     }
3710 
3711     /**
3712      * Sets the {@code ondragstart} event handler.
3713      * @param ondragstart the {@code ondragstart} event handler
3714      */
3715     @JsxSetter
3716     public void setOndragstart(final Object ondragstart) {
3717         setHandlerForJavaScript(Event.TYPE_DRAGSTART, ondragstart);
3718     }
3719 
3720     /**
3721      * Returns the {@code ontransitionend} event handler.
3722      * @return the {@code ontransitionend} event handler
3723      */
3724     @JsxGetter({CHROME, EDGE})
3725     public Function getOntransitionend() {
3726         return getEventHandler(Event.TYPE_TRANSITIONEND);
3727     }
3728 
3729     /**
3730      * Sets the {@code ontransitionend} event handler.
3731      * @param ontransitionend the {@code ontransitionend} event handler
3732      */
3733     @JsxSetter({CHROME, EDGE})
3734     public void setOntransitionend(final Object ontransitionend) {
3735         setHandlerForJavaScript(Event.TYPE_TRANSITIONEND, ontransitionend);
3736     }
3737 
3738     /**
3739      * Returns the {@code ondeviceorientationabsolute} event handler.
3740      * @return the {@code ondeviceorientationabsolute} event handler
3741      */
3742     @JsxGetter({CHROME, EDGE})
3743     public Function getOndeviceorientationabsolute() {
3744         return getEventHandler(Event.TYPE_DEVICEORIENTATIONABSOLUTE);
3745     }
3746 
3747     /**
3748      * Sets the {@code ondeviceorientationabsolute} event handler.
3749      * @param ondeviceorientationabsolute the {@code ondeviceorientationabsolute} event handler
3750      */
3751     @JsxSetter({CHROME, EDGE})
3752     public void setOndeviceorientationabsolute(final Object ondeviceorientationabsolute) {
3753         setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATIONABSOLUTE, ondeviceorientationabsolute);
3754     }
3755 
3756     /**
3757      * Returns the {@code onvolumechange} event handler.
3758      * @return the {@code onvolumechange} event handler
3759      */
3760     @JsxGetter
3761     public Function getOnvolumechange() {
3762         return getEventHandler(Event.TYPE_VOLUMECHANGE);
3763     }
3764 
3765     /**
3766      * Sets the {@code onvolumechange} event handler.
3767      * @param onvolumechange the {@code onvolumechange} event handler
3768      */
3769     @JsxSetter
3770     public void setOnvolumechange(final Object onvolumechange) {
3771         setHandlerForJavaScript(Event.TYPE_VOLUMECHANGE, onvolumechange);
3772     }
3773 
3774     /**
3775      * Returns the {@code ongotpointercapture} event handler.
3776      * @return the {@code ongotpointercapture} event handler
3777      */
3778     @JsxGetter({CHROME, EDGE})
3779     public Function getOngotpointercapture() {
3780         return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
3781     }
3782 
3783     /**
3784      * Sets the {@code ongotpointercapture} event handler.
3785      * @param ongotpointercapture the {@code ongotpointercapture} event handler
3786      */
3787     @JsxSetter({CHROME, EDGE})
3788     public void setOngotpointercapture(final Object ongotpointercapture) {
3789         setHandlerForJavaScript(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
3790     }
3791 
3792     /**
3793      * Returns the {@code onpopstate} event handler.
3794      * @return the {@code onpopstate} event handler
3795      */
3796     @JsxGetter
3797     public Function getOnpopstate() {
3798         return getEventHandler(Event.TYPE_POPSTATE);
3799     }
3800 
3801     /**
3802      * Sets the {@code onpopstate} event handler.
3803      * @param onpopstate the {@code onpopstate} event handler
3804      */
3805     @JsxSetter
3806     public void setOnpopstate(final Object onpopstate) {
3807         setHandlerForJavaScript(Event.TYPE_POPSTATE, onpopstate);
3808     }
3809 
3810     /**
3811      * {@inheritDoc}
3812      * optimized version
3813      */
3814     @Override
3815     public BrowserVersion getBrowserVersion() {
3816         return getWebWindow().getWebClient().getBrowserVersion();
3817     }
3818 
3819     @Override
3820     public void put(final String name, final Scriptable start, final Object value) {
3821         // see https://dom.spec.whatwg.org/#window-current-event
3822         // because event is replaceable we need this hack here
3823         if ("event".equals(name)) {
3824             final Slot slot = querySlot(Context.getCurrentContext(), "event");
3825             if (slot instanceof AccessorSlot) {
3826                 delete("event");
3827             }
3828         }
3829         super.put(name, start, value);
3830     }
3831 
3832     /**
3833      * @return a boolean indicating whether the current context is secure (true) or not (false).
3834      */
3835     @JsxGetter
3836     public boolean getIsSecureContext() {
3837         final Page page = getWebWindow().getEnclosedPage();
3838         if (page != null) {
3839             final String protocol = page.getUrl().getProtocol();
3840             if ("https".equals(protocol)
3841                     || "wss".equals(protocol)
3842                     || "file".equals(protocol)) {
3843                 return true;
3844             }
3845 
3846             final String host = page.getUrl().getHost();
3847             if ("localhost".equals(host)
3848                     || "localhost.".equals(host)
3849                     || host.endsWith(".localhost")
3850                     || host.endsWith(".localhost.")) {
3851                 return true;
3852             }
3853         }
3854 
3855         return false;
3856     }
3857 }
3858 
3859 class HTMLCollectionFrames extends HTMLCollection {
3860     private static final Log LOG = LogFactory.getLog(HTMLCollectionFrames.class);
3861 
3862     HTMLCollectionFrames(final HtmlPage page) {
3863         super(page, false);
3864         this.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof BaseFrameElement);
3865     }
3866 
3867     @Override
3868     protected Scriptable getScriptableForElement(final Object obj) {
3869         final WebWindow window;
3870         if (obj instanceof BaseFrameElement) {
3871             window = ((BaseFrameElement) obj).getEnclosedWindow();
3872         }
3873         else {
3874             window = ((FrameWindow) obj).getFrameElement().getEnclosedWindow();
3875         }
3876 
3877         return window.getScriptableObject();
3878     }
3879 
3880     @Override
3881     protected Object getWithPreemption(final String name) {
3882         final List<DomNode> elements = getElements();
3883 
3884         for (final Object next : elements) {
3885             final BaseFrameElement frameElt = (BaseFrameElement) next;
3886             final WebWindow window = frameElt.getEnclosedWindow();
3887             if (name.equals(window.getName())) {
3888                 if (LOG.isDebugEnabled()) {
3889                     LOG.debug("Property \"" + name + "\" evaluated (by name) to " + window);
3890                 }
3891                 return getScriptableForElement(window);
3892             }
3893         }
3894 
3895         return NOT_FOUND;
3896     }
3897 }