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 
1463         // May be attempting to retrieve a frame by name.
1464         final HtmlPage page = (HtmlPage) domNode.getPage();
1465         Object result = getFrameWindowByName(page, name);
1466 
1467         if (result == NOT_FOUND) {
1468             result = getElementsByName(page, name);
1469 
1470             if (result == NOT_FOUND) {
1471                 // May be attempting to retrieve element by ID (try map-backed operation again instead of XPath).
1472                 try {
1473                     final HtmlElement htmlElement = page.getHtmlElementById(name);
1474                     result = getScriptableFor(htmlElement);
1475                 }
1476                 catch (final ElementNotFoundException e) {
1477                     result = NOT_FOUND;
1478                 }
1479             }
1480         }
1481 
1482         if (result instanceof Window) {
1483             final WebWindow webWindow = ((Window) result).getWebWindow();
1484             result = getProxy(webWindow);
1485         }
1486 
1487         return result;
1488     }
1489 
1490     /**
1491      * {@inheritDoc}
1492      */
1493     @Override
1494     public Object get(final int index, final Scriptable start) {
1495         if (index < 0 || getWebWindow() == null) {
1496             return JavaScriptEngine.UNDEFINED;
1497         }
1498 
1499         final HTMLCollection frames = getFrames();
1500         if (frames == null || index >= frames.getLength()) {
1501             return JavaScriptEngine.UNDEFINED;
1502         }
1503         return frames.item(Integer.valueOf(index));
1504     }
1505 
1506     private static Object getFrameWindowByName(final HtmlPage page, final String name) {
1507         try {
1508             return page.getFrameByName(name).getScriptableObject();
1509         }
1510         catch (final ElementNotFoundException e) {
1511             return NOT_FOUND;
1512         }
1513     }
1514 
1515     private Object getElementsByName(final HtmlPage page, final String name) {
1516 
1517         // May be attempting to retrieve element(s) by name. IMPORTANT: We're using map-backed operations
1518         // like getHtmlElementsByName() and getHtmlElementById() as much as possible, so as to avoid XPath
1519         // overhead. We only use an XPath-based operation when we have to (where there is more than one
1520         // matching element). This optimization appears to improve performance in certain situations by ~15%
1521         // vs using XPath-based operations throughout.
1522         final List<DomElement> elements = page.getElementsByName(name);
1523 
1524         final Filter filter = new Filter(false);
1525 
1526         elements.removeIf(domElement -> !filter.matches(domElement));
1527 
1528         if (elements.isEmpty()) {
1529             return NOT_FOUND;
1530         }
1531 
1532         if (elements.size() == 1) {
1533             return getScriptableFor(elements.get(0));
1534         }
1535 
1536         // Null must be changed to '' for proper collection initialization.
1537         final String expElementName = "null".equals(name) ? "" : name;
1538 
1539         final HTMLCollection coll = new HTMLCollection(page, true);
1540         coll.setElementsSupplier(
1541                 (Supplier<List<DomNode>> & Serializable)
1542                 () -> {
1543                     final List<DomElement> expElements = page.getElementsByName(expElementName);
1544                     final List<DomNode> result = new ArrayList<>(expElements.size());
1545 
1546                     for (final DomElement domElement : expElements) {
1547                         if (filter.matches(domElement)) {
1548                             result.add(domElement);
1549                         }
1550                     }
1551                     return result;
1552                 });
1553 
1554         coll.setEffectOnCacheFunction(
1555                 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1556                 event -> {
1557                     if ("name".equals(event.getName())) {
1558                         return EffectOnCache.RESET;
1559                     }
1560                     return EffectOnCache.NONE;
1561                 });
1562 
1563         return coll;
1564     }
1565 
1566     /**
1567      * Returns the proxy for the specified window.
1568      * @param w the window whose proxy is to be returned
1569      * @return the proxy for the specified window
1570      */
1571     public static WindowProxy getProxy(final WebWindow w) {
1572         return ((Window) w.getScriptableObject()).windowProxy_;
1573     }
1574 
1575     /**
1576      * Returns the text from the status line.
1577      * @return the status line text
1578      */
1579     @JsxGetter
1580     public String getStatus() {
1581         return status_;
1582     }
1583 
1584     /**
1585      * Sets the text from the status line.
1586      * @param message the status line text
1587      */
1588     @JsxSetter
1589     public void setStatus(final String message) {
1590         status_ = message;
1591 
1592         final StatusHandler statusHandler = webWindow_.getWebClient().getStatusHandler();
1593         if (statusHandler != null) {
1594             statusHandler.statusMessageChanged(webWindow_.getEnclosedPage(), message);
1595         }
1596     }
1597 
1598     /**
1599      * Returns the {@code innerWidth}.
1600      * @return the {@code innerWidth}
1601      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref28.html">Mozilla doc</a>
1602      */
1603     @JsxGetter
1604     public int getInnerWidth() {
1605         return getWebWindow().getInnerWidth();
1606     }
1607 
1608     /**
1609      * Sets the {@code innerWidth}.
1610      * @param width the {@code innerWidth}
1611      */
1612     @JsxSetter
1613     public void setInnerWidth(final int width) {
1614         getWebWindow().setInnerWidth(width);
1615     }
1616 
1617     /**
1618      * Returns the {@code outerWidth}.
1619      * @return the {@code outerWidth}
1620      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref79.html">Mozilla doc</a>
1621      */
1622     @JsxGetter
1623     public int getOuterWidth() {
1624         return getWebWindow().getOuterWidth();
1625     }
1626 
1627     /**
1628      * Sets the {@code outerWidth}.
1629      * @param width the {@code outerWidth}
1630      */
1631     @JsxSetter
1632     public void setOuterWidth(final int width) {
1633         getWebWindow().setOuterWidth(width);
1634     }
1635 
1636     /**
1637      * Returns the {@code innerHeight}.
1638      * @return the {@code innerHeight}
1639      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref27.html">Mozilla doc</a>
1640      */
1641     @JsxGetter
1642     public int getInnerHeight() {
1643         return getWebWindow().getInnerHeight();
1644     }
1645 
1646     /**
1647      * Sets the {@code innerHeight}.
1648      * @param height the {@code innerHeight}
1649      */
1650     @JsxSetter
1651     public void setInnerHeight(final int height) {
1652         getWebWindow().setInnerHeight(height);
1653     }
1654 
1655     /**
1656      * Returns the {@code outerHeight}.
1657      * @return the {@code outerHeight}
1658      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref78.html">Mozilla doc</a>
1659      */
1660     @JsxGetter
1661     public int getOuterHeight() {
1662         return getWebWindow().getOuterHeight();
1663     }
1664 
1665     /**
1666      * Sets the {@code outerHeight}.
1667      * @param height the {@code outerHeight}
1668      */
1669     @JsxSetter
1670     public void setOuterHeight(final int height) {
1671         getWebWindow().setOuterHeight(height);
1672     }
1673 
1674     /**
1675      * Prints the current page. The current implementation uses the {@link PrintHandler}
1676      * defined for the {@link WebClient} to process the window.
1677      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref85.html">
1678      *     Mozilla documentation</a>
1679      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536672.aspx">MSDN documentation</a>
1680      */
1681     @JsxFunction
1682     public void print() {
1683         final PrintHandler handler = getWebWindow().getWebClient().getPrintHandler();
1684         if (handler == null) {
1685             LOG.info("No PrintHandler installed - window.print() ignored");
1686             return;
1687         }
1688 
1689         final SgmlPage sgmlPage = getDocument().getPage();
1690         if (!(sgmlPage instanceof HtmlPage)) {
1691             LOG.debug("Page is not an HtmlPage - window.print() ignored");
1692             return;
1693         }
1694 
1695         Event event = new Event(this, Event.TYPE_BEFOREPRINT);
1696         fireEvent(event);
1697 
1698         final HtmlPage page = (HtmlPage) sgmlPage;
1699         page.setPrinting(true);
1700         try {
1701             handler.handlePrint(page);
1702         }
1703         finally {
1704             page.setPrinting(false);
1705         }
1706         event = new Event(this, Event.TYPE_AFTERPRINT);
1707         fireEvent(event);
1708     }
1709 
1710     /**
1711      * Does nothing special anymore.
1712      * @param type the type of events to capture
1713      * @see HTMLDocument#captureEvents(String)
1714      */
1715     @JsxFunction
1716     public void captureEvents(final String type) {
1717         // Empty.
1718     }
1719 
1720     /**
1721      * Does nothing special anymore.
1722      * @param type the type of events to capture
1723      * @see HTMLDocument#releaseEvents(String)
1724      */
1725     @JsxFunction
1726     public void releaseEvents(final String type) {
1727         // Empty.
1728     }
1729 
1730     /**
1731      * Returns computed style of the element. Computed style represents the final computed values
1732      * of all CSS properties for the element. This method's return value is of the same type as
1733      * that of <code>element.style</code>, but the value returned by this method is read-only.
1734      *
1735      * @param element the element
1736      * @param pseudoElement a string specifying the pseudo-element to match (may be {@code null});
1737      *        e.g. ':before'
1738      * @return the computed style
1739      */
1740     @JsxFunction
1741     public ComputedCSSStyleDeclaration getComputedStyle(final Object element, final String pseudoElement) {
1742         if (!(element instanceof Element)) {
1743             throw JavaScriptEngine.typeError("parameter 1 is not of type 'Element'");
1744         }
1745         final Element e = (Element) element;
1746 
1747         final ComputedCssStyleDeclaration style = getWebWindow().getComputedStyle(e.getDomNodeOrDie(), pseudoElement);
1748         return new ComputedCSSStyleDeclaration(e, style);
1749     }
1750 
1751     /**
1752      * Returns the current selection.
1753      * @return the current selection
1754      */
1755     @JsxFunction
1756     public Selection getSelection() {
1757         final WebWindow webWindow = getWebWindow();
1758         // return null if the window is in a frame that is not displayed
1759         if (webWindow instanceof FrameWindow) {
1760             final FrameWindow frameWindow = (FrameWindow) webWindow;
1761             if (getBrowserVersion().hasFeature(JS_WINDOW_SELECTION_NULL_IF_INVISIBLE)
1762                     && !frameWindow.getFrameElement().isDisplayed()) {
1763                 return null;
1764             }
1765         }
1766         return getSelectionImpl();
1767     }
1768 
1769     /**
1770      * Returns the current selection.
1771      * @return the current selection
1772      */
1773     public Selection getSelectionImpl() {
1774         if (selection_ == null) {
1775             selection_ = new Selection();
1776             selection_.setParentScope(this);
1777             selection_.setPrototype(getPrototype(selection_.getClass()));
1778         }
1779         return selection_;
1780     }
1781 
1782     /**
1783      * Gets the {@code controllers}. The result doesn't currently matter but it is important to return an
1784      * object as some JavaScript libraries check it.
1785      * @see <a href="https://developer.mozilla.org/En/DOM/Window.controllers">Mozilla documentation</a>
1786      * @return some object
1787      */
1788     @JsxGetter({FF, FF_ESR})
1789     public Object getControllers() {
1790         return controllers_;
1791     }
1792 
1793     /**
1794      * Sets the {@code controllers}.
1795      * @param value the new value
1796      */
1797     @JsxSetter({FF, FF_ESR})
1798     public void setControllers(final Object value) {
1799         controllers_ = value;
1800     }
1801 
1802     /**
1803      * Returns the value of {@code mozInnerScreenX} property.
1804      * @return the value of {@code mozInnerScreenX} property
1805      */
1806     @JsxGetter(FF)
1807     public int getMozInnerScreenX() {
1808         return 12;
1809     }
1810 
1811     /**
1812      * Returns the value of {@code mozInnerScreenX} property.
1813      * @return the value of {@code mozInnerScreenX} property
1814      */
1815     @JsxGetter(value = FF_ESR, propertyName = "mozInnerScreenX")
1816     public int getMozInnerScreenXffesr_js() {
1817         return 10;
1818     }
1819 
1820     /**
1821      * Returns the value of {@code mozInnerScreenY} property.
1822      * @return the value of {@code mozInnerScreenY} property
1823      */
1824     @JsxGetter({FF, FF_ESR})
1825     public int getMozInnerScreenY() {
1826         return 89;
1827     }
1828 
1829     private static final class Filter {
1830         private final boolean includeFormFields_;
1831 
1832         Filter(final boolean includeFormFields) {
1833             includeFormFields_ = includeFormFields;
1834         }
1835 
1836         boolean matches(final Object object) {
1837             if (object instanceof HtmlEmbed
1838                 || object instanceof HtmlForm
1839                 || object instanceof HtmlImage
1840                 || object instanceof HtmlObject) {
1841                 return true;
1842             }
1843 
1844             return includeFormFields_
1845                     && (object instanceof HtmlAnchor
1846                         || object instanceof HtmlButton
1847                         || object instanceof HtmlInput
1848                         || object instanceof HtmlMap
1849                         || object instanceof HtmlSelect
1850                         || object instanceof HtmlTextArea);
1851         }
1852     }
1853 
1854     /**
1855      * Should implement the stop() function on the window object.
1856      * (currently empty implementation)
1857      * @see <a href="https://developer.mozilla.org/en/DOM/window.stop">window.stop</a>
1858      */
1859     @JsxFunction
1860     public void stop() {
1861         //empty
1862     }
1863 
1864     /**
1865      * Returns the value of {@code pageXOffset} property.
1866      * @return the value of {@code pageXOffset} property
1867      */
1868     @JsxGetter
1869     public int getPageXOffset() {
1870         return 0;
1871     }
1872 
1873     /**
1874      * Returns the value of {@code pageYOffset} property.
1875      * @return the value of {@code pageYOffset} property
1876      */
1877     @JsxGetter
1878     public int getPageYOffset() {
1879         return 0;
1880     }
1881 
1882     /**
1883      * Returns the value of {@code scrollX} property.
1884      * @return the value of {@code scrollX} property
1885      */
1886     @JsxGetter
1887     public int getScrollX() {
1888         return 0;
1889     }
1890 
1891     /**
1892      * Returns the value of {@code scrollY} property.
1893      * @return the value of {@code scrollY} property
1894      */
1895     @JsxGetter
1896     public int getScrollY() {
1897         return 0;
1898     }
1899 
1900     /**
1901      * @return the value of {@code netscape} property
1902      */
1903     @JsxGetter({FF, FF_ESR})
1904     public Netscape getNetscape() {
1905         return new Netscape(this);
1906     }
1907 
1908     /**
1909      * {@inheritDoc}
1910      * Used to allow re-declaration of constants (eg: "var undefined;").
1911      */
1912     @Override
1913     public boolean isConst(final String name) {
1914         if ("undefined".equals(name) || "Infinity".equals(name) || "NaN".equals(name)) {
1915             return false;
1916         }
1917 
1918         return super.isConst(name);
1919     }
1920 
1921     /**
1922      * {@inheritDoc}
1923      */
1924     @Override
1925     public boolean dispatchEvent(final Event event) {
1926         event.setTarget(this);
1927         final ScriptResult result = fireEvent(event);
1928         return !event.isAborted(result);
1929     }
1930 
1931     /**
1932      * Getter for the {@code onchange} event handler.
1933      * @return the handler
1934      */
1935     @JsxGetter
1936     public Function getOnchange() {
1937         return getEventHandler(Event.TYPE_CHANGE);
1938     }
1939 
1940     /**
1941      * Setter for the {@code onchange} event handler.
1942      * @param onchange the handler
1943      */
1944     @JsxSetter
1945     public void setOnchange(final Object onchange) {
1946         setHandlerForJavaScript(Event.TYPE_CHANGE, onchange);
1947     }
1948 
1949     /**
1950      * Getter for the {@code onsubmit} event handler.
1951      * @return the handler
1952      */
1953     @JsxGetter
1954     public Function getOnsubmit() {
1955         return getEventHandler(Event.TYPE_SUBMIT);
1956     }
1957 
1958     /**
1959      * Setter for the {@code onsubmit} event handler.
1960      * @param onsubmit the handler
1961      */
1962     @JsxSetter
1963     public void setOnsubmit(final Object onsubmit) {
1964         setHandlerForJavaScript(Event.TYPE_SUBMIT, onsubmit);
1965     }
1966 
1967     /**
1968      * Posts a message.
1969      * @param context the current context
1970      * @param scope the scope
1971      * @param thisObj this object
1972      * @param args the script(s) to import
1973      * @param funObj the JS function called
1974      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage">MDN documentation</a>
1975      */
1976     @JsxFunction
1977     public static void postMessage(final Context context, final Scriptable scope,
1978             final Scriptable thisObj, final Object[] args, final Function funObj) {
1979 
1980         // support the structured clone algorithm
1981         if (args.length < 1) {
1982             throw JavaScriptEngine.typeError("message not provided");
1983         }
1984         final Object message = args[0];
1985 
1986         String targetOrigin = "*";
1987         if (args.length > 1) {
1988             targetOrigin = JavaScriptEngine.toString(args[1]);
1989         }
1990 
1991         Object transfer = JavaScriptEngine.UNDEFINED;
1992         if (args.length > 2) {
1993             transfer = args[2];
1994         }
1995 
1996         final Window sender = (Window) scope;
1997         final Window receiver = (Window) thisObj;
1998         final URL receiverURL = receiver.getWebWindow().getEnclosedPage().getUrl();
1999 
2000         final WebWindow webWindow = sender.getWebWindow();
2001         final Page page = webWindow.getEnclosedPage();
2002         final URL senderURL = page.getUrl();
2003 
2004         if (!org.htmlunit.util.StringUtils.equalsChar('*', targetOrigin)) {
2005             final URL targetURL;
2006             if (org.htmlunit.util.StringUtils.equalsChar('/', targetOrigin)) {
2007                 targetURL = senderURL;
2008             }
2009             else {
2010                 try {
2011                     targetURL = new URL(targetOrigin);
2012                 }
2013                 catch (final Exception e) {
2014                     throw JavaScriptEngine.asJavaScriptException(
2015                             (HtmlUnitScriptable) getTopLevelScope(thisObj),
2016                             "Failed to execute 'postMessage' on 'Window': Invalid target origin '"
2017                                     + targetOrigin + "' was specified (reason: " + e.getMessage() + ".",
2018                             DOMException.SYNTAX_ERR);
2019                 }
2020             }
2021 
2022             if (getPort(targetURL) != getPort(receiverURL)) {
2023                 return;
2024             }
2025             if (!targetURL.getHost().equals(receiverURL.getHost())) {
2026                 return;
2027             }
2028             if (!targetURL.getProtocol().equals(receiverURL.getProtocol())) {
2029                 return;
2030             }
2031         }
2032 
2033         String origin = "";
2034         try {
2035             final URL originUrl = UrlUtils.getUrlWithoutPathRefQuery(senderURL);
2036             origin = UrlUtils.removeRedundantPort(originUrl).toExternalForm();
2037         }
2038         catch (final MalformedURLException e) {
2039             throw JavaScriptEngine.throwAsScriptRuntimeEx(e);
2040         }
2041 
2042         final MessageEvent event = new MessageEvent();
2043         event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin, "", sender, transfer);
2044         event.setParentScope(scope);
2045         event.setPrototype(receiver.getPrototype(event.getClass()));
2046 
2047         final AbstractJavaScriptEngine<?> jsEngine = webWindow.getWebClient().getJavaScriptEngine();
2048         final PostponedAction action = new PostponedAction(page, "Window.postMessage") {
2049             @Override
2050             public void execute() {
2051                 final HtmlUnitContextFactory cf = jsEngine.getContextFactory();
2052                 cf.call(cx -> receiver.dispatchEvent(event));
2053             }
2054         };
2055         jsEngine.addPostponedAction(action);
2056     }
2057 
2058     /**
2059      * Returns the port of the specified URL.
2060      * @param url the URL
2061      * @return the port
2062      */
2063     public static int getPort(final URL url) {
2064         int port = url.getPort();
2065         if (port == -1) {
2066             if ("http".equals(url.getProtocol())) {
2067                 port = 80;
2068             }
2069             else {
2070                 port = 443;
2071             }
2072         }
2073         return port;
2074     }
2075 
2076     /**
2077      * The performance attribute is defined as replacable
2078      * (https://w3c.github.io/hr-time/#the-performance-attribute) but not implemented
2079      * as that.
2080      * @return the value of the {@code performance} property
2081      */
2082     @JsxGetter
2083     public Scriptable getPerformance() {
2084         if (performance_ == null) {
2085             final Performance performance = new Performance();
2086             performance.setParentScope(this);
2087             performance.setPrototype(getPrototype(performance.getClass()));
2088             performance_ = performance;
2089         }
2090         return performance_;
2091     }
2092 
2093     /**
2094      * The performance attribute is defined as replacable
2095      * (https://w3c.github.io/hr-time/#the-performance-attribute) but not implemented
2096      * as that.
2097      *
2098      * Sets the {@code performance} property.
2099      * @param performance the value to overwrite the defined property value
2100      */
2101     @JsxSetter
2102     public void setPerformance(final Scriptable performance) {
2103         performance_ = performance;
2104     }
2105 
2106     /**
2107      * Returns the {@code devicePixelRatio} property.
2108      * @return the {@code devicePixelRatio} property
2109      */
2110     @JsxGetter
2111     public int getDevicePixelRatio() {
2112         return 1;
2113     }
2114 
2115     /**
2116      * Returns the {@code styleMedia} property.
2117      * @return the {@code styleMedia} property
2118      */
2119     @JsxGetter({CHROME, EDGE})
2120     public StyleMedia getStyleMedia() {
2121         final StyleMedia styleMedia = new StyleMedia();
2122         styleMedia.setParentScope(this);
2123         styleMedia.setPrototype(getPrototype(styleMedia.getClass()));
2124         return styleMedia;
2125     }
2126 
2127     /**
2128      * Returns a new MediaQueryList object representing the parsed results of the specified media query string.
2129      *
2130      * @param mediaQueryString the media query
2131      * @return a new MediaQueryList object
2132      */
2133     @JsxFunction
2134     public MediaQueryList matchMedia(final String mediaQueryString) {
2135         final MediaQueryList mediaQueryList = new MediaQueryList(mediaQueryString);
2136         mediaQueryList.setParentScope(this);
2137         mediaQueryList.setPrototype(getPrototype(mediaQueryList.getClass()));
2138         return mediaQueryList;
2139     }
2140 
2141     /**
2142      * Stub only at the moment.
2143      * @param search the text string for which to search
2144      * @param caseSensitive if true, specifies a case-sensitive search
2145      * @param backwards if true, specifies a backward search
2146      * @param wrapAround if true, specifies a wrap around search
2147      * @param wholeWord if true, specifies a whole word search
2148      * @param searchInFrames if true, specifies a search in frames
2149      * @param showDialog if true, specifies a show Dialog.
2150      * @return false
2151      */
2152     @JsxFunction
2153     public boolean find(final String search, final boolean caseSensitive,
2154             final boolean backwards, final boolean wrapAround,
2155             final boolean wholeWord, final boolean searchInFrames, final boolean showDialog) {
2156         return false;
2157     }
2158 
2159     /**
2160      * Returns the {@code speechSynthesis} property.
2161      * @return the {@code speechSynthesis} property
2162      */
2163     @JsxGetter({CHROME, EDGE})
2164     public SpeechSynthesis getSpeechSynthesis() {
2165         final SpeechSynthesis speechSynthesis = new SpeechSynthesis();
2166         speechSynthesis.setParentScope(this);
2167         speechSynthesis.setPrototype(getPrototype(speechSynthesis.getClass()));
2168         return speechSynthesis;
2169     }
2170 
2171     /**
2172      * Returns the {@code offscreenBuffering} property.
2173      * @return the {@code offscreenBuffering} property
2174      */
2175     @JsxGetter({CHROME, EDGE})
2176     public boolean getOffscreenBuffering() {
2177         return true;
2178     }
2179 
2180     /**
2181      * Returns the {@code crypto} property.
2182      * @return the {@code crypto} property
2183      */
2184     @JsxGetter
2185     public Crypto getCrypto() {
2186         if (crypto_ == null) {
2187             crypto_ = new Crypto(this);
2188         }
2189         return crypto_;
2190     }
2191 
2192     /**
2193      * {@inheritDoc}
2194      */
2195     @Override
2196     public void close() {
2197         // nothing to do
2198     }
2199 
2200     /**
2201      * Does nothing.
2202      * @param parent the new parent scope
2203      */
2204     @Override
2205     public void setParentScope(final Scriptable parent) {
2206         // nothing as the window is the top level scope and its parent scope should stay null
2207     }
2208 
2209     /**
2210      * Returns the {@code onfocus} event handler.
2211      * @return the {@code onfocus} event handler
2212      */
2213     @JsxGetter
2214     public Function getOnfocus() {
2215         return getEventHandler(Event.TYPE_FOCUS);
2216     }
2217 
2218     /**
2219      * Sets the {@code onfocus} event handler.
2220      * @param onfocus the {@code onfocus} event handler
2221      */
2222     @JsxSetter
2223     public void setOnfocus(final Object onfocus) {
2224         setHandlerForJavaScript(Event.TYPE_FOCUS, onfocus);
2225     }
2226 
2227     /**
2228      * Returns the {@code ondragend} event handler.
2229      * @return the {@code ondragend} event handler
2230      */
2231     @JsxGetter
2232     public Function getOndragend() {
2233         return getEventHandler(Event.TYPE_DRAGEND);
2234     }
2235 
2236     /**
2237      * Sets the {@code ondragend} event handler.
2238      * @param ondragend the {@code ondragend} event handler
2239      */
2240     @JsxSetter
2241     public void setOndragend(final Object ondragend) {
2242         setHandlerForJavaScript(Event.TYPE_DRAGEND, ondragend);
2243     }
2244 
2245     /**
2246      * Returns the {@code oninvalid} event handler.
2247      * @return the {@code oninvalid} event handler
2248      */
2249     @JsxGetter
2250     public Function getOninvalid() {
2251         return getEventHandler(Event.TYPE_INVALID);
2252     }
2253 
2254     /**
2255      * Sets the {@code oninvalid} event handler.
2256      * @param oninvalid the {@code oninvalid} event handler
2257      */
2258     @JsxSetter
2259     public void setOninvalid(final Object oninvalid) {
2260         setHandlerForJavaScript(Event.TYPE_INVALID, oninvalid);
2261     }
2262 
2263     /**
2264      * Returns the {@code onpointerout} event handler.
2265      * @return the {@code onpointerout} event handler
2266      */
2267     @JsxGetter({CHROME, EDGE})
2268     public Function getOnpointerout() {
2269         return getEventHandler(Event.TYPE_POINTEROUT);
2270     }
2271 
2272     /**
2273      * Sets the {@code onpointerout} event handler.
2274      * @param onpointerout the {@code onpointerout} event handler
2275      */
2276     @JsxSetter({CHROME, EDGE})
2277     public void setOnpointerout(final Object onpointerout) {
2278         setHandlerForJavaScript(Event.TYPE_POINTEROUT, onpointerout);
2279     }
2280 
2281     /**
2282      * Returns the {@code onratechange} event handler.
2283      * @return the {@code onratechange} event handler
2284      */
2285     @JsxGetter
2286     public Function getOnratechange() {
2287         return getEventHandler(Event.TYPE_RATECHANGE);
2288     }
2289 
2290     /**
2291      * Sets the {@code onratechange} event handler.
2292      * @param onratechange the {@code onratechange} event handler
2293      */
2294     @JsxSetter
2295     public void setOnratechange(final Object onratechange) {
2296         setHandlerForJavaScript(Event.TYPE_RATECHANGE, onratechange);
2297     }
2298 
2299     /**
2300      * Returns the {@code onanimationiteration} event handler.
2301      * @return the {@code onanimationiteration} event handler
2302      */
2303     @JsxGetter
2304     public Function getOnanimationiteration() {
2305         return getEventHandler(Event.TYPE_ANIMATIONITERATION);
2306     }
2307 
2308     /**
2309      * Sets the {@code onanimationiteration} event handler.
2310      * @param onanimationiteration the {@code onanimationiteration} event handler
2311      */
2312     @JsxSetter
2313     public void setOnanimationiteration(final Object onanimationiteration) {
2314         setHandlerForJavaScript(Event.TYPE_ANIMATIONITERATION, onanimationiteration);
2315     }
2316 
2317     /**
2318      * Returns the {@code oncanplaythrough} event handler.
2319      * @return the {@code oncanplaythrough} event handler
2320      */
2321     @JsxGetter
2322     public Function getOncanplaythrough() {
2323         return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2324     }
2325 
2326     /**
2327      * Sets the {@code oncanplaythrough} event handler.
2328      * @param oncanplaythrough the {@code oncanplaythrough} event handler
2329      */
2330     @JsxSetter
2331     public void setOncanplaythrough(final Object oncanplaythrough) {
2332         setHandlerForJavaScript(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2333     }
2334 
2335     /**
2336      * Returns the {@code oncancel} event handler.
2337      * @return the {@code oncancel} event handler
2338      */
2339     @JsxGetter({CHROME, EDGE})
2340     public Function getOncancel() {
2341         return getEventHandler(Event.TYPE_CANCEL);
2342     }
2343 
2344     /**
2345      * Sets the {@code oncancel} event handler.
2346      * @param oncancel the {@code oncancel} event handler
2347      */
2348     @JsxSetter({CHROME, EDGE})
2349     public void setOncancel(final Object oncancel) {
2350         setHandlerForJavaScript(Event.TYPE_CANCEL, oncancel);
2351     }
2352 
2353     /**
2354      * Returns the {@code onpointerenter} event handler.
2355      * @return the {@code onpointerenter} event handler
2356      */
2357     @JsxGetter({CHROME, EDGE})
2358     public Function getOnpointerenter() {
2359         return getEventHandler(Event.TYPE_POINTERENTER);
2360     }
2361 
2362     /**
2363      * Sets the {@code onpointerenter} event handler.
2364      * @param onpointerenter the {@code onpointerenter} event handler
2365      */
2366     @JsxSetter({CHROME, EDGE})
2367     public void setOnpointerenter(final Object onpointerenter) {
2368         setHandlerForJavaScript(Event.TYPE_POINTERENTER, onpointerenter);
2369     }
2370 
2371     /**
2372      * Returns the {@code onselect} event handler.
2373      * @return the {@code onselect} event handler
2374      */
2375     @JsxGetter
2376     public Function getOnselect() {
2377         return getEventHandler(Event.TYPE_SELECT);
2378     }
2379 
2380     /**
2381      * Sets the {@code onselect} event handler.
2382      * @param onselect the {@code onselect} event handler
2383      */
2384     @JsxSetter
2385     public void setOnselect(final Object onselect) {
2386         setHandlerForJavaScript(Event.TYPE_SELECT, onselect);
2387     }
2388 
2389     /**
2390      * Returns the {@code onauxclick} event handler.
2391      * @return the {@code onauxclick} event handler
2392      */
2393     @JsxGetter({CHROME, EDGE})
2394     public Function getOnauxclick() {
2395         return getEventHandler(Event.TYPE_AUXCLICK);
2396     }
2397 
2398     /**
2399      * Sets the {@code onauxclick} event handler.
2400      * @param onauxclick the {@code onauxclick} event handler
2401      */
2402     @JsxSetter({CHROME, EDGE})
2403     public void setOnauxclick(final Object onauxclick) {
2404         setHandlerForJavaScript(Event.TYPE_AUXCLICK, onauxclick);
2405     }
2406 
2407     /**
2408      * Returns the {@code onscroll} event handler.
2409      * @return the {@code onscroll} event handler
2410      */
2411     @JsxGetter
2412     public Function getOnscroll() {
2413         return getEventHandler(Event.TYPE_SCROLL);
2414     }
2415 
2416     /**
2417      * Sets the {@code onscroll} event handler.
2418      * @param onscroll the {@code onscroll} event handler
2419      */
2420     @JsxSetter
2421     public void setOnscroll(final Object onscroll) {
2422         setHandlerForJavaScript(Event.TYPE_SCROLL, onscroll);
2423     }
2424 
2425     /**
2426      * Returns the {@code onkeydown} event handler.
2427      * @return the {@code onkeydown} event handler
2428      */
2429     @JsxGetter
2430     public Function getOnkeydown() {
2431         return getEventHandler(Event.TYPE_KEY_DOWN);
2432     }
2433 
2434     /**
2435      * Sets the {@code onkeydown} event handler.
2436      * @param onkeydown the {@code onkeydown} event handler
2437      */
2438     @JsxSetter
2439     public void setOnkeydown(final Object onkeydown) {
2440         setHandlerForJavaScript(Event.TYPE_KEY_DOWN, onkeydown);
2441     }
2442 
2443     /**
2444      * Returns the {@code onwebkitanimationstart} event handler.
2445      * @return the {@code onwebkitanimationstart} event handler
2446      */
2447     @JsxGetter({CHROME, EDGE})
2448     public Function getOnwebkitanimationstart() {
2449         return getEventHandler(Event.TYPE_WEBANIMATIONSTART);
2450     }
2451 
2452     /**
2453      * Sets the {@code onwebkitanimationstart} event handler.
2454      * @param onwebkitanimationstart the {@code onwebkitanimationstart} event handler
2455      */
2456     @JsxSetter({CHROME, EDGE})
2457     public void setOnwebkitanimationstart(final Object onwebkitanimationstart) {
2458         setHandlerForJavaScript(Event.TYPE_WEBANIMATIONSTART, onwebkitanimationstart);
2459     }
2460 
2461     /**
2462      * Returns the {@code onkeyup} event handler.
2463      * @return the {@code onkeyup} event handler
2464      */
2465     @JsxGetter
2466     public Function getOnkeyup() {
2467         return getEventHandler(Event.TYPE_KEY_UP);
2468     }
2469 
2470     /**
2471      * Sets the {@code onkeyup} event handler.
2472      * @param onkeyup the {@code onkeyup} event handler
2473      */
2474     @JsxSetter
2475     public void setOnkeyup(final Object onkeyup) {
2476         setHandlerForJavaScript(Event.TYPE_KEY_UP, onkeyup);
2477     }
2478 
2479     /**
2480      * Returns the {@code onreset} event handler.
2481      * @return the {@code onreset} event handler
2482      */
2483     @JsxGetter
2484     public Function getOnreset() {
2485         return getEventHandler(Event.TYPE_RESET);
2486     }
2487 
2488     /**
2489      * Sets the {@code onreset} event handler.
2490      * @param onreset the {@code onreset} event handler
2491      */
2492     @JsxSetter
2493     public void setOnreset(final Object onreset) {
2494         setHandlerForJavaScript(Event.TYPE_RESET, onreset);
2495     }
2496 
2497     /**
2498      * Returns the {@code onkeypress} event handler.
2499      * @return the {@code onkeypress} event handler
2500      */
2501     @JsxGetter
2502     public Function getOnkeypress() {
2503         return getEventHandler(Event.TYPE_KEY_PRESS);
2504     }
2505 
2506     /**
2507      * Sets the {@code onkeypress} event handler.
2508      * @param onkeypress the {@code onkeypress} event handler
2509      */
2510     @JsxSetter
2511     public void setOnkeypress(final Object onkeypress) {
2512         setHandlerForJavaScript(Event.TYPE_KEY_PRESS, onkeypress);
2513     }
2514 
2515     /**
2516      * Returns the {@code ondrag} event handler.
2517      * @return the {@code ondrag} event handler
2518      */
2519     @JsxGetter
2520     public Function getOndrag() {
2521         return getEventHandler(Event.TYPE_DRAG);
2522     }
2523 
2524     /**
2525      * Sets the {@code ondrag} event handler.
2526      * @param ondrag the {@code ondrag} event handler
2527      */
2528     @JsxSetter
2529     public void setOndrag(final Object ondrag) {
2530         setHandlerForJavaScript(Event.TYPE_DRAG, ondrag);
2531     }
2532 
2533     /**
2534      * Returns the {@code onseeked} event handler.
2535      * @return the {@code onseeked} event handler
2536      */
2537     @JsxGetter
2538     public Function getOnseeked() {
2539         return getEventHandler(Event.TYPE_SEEKED);
2540     }
2541 
2542     /**
2543      * Sets the {@code onseeked} event handler.
2544      * @param onseeked the {@code onseeked} event handler
2545      */
2546     @JsxSetter
2547     public void setOnseeked(final Object onseeked) {
2548         setHandlerForJavaScript(Event.TYPE_SEEKED, onseeked);
2549     }
2550 
2551     /**
2552      * Returns the {@code onoffline} event handler.
2553      * @return the {@code onoffline} event handler
2554      */
2555     @JsxGetter
2556     public Function getOnoffline() {
2557         return getEventHandler(Event.TYPE_OFFLINE);
2558     }
2559 
2560     /**
2561      * Sets the {@code onoffline} event handler.
2562      * @param onoffline the {@code onoffline} event handler
2563      */
2564     @JsxSetter
2565     public void setOnoffline(final Object onoffline) {
2566         setHandlerForJavaScript(Event.TYPE_OFFLINE, onoffline);
2567     }
2568 
2569     /**
2570      * Returns the {@code ondeviceorientation} event handler.
2571      * @return the {@code ondeviceorientation} event handler
2572      */
2573     @JsxGetter
2574     public Function getOndeviceorientation() {
2575         return getEventHandler(Event.TYPE_DEVICEORIENTATION);
2576     }
2577 
2578     /**
2579      * Sets the {@code ondeviceorientation} event handler.
2580      * @param ondeviceorientation the {@code ondeviceorientation} event handler
2581      */
2582     @JsxSetter
2583     public void setOndeviceorientation(final Object ondeviceorientation) {
2584         setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATION, ondeviceorientation);
2585     }
2586 
2587     /**
2588      * Returns the {@code ontoggle} event handler.
2589      * @return the {@code ontoggle} event handler
2590      */
2591     @JsxGetter({CHROME, EDGE})
2592     public Function getOntoggle() {
2593         return getEventHandler(Event.TYPE_TOGGLE);
2594     }
2595 
2596     /**
2597      * Sets the {@code ontoggle} event handler.
2598      * @param ontoggle the {@code ontoggle} event handler
2599      */
2600     @JsxSetter({CHROME, EDGE})
2601     public void setOntoggle(final Object ontoggle) {
2602         setHandlerForJavaScript(Event.TYPE_TOGGLE, ontoggle);
2603     }
2604 
2605     /**
2606      * Returns the {@code onplay} event handler.
2607      * @return the {@code onplay} event handler
2608      */
2609     @JsxGetter
2610     public Function getOnplay() {
2611         return getEventHandler(Event.TYPE_PLAY);
2612     }
2613 
2614     /**
2615      * Sets the {@code onplay} event handler.
2616      * @param onplay the {@code onplay} event handler
2617      */
2618     @JsxSetter
2619     public void setOnplay(final Object onplay) {
2620         setHandlerForJavaScript(Event.TYPE_PLAY, onplay);
2621     }
2622 
2623     /**
2624      * Returns the {@code oncontextmenu} event handler.
2625      * @return the {@code oncontextmenu} event handler
2626      */
2627     @JsxGetter
2628     public Function getOncontextmenu() {
2629         return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
2630     }
2631 
2632     /**
2633      * Sets the {@code oncontextmenu} event handler.
2634      * @param oncontextmenu the {@code oncontextmenu} event handler
2635      */
2636     @JsxSetter
2637     public void setOncontextmenu(final Object oncontextmenu) {
2638         setHandlerForJavaScript(MouseEvent.TYPE_CONTEXT_MENU, oncontextmenu);
2639     }
2640 
2641     /**
2642      * Returns the {@code onmousemove} event handler.
2643      * @return the {@code onmousemove} event handler
2644      */
2645     @JsxGetter
2646     public Function getOnmousemove() {
2647         return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
2648     }
2649 
2650     /**
2651      * Sets the {@code onmousemove} event handler.
2652      * @param onmousemove the {@code onmousemove} event handler
2653      */
2654     @JsxSetter
2655     public void setOnmousemove(final Object onmousemove) {
2656         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_MOVE, onmousemove);
2657     }
2658 
2659     /**
2660      * Returns the {@code onpointermove} event handler.
2661      * @return the {@code onpointermove} event handler
2662      */
2663     @JsxGetter({CHROME, EDGE})
2664     public Function getOnpointermove() {
2665         return getEventHandler(Event.TYPE_POINTERMOVE);
2666     }
2667 
2668     /**
2669      * Sets the {@code onpointermove} event handler.
2670      * @param onpointermove the {@code onpointermove} event handler
2671      */
2672     @JsxSetter({CHROME, EDGE})
2673     public void setOnpointermove(final Object onpointermove) {
2674         setHandlerForJavaScript(Event.TYPE_POINTERMOVE, onpointermove);
2675     }
2676 
2677     /**
2678      * Returns the {@code onmouseover} event handler.
2679      * @return the {@code onmouseover} event handler
2680      */
2681     @JsxGetter
2682     public Function getOnmouseover() {
2683         return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
2684     }
2685 
2686     /**
2687      * Sets the {@code onmouseover} event handler.
2688      * @param onmouseover the {@code onmouseover} event handler
2689      */
2690     @JsxSetter
2691     public void setOnmouseover(final Object onmouseover) {
2692         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OVER, onmouseover);
2693     }
2694 
2695     /**
2696      * Returns the {@code onlostpointercapture} event handler.
2697      * @return the {@code onlostpointercapture} event handler
2698      */
2699     @JsxGetter({CHROME, EDGE})
2700     public Function getOnlostpointercapture() {
2701         return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2702     }
2703 
2704     /**
2705      * Sets the {@code onlostpointercapture} event handler.
2706      * @param onlostpointercapture the {@code onlostpointercapture} event handler
2707      */
2708     @JsxSetter({CHROME, EDGE})
2709     public void setOnlostpointercapture(final Object onlostpointercapture) {
2710         setHandlerForJavaScript(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2711     }
2712 
2713     /**
2714      * Returns the {@code onpointerover} event handler.
2715      * @return the {@code onpointerover} event handler
2716      */
2717     @JsxGetter({CHROME, EDGE})
2718     public Function getOnpointerover() {
2719         return getEventHandler(Event.TYPE_POINTEROVER);
2720     }
2721 
2722     /**
2723      * Sets the {@code onpointerover} event handler.
2724      * @param onpointerover the {@code onpointerover} event handler
2725      */
2726     @JsxSetter({CHROME, EDGE})
2727     public void setOnpointerover(final Object onpointerover) {
2728         setHandlerForJavaScript(Event.TYPE_POINTEROVER, onpointerover);
2729     }
2730 
2731     /**
2732      * Returns the {@code onclose} event handler.
2733      * @return the {@code onclose} event handler
2734      */
2735     @JsxGetter({CHROME, EDGE})
2736     public Function getOnclose() {
2737         return getEventHandler(Event.TYPE_CLOSE);
2738     }
2739 
2740     /**
2741      * Sets the {@code onclose} event handler.
2742      * @param onclose the {@code onclose} event handler
2743      */
2744     @JsxSetter({CHROME, EDGE})
2745     public void setOnclose(final Object onclose) {
2746         setHandlerForJavaScript(Event.TYPE_CLOSE, onclose);
2747     }
2748 
2749     /**
2750      * Returns the {@code onanimationend} event handler.
2751      * @return the {@code onanimationend} event handler
2752      */
2753     @JsxGetter
2754     public Function getOnanimationend() {
2755         return getEventHandler(Event.TYPE_ANIMATIONEND);
2756     }
2757 
2758     /**
2759      * Sets the {@code onanimationend} event handler.
2760      * @param onanimationend the {@code onanimationend} event handler
2761      */
2762     @JsxSetter
2763     public void setOnanimationend(final Object onanimationend) {
2764         setHandlerForJavaScript(Event.TYPE_ANIMATIONEND, onanimationend);
2765     }
2766 
2767     /**
2768      * Returns the {@code ondragenter} event handler.
2769      * @return the {@code ondragenter} event handler
2770      */
2771     @JsxGetter
2772     public Function getOndragenter() {
2773         return getEventHandler(Event.TYPE_DRAGENTER);
2774     }
2775 
2776     /**
2777      * Sets the {@code ondragenter} event handler.
2778      * @param ondragenter the {@code ondragenter} event handler
2779      */
2780     @JsxSetter
2781     public void setOndragenter(final Object ondragenter) {
2782         setHandlerForJavaScript(Event.TYPE_DRAGENTER, ondragenter);
2783     }
2784 
2785     /**
2786      * Returns the {@code onafterprint} event handler.
2787      * @return the {@code onafterprint} event handler
2788      */
2789     @JsxGetter({FF, FF_ESR})
2790     public Function getOnafterprint() {
2791         return getEventHandler(Event.TYPE_AFTERPRINT);
2792     }
2793 
2794     /**
2795      * Sets the {@code onafterprint} event handler.
2796      * @param onafterprint the {@code onafterprint} event handler
2797      */
2798     @JsxSetter({FF, FF_ESR})
2799     public void setOnafterprint(final Object onafterprint) {
2800         setHandlerForJavaScript(Event.TYPE_AFTERPRINT, onafterprint);
2801     }
2802 
2803     /**
2804      * Returns the {@code onmozfullscreenerror} event handler.
2805      * @return the {@code onmozfullscreenerror} event handler
2806      */
2807     @JsxGetter({FF, FF_ESR})
2808     public Function getOnmozfullscreenerror() {
2809         return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
2810     }
2811 
2812     /**
2813      * Sets the {@code onmozfullscreenerror} event handler.
2814      * @param onmozfullscreenerror the {@code onmozfullscreenerror} event handler
2815      */
2816     @JsxSetter({FF, FF_ESR})
2817     public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
2818         setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
2819     }
2820 
2821     /**
2822      * Returns the {@code onmouseleave} event handler.
2823      * @return the {@code onmouseleave} event handler
2824      */
2825     @JsxGetter
2826     public Function getOnmouseleave() {
2827         return getEventHandler(Event.TYPE_MOUSELEAVE);
2828     }
2829 
2830     /**
2831      * Sets the {@code onmouseleave} event handler.
2832      * @param onmouseleave the {@code onmouseleave} event handler
2833      */
2834     @JsxSetter
2835     public void setOnmouseleave(final Object onmouseleave) {
2836         setHandlerForJavaScript(Event.TYPE_MOUSELEAVE, onmouseleave);
2837     }
2838 
2839     /**
2840      * Returns the {@code onmousewheel} event handler.
2841      * @return the {@code onmousewheel} event handler
2842      */
2843     @JsxGetter({CHROME, EDGE})
2844     public Function getOnmousewheel() {
2845         return getEventHandler(Event.TYPE_MOUSEWHEEL);
2846     }
2847 
2848     /**
2849      * Sets the {@code onmousewheel} event handler.
2850      * @param onmousewheel the {@code onmousewheel} event handler
2851      */
2852     @JsxSetter({CHROME, EDGE})
2853     public void setOnmousewheel(final Object onmousewheel) {
2854         setHandlerForJavaScript(Event.TYPE_MOUSEWHEEL, onmousewheel);
2855     }
2856 
2857     /**
2858      * Returns the {@code onseeking} event handler.
2859      * @return the {@code onseeking} event handler
2860      */
2861     @JsxGetter
2862     public Function getOnseeking() {
2863         return getEventHandler(Event.TYPE_SEEKING);
2864     }
2865 
2866     /**
2867      * Sets the {@code onseeking} event handler.
2868      * @param onseeking the {@code onseeking} event handler
2869      */
2870     @JsxSetter
2871     public void setOnseeking(final Object onseeking) {
2872         setHandlerForJavaScript(Event.TYPE_SEEKING, onseeking);
2873     }
2874 
2875     /**
2876      * Returns the {@code oncuechange} event handler.
2877      * @return the {@code oncuechange} event handler
2878      */
2879     @JsxGetter({CHROME, EDGE})
2880     public Function getOncuechange() {
2881         return getEventHandler(Event.TYPE_CUECHANGE);
2882     }
2883 
2884     /**
2885      * Sets the {@code oncuechange} event handler.
2886      * @param oncuechange the {@code oncuechange} event handler
2887      */
2888     @JsxSetter({CHROME, EDGE})
2889     public void setOncuechange(final Object oncuechange) {
2890         setHandlerForJavaScript(Event.TYPE_CUECHANGE, oncuechange);
2891     }
2892 
2893     /**
2894      * Returns the {@code onpageshow} event handler.
2895      * @return the {@code onpageshow} event handler
2896      */
2897     @JsxGetter
2898     public Function getOnpageshow() {
2899         return getEventHandler(Event.TYPE_PAGESHOW);
2900     }
2901 
2902     /**
2903      * Sets the {@code onpageshow} event handler.
2904      * @param onpageshow the {@code onpageshow} event handler
2905      */
2906     @JsxSetter
2907     public void setOnpageshow(final Object onpageshow) {
2908         setHandlerForJavaScript(Event.TYPE_PAGESHOW, onpageshow);
2909     }
2910 
2911     /**
2912      * Returns the {@code onmozfullscreenchange} event handler.
2913      * @return the {@code onmozfullscreenchange} event handler
2914      */
2915     @JsxGetter({FF, FF_ESR})
2916     public Function getOnmozfullscreenchange() {
2917         return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
2918     }
2919 
2920     /**
2921      * Sets the {@code onmozfullscreenchange} event handler.
2922      * @param onmozfullscreenchange the {@code onmozfullscreenchange} event handler
2923      */
2924     @JsxSetter({FF, FF_ESR})
2925     public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
2926         setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
2927     }
2928 
2929     /**
2930      * Returns the {@code ondurationchange} event handler.
2931      * @return the {@code ondurationchange} event handler
2932      */
2933     @JsxGetter
2934     public Function getOndurationchange() {
2935         return getEventHandler(Event.TYPE_DURATIONCHANGE);
2936     }
2937 
2938     /**
2939      * Sets the {@code ondurationchange} event handler.
2940      * @param ondurationchange the {@code ondurationchange} event handler
2941      */
2942     @JsxSetter
2943     public void setOndurationchange(final Object ondurationchange) {
2944         setHandlerForJavaScript(Event.TYPE_DURATIONCHANGE, ondurationchange);
2945     }
2946 
2947     /**
2948      * Returns the {@code onplaying} event handler.
2949      * @return the {@code onplaying} event handler
2950      */
2951     @JsxGetter
2952     public Function getOnplaying() {
2953         return getEventHandler(Event.TYPE_PLAYING);
2954     }
2955 
2956     /**
2957      * Sets the {@code onplaying} event handler.
2958      * @param onplaying the {@code onplaying} event handler
2959      */
2960     @JsxSetter
2961     public void setOnplaying(final Object onplaying) {
2962         setHandlerForJavaScript(Event.TYPE_PLAYING, onplaying);
2963     }
2964 
2965     /**
2966      * Returns the {@code onended} event handler.
2967      * @return the {@code onended} event handler
2968      */
2969     @JsxGetter
2970     public Function getOnended() {
2971         return getEventHandler(Event.TYPE_ENDED);
2972     }
2973 
2974     /**
2975      * Sets the {@code onended} event handler.
2976      * @param onended the {@code onended} event handler
2977      */
2978     @JsxSetter
2979     public void setOnended(final Object onended) {
2980         setHandlerForJavaScript(Event.TYPE_ENDED, onended);
2981     }
2982 
2983     /**
2984      * Returns the {@code onloadeddata} event handler.
2985      * @return the {@code onloadeddata} event handler
2986      */
2987     @JsxGetter
2988     public Function getOnloadeddata() {
2989         return getEventHandler(Event.TYPE_LOADEDDATA);
2990     }
2991 
2992     /**
2993      * Sets the {@code onloadeddata} event handler.
2994      * @param onloadeddata the {@code onloadeddata} event handler
2995      */
2996     @JsxSetter
2997     public void setOnloadeddata(final Object onloadeddata) {
2998         setHandlerForJavaScript(Event.TYPE_LOADEDDATA, onloadeddata);
2999     }
3000 
3001     /**
3002      * Returns the {@code onunhandledrejection} event handler.
3003      * @return the {@code onunhandledrejection} event handler
3004      */
3005     @JsxGetter({CHROME, EDGE})
3006     public Function getOnunhandledrejection() {
3007         return getEventHandler(Event.TYPE_UNHANDLEDREJECTION);
3008     }
3009 
3010     /**
3011      * Sets the {@code onunhandledrejection} event handler.
3012      * @param onunhandledrejection the {@code onunhandledrejection} event handler
3013      */
3014     @JsxSetter({CHROME, EDGE})
3015     public void setOnunhandledrejection(final Object onunhandledrejection) {
3016         setHandlerForJavaScript(Event.TYPE_UNHANDLEDREJECTION, onunhandledrejection);
3017     }
3018 
3019     /**
3020      * Returns the {@code onmouseout} event handler.
3021      * @return the {@code onmouseout} event handler
3022      */
3023     @JsxGetter
3024     public Function getOnmouseout() {
3025         return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
3026     }
3027 
3028     /**
3029      * Sets the {@code onmouseout} event handler.
3030      * @param onmouseout the {@code onmouseout} event handler
3031      */
3032     @JsxSetter
3033     public void setOnmouseout(final Object onmouseout) {
3034         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OUT, onmouseout);
3035     }
3036 
3037     /**
3038      * Returns the {@code onsuspend} event handler.
3039      * @return the {@code onsuspend} event handler
3040      */
3041     @JsxGetter
3042     public Function getOnsuspend() {
3043         return getEventHandler(Event.TYPE_SUSPEND);
3044     }
3045 
3046     /**
3047      * Sets the {@code onsuspend} event handler.
3048      * @param onsuspend the {@code onsuspend} event handler
3049      */
3050     @JsxSetter
3051     public void setOnsuspend(final Object onsuspend) {
3052         setHandlerForJavaScript(Event.TYPE_SUSPEND, onsuspend);
3053     }
3054 
3055     /**
3056      * Returns the {@code onwaiting} event handler.
3057      * @return the {@code onwaiting} event handler
3058      */
3059     @JsxGetter
3060     public Function getOnwaiting() {
3061         return getEventHandler(Event.TYPE_WAITING);
3062     }
3063 
3064     /**
3065      * Sets the {@code onwaiting} event handler.
3066      * @param onwaiting the {@code onwaiting} event handler
3067      */
3068     @JsxSetter
3069     public void setOnwaiting(final Object onwaiting) {
3070         setHandlerForJavaScript(Event.TYPE_WAITING, onwaiting);
3071     }
3072 
3073     /**
3074      * Returns the {@code oncanplay} event handler.
3075      * @return the {@code oncanplay} event handler
3076      */
3077     @JsxGetter
3078     public Function getOncanplay() {
3079         return getEventHandler(Event.TYPE_CANPLAY);
3080     }
3081 
3082     /**
3083      * Sets the {@code oncanplay} event handler.
3084      * @param oncanplay the {@code oncanplay} event handler
3085      */
3086     @JsxSetter
3087     public void setOncanplay(final Object oncanplay) {
3088         setHandlerForJavaScript(Event.TYPE_CANPLAY, oncanplay);
3089     }
3090 
3091     /**
3092      * Returns the {@code onmousedown} event handler.
3093      * @return the {@code onmousedown} event handler
3094      */
3095     @JsxGetter
3096     public Function getOnmousedown() {
3097         return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
3098     }
3099 
3100     /**
3101      * Sets the {@code onmousedown} event handler.
3102      * @param onmousedown the {@code onmousedown} event handler
3103      */
3104     @JsxSetter
3105     public void setOnmousedown(final Object onmousedown) {
3106         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_DOWN, onmousedown);
3107     }
3108 
3109     /**
3110      * Returns the {@code onlanguagechange} event handler.
3111      * @return the {@code onlanguagechange} event handler
3112      */
3113     @JsxGetter
3114     public Function getOnlanguagechange() {
3115         return getEventHandler(Event.TYPE_LANGUAGECHANGE);
3116     }
3117 
3118     /**
3119      * Sets the {@code onlanguagechange} event handler.
3120      * @param onlanguagechange the {@code onlanguagechange} event handler
3121      */
3122     @JsxSetter
3123     public void setOnlanguagechange(final Object onlanguagechange) {
3124         setHandlerForJavaScript(Event.TYPE_LANGUAGECHANGE, onlanguagechange);
3125     }
3126 
3127     /**
3128      * Returns the {@code onemptied} event handler.
3129      * @return the {@code onemptied} event handler
3130      */
3131     @JsxGetter
3132     public Function getOnemptied() {
3133         return getEventHandler(Event.TYPE_EMPTIED);
3134     }
3135 
3136     /**
3137      * Sets the {@code onemptied} event handler.
3138      * @param onemptied the {@code onemptied} event handler
3139      */
3140     @JsxSetter
3141     public void setOnemptied(final Object onemptied) {
3142         setHandlerForJavaScript(Event.TYPE_EMPTIED, onemptied);
3143     }
3144 
3145     /**
3146      * Returns the {@code onrejectionhandled} event handler.
3147      * @return the {@code onrejectionhandled} event handler
3148      */
3149     @JsxGetter({CHROME, EDGE})
3150     public Function getOnrejectionhandled() {
3151         return getEventHandler(Event.TYPE_REJECTIONHANDLED);
3152     }
3153 
3154     /**
3155      * Sets the {@code onrejectionhandled} event handler.
3156      * @param onrejectionhandled the {@code onrejectionhandled} event handler
3157      */
3158     @JsxSetter({CHROME, EDGE})
3159     public void setOnrejectionhandled(final Object onrejectionhandled) {
3160         setHandlerForJavaScript(Event.TYPE_REJECTIONHANDLED, onrejectionhandled);
3161     }
3162 
3163     /**
3164      * Returns the {@code onpointercancel} event handler.
3165      * @return the {@code onpointercancel} event handler
3166      */
3167     @JsxGetter({CHROME, EDGE})
3168     public Function getOnpointercancel() {
3169         return getEventHandler(Event.TYPE_POINTERCANCEL);
3170     }
3171 
3172     /**
3173      * Sets the {@code onpointercancel} event handler.
3174      * @param onpointercancel the {@code onpointercancel} event handler
3175      */
3176     @JsxSetter({CHROME, EDGE})
3177     public void setOnpointercancel(final Object onpointercancel) {
3178         setHandlerForJavaScript(Event.TYPE_POINTERCANCEL, onpointercancel);
3179     }
3180 
3181     /**
3182      * Returns the {@code onresize} event handler.
3183      * @return the {@code onresize} event handler
3184      */
3185     @JsxGetter
3186     public Function getOnresize() {
3187         return getEventHandler(Event.TYPE_RESIZE);
3188     }
3189 
3190     /**
3191      * Sets the {@code onresize} event handler.
3192      * @param onresize the {@code onresize} event handler
3193      */
3194     @JsxSetter
3195     public void setOnresize(final Object onresize) {
3196         setHandlerForJavaScript(Event.TYPE_RESIZE, onresize);
3197     }
3198 
3199     /**
3200      * Returns the {@code onpause} event handler.
3201      * @return the {@code onpause} event handler
3202      */
3203     @JsxGetter
3204     public Function getOnpause() {
3205         return getEventHandler(Event.TYPE_PAUSE);
3206     }
3207 
3208     /**
3209      * Sets the {@code onpause} event handler.
3210      * @param onpause the {@code onpause} event handler
3211      */
3212     @JsxSetter
3213     public void setOnpause(final Object onpause) {
3214         setHandlerForJavaScript(Event.TYPE_PAUSE, onpause);
3215     }
3216 
3217     /**
3218      * Returns the {@code onloadstart} event handler.
3219      * @return the {@code onloadstart} event handler
3220      */
3221     @JsxGetter
3222     public Function getOnloadstart() {
3223         return getEventHandler(Event.TYPE_LOAD_START);
3224     }
3225 
3226     /**
3227      * Sets the {@code onloadstart} event handler.
3228      * @param onloadstart the {@code onloadstart} event handler
3229      */
3230     @JsxSetter
3231     public void setOnloadstart(final Object onloadstart) {
3232         setHandlerForJavaScript(Event.TYPE_LOAD_START, onloadstart);
3233     }
3234 
3235     /**
3236      * Returns the {@code onprogress} event handler.
3237      * @return the {@code onprogress} event handler
3238      */
3239     @JsxGetter
3240     public Function getOnprogress() {
3241         return getEventHandler(Event.TYPE_PROGRESS);
3242     }
3243 
3244     /**
3245      * Sets the {@code onprogress} event handler.
3246      * @param onprogress the {@code onprogress} event handler
3247      */
3248     @JsxSetter
3249     public void setOnprogress(final Object onprogress) {
3250         setHandlerForJavaScript(Event.TYPE_PROGRESS, onprogress);
3251     }
3252 
3253     /**
3254      * Returns the {@code onpointerup} event handler.
3255      * @return the {@code onpointerup} event handler
3256      */
3257     @JsxGetter({CHROME, EDGE})
3258     public Function getOnpointerup() {
3259         return getEventHandler(Event.TYPE_POINTERUP);
3260     }
3261 
3262     /**
3263      * Sets the {@code onpointerup} event handler.
3264      * @param onpointerup the {@code onpointerup} event handler
3265      */
3266     @JsxSetter({CHROME, EDGE})
3267     public void setOnpointerup(final Object onpointerup) {
3268         setHandlerForJavaScript(Event.TYPE_POINTERUP, onpointerup);
3269     }
3270 
3271     /**
3272      * Returns the {@code onwheel} event handler.
3273      * @return the {@code onwheel} event handler
3274      */
3275     @JsxGetter
3276     public Function getOnwheel() {
3277         return getEventHandler(Event.TYPE_WHEEL);
3278     }
3279 
3280     /**
3281      * Sets the {@code onwheel} event handler.
3282      * @param onwheel the {@code onwheel} event handler
3283      */
3284     @JsxSetter
3285     public void setOnwheel(final Object onwheel) {
3286         setHandlerForJavaScript(Event.TYPE_WHEEL, onwheel);
3287     }
3288 
3289     /**
3290      * Returns the {@code onpointerleave} event handler.
3291      * @return the {@code onpointerleave} event handler
3292      */
3293     @JsxGetter({CHROME, EDGE})
3294     public Function getOnpointerleave() {
3295         return getEventHandler(Event.TYPE_POINTERLEAVE);
3296     }
3297 
3298     /**
3299      * Sets the {@code onpointerleave} event handler.
3300      * @param onpointerleave the {@code onpointerleave} event handler
3301      */
3302     @JsxSetter({CHROME, EDGE})
3303     public void setOnpointerleave(final Object onpointerleave) {
3304         setHandlerForJavaScript(Event.TYPE_POINTERLEAVE, onpointerleave);
3305     }
3306 
3307     /**
3308      * Returns the {@code onbeforeprint} event handler.
3309      * @return the {@code onbeforeprint} event handler
3310      */
3311     @JsxGetter({FF, FF_ESR})
3312     public Function getOnbeforeprint() {
3313         return getEventHandler(Event.TYPE_BEFOREPRINT);
3314     }
3315 
3316     /**
3317      * Sets the {@code onbeforeprint} event handler.
3318      * @param onbeforeprint the {@code onbeforeprint} event handler
3319      */
3320     @JsxSetter({FF, FF_ESR})
3321     public void setOnbeforeprint(final Object onbeforeprint) {
3322         setHandlerForJavaScript(Event.TYPE_BEFOREPRINT, onbeforeprint);
3323     }
3324 
3325     /**
3326      * Returns the {@code onstorage} event handler.
3327      * @return the {@code onstorage} event handler
3328      */
3329     @JsxGetter
3330     public Function getOnstorage() {
3331         return getEventHandler(Event.TYPE_STORAGE);
3332     }
3333 
3334     /**
3335      * Sets the {@code onstorage} event handler.
3336      * @param onstorage the {@code onstorage} event handler
3337      */
3338     @JsxSetter
3339     public void setOnstorage(final Object onstorage) {
3340         setHandlerForJavaScript(Event.TYPE_STORAGE, onstorage);
3341     }
3342 
3343     /**
3344      * Returns the {@code onanimationstart} event handler.
3345      * @return the {@code onanimationstart} event handler
3346      */
3347     @JsxGetter
3348     public Function getOnanimationstart() {
3349         return getEventHandler(Event.TYPE_ANIMATIONSTART);
3350     }
3351 
3352     /**
3353      * Sets the {@code onanimationstart} event handler.
3354      * @param onanimationstart the {@code onanimationstart} event handler
3355      */
3356     @JsxSetter
3357     public void setOnanimationstart(final Object onanimationstart) {
3358         setHandlerForJavaScript(Event.TYPE_ANIMATIONSTART, onanimationstart);
3359     }
3360 
3361     /**
3362      * Returns the {@code ontimeupdate} event handler.
3363      * @return the {@code ontimeupdate} event handler
3364      */
3365     @JsxGetter
3366     public Function getOntimeupdate() {
3367         return getEventHandler(Event.TYPE_TIMEUPDATE);
3368     }
3369 
3370     /**
3371      * Sets the {@code ontimeupdate} event handler.
3372      * @param ontimeupdate the {@code ontimeupdate} event handler
3373      */
3374     @JsxSetter
3375     public void setOntimeupdate(final Object ontimeupdate) {
3376         setHandlerForJavaScript(Event.TYPE_TIMEUPDATE, ontimeupdate);
3377     }
3378 
3379     /**
3380      * Returns the {@code onpagehide} event handler.
3381      * @return the {@code onpagehide} event handler
3382      */
3383     @JsxGetter
3384     public Function getOnpagehide() {
3385         return getEventHandler(Event.TYPE_PAGEHIDE);
3386     }
3387 
3388     /**
3389      * Sets the {@code onpagehide} event handler.
3390      * @param onpagehide the {@code onpagehide} event handler
3391      */
3392     @JsxSetter
3393     public void setOnpagehide(final Object onpagehide) {
3394         setHandlerForJavaScript(Event.TYPE_PAGEHIDE, onpagehide);
3395     }
3396 
3397     /**
3398      * Returns the {@code onwebkitanimationiteration} event handler.
3399      * @return the {@code onwebkitanimationiteration} event handler
3400      */
3401     @JsxGetter({CHROME, EDGE})
3402     public Function getOnwebkitanimationiteration() {
3403         return getEventHandler(Event.TYPE_WEBKITANIMATIONITERATION);
3404     }
3405 
3406     /**
3407      * Sets the {@code onwebkitanimationiteration} event handler.
3408      * @param onwebkitanimationiteration the {@code onwebkitanimationiteration} event handler
3409      */
3410     @JsxSetter({CHROME, EDGE})
3411     public void setOnwebkitanimationiteration(final Object onwebkitanimationiteration) {
3412         setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONITERATION, onwebkitanimationiteration);
3413     }
3414 
3415     /**
3416      * Returns the {@code onabort} event handler.
3417      * @return the {@code onabort} event handler
3418      */
3419     @JsxGetter
3420     public Function getOnabort() {
3421         return getEventHandler(Event.TYPE_ABORT);
3422     }
3423 
3424     /**
3425      * Sets the {@code onabort} event handler.
3426      * @param onabort the {@code onabort} event handler
3427      */
3428     @JsxSetter
3429     public void setOnabort(final Object onabort) {
3430         setHandlerForJavaScript(Event.TYPE_ABORT, onabort);
3431     }
3432 
3433     /**
3434      * Returns the {@code onloadedmetadata} event handler.
3435      * @return the {@code onloadedmetadata} event handler
3436      */
3437     @JsxGetter
3438     public Function getOnloadedmetadata() {
3439         return getEventHandler(Event.TYPE_LOADEDMETADATA);
3440     }
3441 
3442     /**
3443      * Sets the {@code onloadedmetadata} event handler.
3444      * @param onloadedmetadata the {@code onloadedmetadata} event handler
3445      */
3446     @JsxSetter
3447     public void setOnloadedmetadata(final Object onloadedmetadata) {
3448         setHandlerForJavaScript(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
3449     }
3450 
3451     /**
3452      * Returns the {@code onmouseup} event handler.
3453      * @return the {@code onmouseup} event handler
3454      */
3455     @JsxGetter
3456     public Function getOnmouseup() {
3457         return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
3458     }
3459 
3460     /**
3461      * Sets the {@code onmouseup} event handler.
3462      * @param onmouseup the {@code onmouseup} event handler
3463      */
3464     @JsxSetter
3465     public void setOnmouseup(final Object onmouseup) {
3466         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_UP, onmouseup);
3467     }
3468 
3469     /**
3470      * Returns the {@code ondragover} event handler.
3471      * @return the {@code ondragover} event handler
3472      */
3473     @JsxGetter
3474     public Function getOndragover() {
3475         return getEventHandler(Event.TYPE_DRAGOVER);
3476     }
3477 
3478     /**
3479      * Sets the {@code ondragover} event handler.
3480      * @param ondragover the {@code ondragover} event handler
3481      */
3482     @JsxSetter
3483     public void setOndragover(final Object ondragover) {
3484         setHandlerForJavaScript(Event.TYPE_DRAGOVER, ondragover);
3485     }
3486 
3487     /**
3488      * Returns the {@code ononline} event handler.
3489      * @return the {@code ononline} event handler
3490      */
3491     @JsxGetter
3492     public Function getOnonline() {
3493         return getEventHandler(Event.TYPE_ONLINE);
3494     }
3495 
3496     /**
3497      * Sets the {@code ononline} event handler.
3498      * @param ononline the {@code ononline} event handler
3499      */
3500     @JsxSetter
3501     public void setOnonline(final Object ononline) {
3502         setHandlerForJavaScript(Event.TYPE_ONLINE, ononline);
3503     }
3504 
3505     /**
3506      * Returns the {@code onsearch} event handler.
3507      * @return the {@code onsearch} event handler
3508      */
3509     @JsxGetter({CHROME, EDGE})
3510     public Function getOnsearch() {
3511         return getEventHandler(Event.TYPE_SEARCH);
3512     }
3513 
3514     /**
3515      * Sets the {@code onsearch} event handler.
3516      * @param onsearch the {@code onsearch} event handler
3517      */
3518     @JsxSetter({CHROME, EDGE})
3519     public void setOnsearch(final Object onsearch) {
3520         setHandlerForJavaScript(Event.TYPE_SEARCH, onsearch);
3521     }
3522 
3523     /**
3524      * Returns the {@code oninput} event handler.
3525      * @return the {@code oninput} event handler
3526      */
3527     @JsxGetter
3528     public Function getOninput() {
3529         return getEventHandler(Event.TYPE_INPUT);
3530     }
3531 
3532     /**
3533      * Sets the {@code oninput} event handler.
3534      * @param oninput the {@code oninput} event handler
3535      */
3536     @JsxSetter
3537     public void setOninput(final Object oninput) {
3538         setHandlerForJavaScript(Event.TYPE_INPUT, oninput);
3539     }
3540 
3541     /**
3542      * Returns the {@code onwebkittransitionend} event handler.
3543      * @return the {@code onwebkittransitionend} event handler
3544      */
3545     @JsxGetter({CHROME, EDGE})
3546     public Function getOnwebkittransitionend() {
3547         return getEventHandler(Event.TYPE_WEBKITTRANSITIONEND);
3548     }
3549 
3550     /**
3551      * Sets the {@code onwebkittransitionend} event handler.
3552      * @param onwebkittransitionend the {@code onwebkittransitionend} event handler
3553      */
3554     @JsxSetter({CHROME, EDGE})
3555     public void setOnwebkittransitionend(final Object onwebkittransitionend) {
3556         setHandlerForJavaScript(Event.TYPE_WEBKITTRANSITIONEND, onwebkittransitionend);
3557     }
3558 
3559     /**
3560      * Returns the {@code ondevicemotion} event handler.
3561      * @return the {@code ondevicemotion} event handler
3562      */
3563     @JsxGetter
3564     public Function getOndevicemotion() {
3565         return getEventHandler(Event.TYPE_DEVICEMOTION);
3566     }
3567 
3568     /**
3569      * Sets the {@code ondevicemotion} event handler.
3570      * @param ondevicemotion the {@code ondevicemotion} event handler
3571      */
3572     @JsxSetter
3573     public void setOndevicemotion(final Object ondevicemotion) {
3574         setHandlerForJavaScript(Event.TYPE_DEVICEMOTION, ondevicemotion);
3575     }
3576 
3577     /**
3578      * Returns the {@code onstalled} event handler.
3579      * @return the {@code onstalled} event handler
3580      */
3581     @JsxGetter
3582     public Function getOnstalled() {
3583         return getEventHandler(Event.TYPE_STALLED);
3584     }
3585 
3586     /**
3587      * Sets the {@code onstalled} event handler.
3588      * @param onstalled the {@code onstalled} event handler
3589      */
3590     @JsxSetter
3591     public void setOnstalled(final Object onstalled) {
3592         setHandlerForJavaScript(Event.TYPE_STALLED, onstalled);
3593     }
3594 
3595     /**
3596      * Returns the {@code onmouseenter} event handler.
3597      * @return the {@code onmouseenter} event handler
3598      */
3599     @JsxGetter
3600     public Function getOnmouseenter() {
3601         return getEventHandler(Event.TYPE_MOUDEENTER);
3602     }
3603 
3604     /**
3605      * Sets the {@code onmouseenter} event handler.
3606      * @param onmouseenter the {@code onmouseenter} event handler
3607      */
3608     @JsxSetter
3609     public void setOnmouseenter(final Object onmouseenter) {
3610         setHandlerForJavaScript(Event.TYPE_MOUDEENTER, onmouseenter);
3611     }
3612 
3613     /**
3614      * Returns the {@code ondragleave} event handler.
3615      * @return the {@code ondragleave} event handler
3616      */
3617     @JsxGetter
3618     public Function getOndragleave() {
3619         return getEventHandler(Event.TYPE_DRAGLEAVE);
3620     }
3621 
3622     /**
3623      * Sets the {@code ondragleave} event handler.
3624      * @param ondragleave the {@code ondragleave} event handler
3625      */
3626     @JsxSetter
3627     public void setOndragleave(final Object ondragleave) {
3628         setHandlerForJavaScript(Event.TYPE_DRAGLEAVE, ondragleave);
3629     }
3630 
3631     /**
3632      * Returns the {@code onpointerdown} event handler.
3633      * @return the {@code onpointerdown} event handler
3634      */
3635     @JsxGetter({CHROME, EDGE})
3636     public Function getOnpointerdown() {
3637         return getEventHandler(Event.TYPE_POINTERDOWN);
3638     }
3639 
3640     /**
3641      * Sets the {@code onpointerdown} event handler.
3642      * @param onpointerdown the {@code onpointerdown} event handler
3643      */
3644     @JsxSetter({CHROME, EDGE})
3645     public void setOnpointerdown(final Object onpointerdown) {
3646         setHandlerForJavaScript(Event.TYPE_POINTERDOWN, onpointerdown);
3647     }
3648 
3649     /**
3650      * Returns the {@code ondrop} event handler.
3651      * @return the {@code ondrop} event handler
3652      */
3653     @JsxGetter
3654     public Function getOndrop() {
3655         return getEventHandler(Event.TYPE_DROP);
3656     }
3657 
3658     /**
3659      * Sets the {@code ondrop} event handler.
3660      * @param ondrop the {@code ondrop} event handler
3661      */
3662     @JsxSetter
3663     public void setOndrop(final Object ondrop) {
3664         setHandlerForJavaScript(Event.TYPE_DROP, ondrop);
3665     }
3666 
3667     /**
3668      * Returns the {@code onunload} event handler.
3669      * @return the {@code onunload} event handler
3670      */
3671     @JsxGetter
3672     public Function getOnunload() {
3673         return getEventHandler(Event.TYPE_UNLOAD);
3674     }
3675 
3676     /**
3677      * Sets the {@code onunload} event handler.
3678      * @param onunload the {@code onunload} event handler
3679      */
3680     @JsxSetter
3681     public void setOnunload(final Object onunload) {
3682         setHandlerForJavaScript(Event.TYPE_UNLOAD, onunload);
3683     }
3684 
3685     /**
3686      * Returns the {@code onwebkitanimationend} event handler.
3687      * @return the {@code onwebkitanimationend} event handler
3688      */
3689     @JsxGetter({CHROME, EDGE})
3690     public Function getOnwebkitanimationend() {
3691         return getEventHandler(Event.TYPE_WEBKITANIMATIONEND);
3692     }
3693 
3694     /**
3695      * Sets the {@code onwebkitanimationend} event handler.
3696      * @param onwebkitanimationend the {@code onwebkitanimationend} event handler
3697      */
3698     @JsxSetter({CHROME, EDGE})
3699     public void setOnwebkitanimationend(final Object onwebkitanimationend) {
3700         setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONEND, onwebkitanimationend);
3701     }
3702 
3703     /**
3704      * Returns the {@code ondragstart} event handler.
3705      * @return the {@code ondragstart} event handler
3706      */
3707     @JsxGetter
3708     public Function getOndragstart() {
3709         return getEventHandler(Event.TYPE_DRAGSTART);
3710     }
3711 
3712     /**
3713      * Sets the {@code ondragstart} event handler.
3714      * @param ondragstart the {@code ondragstart} event handler
3715      */
3716     @JsxSetter
3717     public void setOndragstart(final Object ondragstart) {
3718         setHandlerForJavaScript(Event.TYPE_DRAGSTART, ondragstart);
3719     }
3720 
3721     /**
3722      * Returns the {@code ontransitionend} event handler.
3723      * @return the {@code ontransitionend} event handler
3724      */
3725     @JsxGetter({CHROME, EDGE})
3726     public Function getOntransitionend() {
3727         return getEventHandler(Event.TYPE_TRANSITIONEND);
3728     }
3729 
3730     /**
3731      * Sets the {@code ontransitionend} event handler.
3732      * @param ontransitionend the {@code ontransitionend} event handler
3733      */
3734     @JsxSetter({CHROME, EDGE})
3735     public void setOntransitionend(final Object ontransitionend) {
3736         setHandlerForJavaScript(Event.TYPE_TRANSITIONEND, ontransitionend);
3737     }
3738 
3739     /**
3740      * Returns the {@code ondeviceorientationabsolute} event handler.
3741      * @return the {@code ondeviceorientationabsolute} event handler
3742      */
3743     @JsxGetter({CHROME, EDGE})
3744     public Function getOndeviceorientationabsolute() {
3745         return getEventHandler(Event.TYPE_DEVICEORIENTATIONABSOLUTE);
3746     }
3747 
3748     /**
3749      * Sets the {@code ondeviceorientationabsolute} event handler.
3750      * @param ondeviceorientationabsolute the {@code ondeviceorientationabsolute} event handler
3751      */
3752     @JsxSetter({CHROME, EDGE})
3753     public void setOndeviceorientationabsolute(final Object ondeviceorientationabsolute) {
3754         setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATIONABSOLUTE, ondeviceorientationabsolute);
3755     }
3756 
3757     /**
3758      * Returns the {@code onvolumechange} event handler.
3759      * @return the {@code onvolumechange} event handler
3760      */
3761     @JsxGetter
3762     public Function getOnvolumechange() {
3763         return getEventHandler(Event.TYPE_VOLUMECHANGE);
3764     }
3765 
3766     /**
3767      * Sets the {@code onvolumechange} event handler.
3768      * @param onvolumechange the {@code onvolumechange} event handler
3769      */
3770     @JsxSetter
3771     public void setOnvolumechange(final Object onvolumechange) {
3772         setHandlerForJavaScript(Event.TYPE_VOLUMECHANGE, onvolumechange);
3773     }
3774 
3775     /**
3776      * Returns the {@code ongotpointercapture} event handler.
3777      * @return the {@code ongotpointercapture} event handler
3778      */
3779     @JsxGetter({CHROME, EDGE})
3780     public Function getOngotpointercapture() {
3781         return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
3782     }
3783 
3784     /**
3785      * Sets the {@code ongotpointercapture} event handler.
3786      * @param ongotpointercapture the {@code ongotpointercapture} event handler
3787      */
3788     @JsxSetter({CHROME, EDGE})
3789     public void setOngotpointercapture(final Object ongotpointercapture) {
3790         setHandlerForJavaScript(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
3791     }
3792 
3793     /**
3794      * Returns the {@code onpopstate} event handler.
3795      * @return the {@code onpopstate} event handler
3796      */
3797     @JsxGetter
3798     public Function getOnpopstate() {
3799         return getEventHandler(Event.TYPE_POPSTATE);
3800     }
3801 
3802     /**
3803      * Sets the {@code onpopstate} event handler.
3804      * @param onpopstate the {@code onpopstate} event handler
3805      */
3806     @JsxSetter
3807     public void setOnpopstate(final Object onpopstate) {
3808         setHandlerForJavaScript(Event.TYPE_POPSTATE, onpopstate);
3809     }
3810 
3811     /**
3812      * {@inheritDoc}
3813      * optimized version
3814      */
3815     @Override
3816     public BrowserVersion getBrowserVersion() {
3817         return getWebWindow().getWebClient().getBrowserVersion();
3818     }
3819 
3820     @Override
3821     public void put(final String name, final Scriptable start, final Object value) {
3822         // see https://dom.spec.whatwg.org/#window-current-event
3823         // because event is replaceable we need this hack here
3824         if ("event".equals(name)) {
3825             final Slot slot = querySlot(Context.getCurrentContext(), "event");
3826             if (slot instanceof AccessorSlot) {
3827                 delete("event");
3828             }
3829         }
3830         super.put(name, start, value);
3831     }
3832 
3833     /**
3834      * @return a boolean indicating whether the current context is secure (true) or not (false).
3835      */
3836     @JsxGetter
3837     public boolean getIsSecureContext() {
3838         final Page page = getWebWindow().getEnclosedPage();
3839         if (page != null) {
3840             final String protocol = page.getUrl().getProtocol();
3841             if ("https".equals(protocol)
3842                     || "wss".equals(protocol)
3843                     || "file".equals(protocol)) {
3844                 return true;
3845             }
3846 
3847             final String host = page.getUrl().getHost();
3848             if ("localhost".equals(host)
3849                     || "localhost.".equals(host)
3850                     || host.endsWith(".localhost")
3851                     || host.endsWith(".localhost.")) {
3852                 return true;
3853             }
3854         }
3855 
3856         return false;
3857     }
3858 }
3859 
3860 class HTMLCollectionFrames extends HTMLCollection {
3861     private static final Log LOG = LogFactory.getLog(HTMLCollectionFrames.class);
3862 
3863     HTMLCollectionFrames(final HtmlPage page) {
3864         super(page, false);
3865         this.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof BaseFrameElement);
3866     }
3867 
3868     @Override
3869     protected Scriptable getScriptableForElement(final Object obj) {
3870         final WebWindow window;
3871         if (obj instanceof BaseFrameElement) {
3872             window = ((BaseFrameElement) obj).getEnclosedWindow();
3873         }
3874         else {
3875             window = ((FrameWindow) obj).getFrameElement().getEnclosedWindow();
3876         }
3877 
3878         return window.getScriptableObject();
3879     }
3880 
3881     @Override
3882     protected Object getWithPreemption(final String name) {
3883         final List<DomNode> elements = getElements();
3884 
3885         for (final Object next : elements) {
3886             final BaseFrameElement frameElt = (BaseFrameElement) next;
3887             final WebWindow window = frameElt.getEnclosedWindow();
3888             if (name.equals(window.getName())) {
3889                 if (LOG.isDebugEnabled()) {
3890                     LOG.debug("Property \"" + name + "\" evaluated (by name) to " + window);
3891                 }
3892                 return getScriptableForElement(window);
3893             }
3894         }
3895 
3896         return NOT_FOUND;
3897     }
3898 }