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