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