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({CHROME, EDGE, FF})
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         final Context ctx = Context.getCurrentContext();
798         controllers_ = ctx.newObject(this);
799 
800         if (webWindow_ instanceof TopLevelWindow) {
801             final WebWindow opener = ((TopLevelWindow) webWindow_).getOpener();
802             if (opener != null) {
803                 opener_ = opener.getScriptableObject();
804             }
805         }
806     }
807 
808     /**
809      * Initialize the object.
810      * @param enclosedPage the page containing the JavaScript
811      */
812     public void initialize(final Page enclosedPage) {
813         if (enclosedPage != null && enclosedPage.isHtmlPage()) {
814             final HtmlPage htmlPage = (HtmlPage) enclosedPage;
815 
816             // Windows don't have corresponding DomNodes so set the domNode
817             // variable to be the page. If this isn't set then HtmlUnitScriptable.get()
818             // won't work properly
819             setDomNode(htmlPage);
820             clearEventListenersContainer();
821 
822             WebAssert.notNull("document_", document_);
823             document_.setDomNode(htmlPage);
824         }
825     }
826 
827     /**
828      * Initializes the object. Only called for Windows with no contents.
829      */
830     public void initialize() {
831         // Empty.
832     }
833 
834     /**
835      * Returns the value of the {@code top} property.
836      * @return the value of {@code top}
837      */
838     @JsxGetter
839     public Object getTop() {
840         final WebWindow top = getWebWindow().getTopWindow();
841         return top.getScriptableObject();
842     }
843 
844     /**
845      * Returns the value of the {@code opener} property.
846      * @return the value of the {@code opener}, or {@code null} for a top level window
847      */
848     @JsxGetter
849     public Object getOpener() {
850         Object opener = opener_;
851         if (opener instanceof Window) {
852             opener = ((Window) opener).windowProxy_;
853         }
854         return opener;
855     }
856 
857     /**
858      * Sets the {@code opener} property.
859      * @param newValue the new value
860      */
861     @JsxSetter
862     public void setOpener(final Object newValue) {
863         opener_ = newValue;
864     }
865 
866     /**
867      * Returns the (i)frame in which the window is contained.
868      * @return {@code null} for a top level window
869      */
870     @JsxGetter
871     public HtmlUnitScriptable getFrameElement() {
872         final WebWindow window = getWebWindow();
873         if (window instanceof FrameWindow) {
874             return ((FrameWindow) window).getFrameElement().getScriptableObject();
875         }
876         return null;
877     }
878 
879     /**
880      * Returns the number of frames contained by this window.
881      * @return the number of frames contained by this window
882      */
883     @JsxGetter
884     public Object getLength() {
885         return JavaScriptEngine.UNDEFINED;
886     }
887 
888     /**
889      * Gets the {@code length} property. Setting this shadows the
890      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
891      * @return the shadow value if set otherwise the number of frames
892      */
893     public Object jsGetLength() {
894         if (lengthShadow_ != null) {
895             return lengthShadow_;
896         }
897 
898         final HTMLCollection frames = getFrames();
899         if (frames != null) {
900             return frames.getLength();
901         }
902         return 0;
903     }
904 
905     /**
906      * Sets the {@code length} property. Setting this shadows the
907      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
908      * @param lengthShadow the value to overwrite the defined property value
909      */
910     public void jsSetLength(final Scriptable lengthShadow) {
911         lengthShadow_ = lengthShadow;
912     }
913 
914     /**
915      * Returns the {@code self} property.
916      * @return this
917      */
918     @JsxGetter
919     public Object getSelf() {
920         return JavaScriptEngine.UNDEFINED;
921     }
922 
923     /**
924      * Gets the {@code self} property. Setting this shadows the
925      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
926      * @return the shadow value if set otherwise the number of frames
927      */
928     public Object jsGetSelf() {
929         if (selfShadow_ != null) {
930             return selfShadow_;
931         }
932 
933         return this;
934     }
935 
936     /**
937      * Sets the {@code self} property. Setting this shadows the
938      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
939      * @param selfShadow the value to overwrite the defined property value
940      */
941     public void jsSetSelf(final Scriptable selfShadow) {
942         selfShadow_ = selfShadow;
943     }
944 
945     /**
946      * Returns the value of the {@code parent} property.
947      * @return the value of the {@code parent} property
948      */
949     @JsxGetter
950     public Object getParent() {
951         return JavaScriptEngine.UNDEFINED;
952     }
953 
954     /**
955      * Gets the {@code parent} property. Setting this shadows the
956      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
957      * @return the shadow value if set otherwise the number of frames
958      */
959     public Object jsGetParent() {
960         if (parentShadow_ != null) {
961             return parentShadow_;
962         }
963 
964         final WebWindow parent = getWebWindow().getParentWindow();
965         return parent.getScriptableObject();
966     }
967 
968     /**
969      * Sets the {@code parent} property. Setting this shadows the
970      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
971      * @param parentShadow the value to overwrite the defined property value
972      */
973     public void jsSetParent(final Scriptable parentShadow) {
974         parentShadow_ = parentShadow;
975     }
976 
977     /**
978      * Returns the value of the {@code frames} property.
979      * @return the value of the {@code frames} property
980      */
981     @JsxGetter(propertyName = "frames")
982     public Object getFrames_js() {
983         return JavaScriptEngine.UNDEFINED;
984     }
985 
986     /**
987      * Gets the {@code frames} property. Setting this shadows the
988      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
989      * @return the shadow value if set otherwise the number of frames
990      */
991     public Object jsGetFrames() {
992         if (framesShadow_ != null) {
993             return framesShadow_;
994         }
995 
996         return this;
997     }
998 
999     /**
1000      * Sets the {@code frames} property. Setting this shadows the
1001      * defined value (see https://webidl.spec.whatwg.org/#Replaceable)
1002      * @param framesShadow the value to overwrite the defined property value
1003      */
1004     public void jsSetFrames(final Scriptable framesShadow) {
1005         framesShadow_ = framesShadow;
1006     }
1007 
1008     /**
1009      * Returns the live collection of frames contained by this window.
1010      * @return the live collection of frames contained by this window
1011      */
1012     private HTMLCollection getFrames() {
1013         final Page page = getWebWindow().getEnclosedPage();
1014         if (page instanceof HtmlPage) {
1015             return new HTMLCollectionFrames((HtmlPage) page);
1016         }
1017         return null;
1018     }
1019 
1020     /**
1021      * Returns the WebWindow associated with this Window.
1022      * @return the WebWindow
1023      */
1024     public WebWindow getWebWindow() {
1025         return webWindow_;
1026     }
1027 
1028     /**
1029      * Sets the focus to this element.
1030      */
1031     @JsxFunction
1032     public void focus() {
1033         final WebWindow window = getWebWindow();
1034         window.getWebClient().setCurrentWindow(window);
1035     }
1036 
1037     /**
1038      * Removes focus from this element.
1039      */
1040     @JsxFunction
1041     public void blur() {
1042         LOG.debug("window.blur() not implemented");
1043     }
1044 
1045     /**
1046      * Closes this window.
1047      */
1048     @JsxFunction(functionName = "close")
1049     public void close_js() {
1050         final WebWindow webWindow = getWebWindow();
1051         if (webWindow instanceof TopLevelWindow) {
1052             ((TopLevelWindow) webWindow).close();
1053         }
1054         else {
1055             webWindow.getWebClient().deregisterWebWindow(webWindow);
1056         }
1057     }
1058 
1059     /**
1060      * Indicates if this window is closed.
1061      * @return {@code true} if this window is closed
1062      */
1063     @JsxGetter
1064     public boolean isClosed() {
1065         final WebWindow webWindow = getWebWindow();
1066         return !webWindow.getWebClient().containsWebWindow(webWindow);
1067     }
1068 
1069     /**
1070      * Does nothing.
1071      * @param x the horizontal position
1072      * @param y the vertical position
1073      */
1074     @JsxFunction
1075     public void moveTo(final int x, final int y) {
1076         LOG.debug("window.moveTo() not implemented");
1077     }
1078 
1079     /**
1080      * Does nothing.
1081      * @param x the horizontal position
1082      * @param y the vertical position
1083      */
1084     @JsxFunction
1085     public void moveBy(final int x, final int y) {
1086         LOG.debug("window.moveBy() not implemented");
1087     }
1088 
1089     /**
1090      * Does nothing.
1091      * @param width the width offset
1092      * @param height the height offset
1093      */
1094     @JsxFunction
1095     public void resizeBy(final int width, final int height) {
1096         LOG.debug("window.resizeBy() not implemented");
1097     }
1098 
1099     /**
1100      * Does nothing.
1101      * @param width the width of the Window in pixel after resize
1102      * @param height the height of the Window in pixel after resize
1103      */
1104     @JsxFunction
1105     public void resizeTo(final int width, final int height) {
1106         LOG.debug("window.resizeTo() not implemented");
1107     }
1108 
1109     /**
1110      * Scrolls to the specified location on the page.
1111      * @param x the horizontal position to scroll to
1112      * @param y the vertical position to scroll to
1113      */
1114     @JsxFunction
1115     public void scroll(final Scriptable x, final Scriptable y) {
1116         scrollTo(x, y);
1117     }
1118 
1119     /**
1120      * Scrolls the window content the specified distance.
1121      * @param x the horizontal distance to scroll by
1122      * @param y the vertical distance to scroll by
1123      */
1124     @JsxFunction
1125     public void scrollBy(final Scriptable x, final Scriptable y) {
1126         final HTMLElement body = document_.getBody();
1127         if (body != null) {
1128             int xOff = 0;
1129             int yOff = 0;
1130             if (y != null) {
1131                 xOff = JavaScriptEngine.toInt32(x);
1132                 yOff = JavaScriptEngine.toInt32(y);
1133             }
1134             else {
1135                 if (!(x instanceof NativeObject)) {
1136                     throw JavaScriptEngine.typeError("eee");
1137                 }
1138                 if (x.has("left", x)) {
1139                     xOff = JavaScriptEngine.toInt32(x.get("left", x));
1140                 }
1141                 if (x.has("top", x)) {
1142                     yOff = JavaScriptEngine.toInt32(x.get("top", x));
1143                 }
1144             }
1145 
1146             body.setScrollLeft(body.getScrollLeft() + xOff);
1147             body.setScrollTop(body.getScrollTop() + yOff);
1148 
1149             fireScrollEvent(body);
1150         }
1151 
1152         fireScrollEvent(document_);
1153     }
1154 
1155     private void fireScrollEvent(final Node node) {
1156         final Event event;
1157         if (getBrowserVersion().hasFeature(EVENT_SCROLL_UIEVENT)) {
1158             event = new UIEvent(node, Event.TYPE_SCROLL);
1159         }
1160         else {
1161             event = new Event(node, Event.TYPE_SCROLL);
1162             event.setCancelable(false);
1163         }
1164         node.fireEvent(event);
1165     }
1166 
1167     /**
1168      * Scrolls the window content down by the specified number of lines.
1169      * @param lines the number of lines to scroll down
1170      */
1171     @JsxFunction({FF, FF_ESR})
1172     public void scrollByLines(final int lines) {
1173         final HTMLElement body = document_.getBody();
1174         if (body != null) {
1175             body.setScrollTop(body.getScrollTop() + (19 * lines));
1176 
1177             fireScrollEvent(body);
1178         }
1179 
1180         fireScrollEvent(document_);
1181     }
1182 
1183     /**
1184      * Scrolls the window content down by the specified number of pages.
1185      * @param pages the number of pages to scroll down
1186      */
1187     @JsxFunction({FF, FF_ESR})
1188     public void scrollByPages(final int pages) {
1189         final HTMLElement body = document_.getBody();
1190         if (body != null) {
1191             body.setScrollTop(body.getScrollTop() + (getInnerHeight() * pages));
1192 
1193             fireScrollEvent(body);
1194         }
1195 
1196         fireScrollEvent(document_);
1197     }
1198 
1199     /**
1200      * Scrolls to the specified location on the page.
1201      * @param x the horizontal position to scroll to
1202      * @param y the vertical position to scroll to
1203      */
1204     @JsxFunction
1205     public void scrollTo(final Scriptable x, final Scriptable y) {
1206         final HTMLElement body = document_.getBody();
1207         if (body != null) {
1208             int xOff;
1209             int yOff;
1210             if (y != null) {
1211                 xOff = JavaScriptEngine.toInt32(x);
1212                 yOff = JavaScriptEngine.toInt32(y);
1213             }
1214             else {
1215                 if (!(x instanceof NativeObject)) {
1216                     throw JavaScriptEngine.typeError("eee");
1217                 }
1218 
1219                 xOff = body.getScrollLeft();
1220                 yOff = body.getScrollTop();
1221 
1222                 if (x.has("left", x)) {
1223                     xOff = JavaScriptEngine.toInt32(x.get("left", x));
1224                 }
1225                 if (x.has("top", x)) {
1226                     yOff = JavaScriptEngine.toInt32(x.get("top", x));
1227                 }
1228             }
1229             body.setScrollLeft(xOff);
1230             body.setScrollTop(yOff);
1231 
1232             fireScrollEvent(body);
1233         }
1234 
1235         fireScrollEvent(document_);
1236     }
1237 
1238     /**
1239      * Returns the {@code onload} property. Note that this is not necessarily a function if something else has been set.
1240      * @return the {@code onload} property
1241      */
1242     @JsxGetter
1243     public Function getOnload() {
1244         return getEventHandler(Event.TYPE_LOAD);
1245     }
1246 
1247     /**
1248      * Sets the value of the {@code onload} event handler.
1249      * @param onload the new handler
1250      */
1251     @JsxSetter
1252     public void setOnload(final Object onload) {
1253         setHandlerForJavaScript(Event.TYPE_LOAD, onload);
1254     }
1255 
1256     /**
1257      * Sets the value of the {@code onblur} event handler.
1258      * @param onblur the new handler
1259      */
1260     @JsxSetter
1261     public void setOnblur(final Object onblur) {
1262         setHandlerForJavaScript(Event.TYPE_BLUR, onblur);
1263     }
1264 
1265     /**
1266      * Returns the {@code onblur} property (not necessary a function if something else has been set).
1267      * @return the {@code onblur} property
1268      */
1269     @JsxGetter
1270     public Function getOnblur() {
1271         return getEventHandler(Event.TYPE_BLUR);
1272     }
1273 
1274     /**
1275      * Returns the {@code onclick} property (not necessary a function if something else has been set).
1276      * @return the {@code onclick} property
1277      */
1278     @JsxGetter
1279     public Function getOnclick() {
1280         return getEventHandler(MouseEvent.TYPE_CLICK);
1281     }
1282 
1283     /**
1284      * Sets the value of the {@code onclick} event handler.
1285      * @param onclick the new handler
1286      */
1287     @JsxSetter
1288     public void setOnclick(final Object onclick) {
1289         setHandlerForJavaScript(MouseEvent.TYPE_CLICK, onclick);
1290     }
1291 
1292     /**
1293      * Returns the {@code ondblclick} property (not necessary a function if something else has been set).
1294      * @return the {@code ondblclick} property
1295      */
1296     @JsxGetter
1297     public Function getOndblclick() {
1298         return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
1299     }
1300 
1301     /**
1302      * Sets the value of the {@code ondblclick} event handler.
1303      * @param ondblclick the new handler
1304      */
1305     @JsxSetter
1306     public void setOndblclick(final Object ondblclick) {
1307         setHandlerForJavaScript(MouseEvent.TYPE_DBL_CLICK, ondblclick);
1308     }
1309 
1310     /**
1311      * Returns the {@code onhashchange} property (not necessary a function if something else has been set).
1312      * @return the {@code onhashchange} property
1313      */
1314     @JsxGetter
1315     public Function getOnhashchange() {
1316         return getEventHandler(Event.TYPE_HASH_CHANGE);
1317     }
1318 
1319     /**
1320      * Sets the value of the {@code onhashchange} event handler.
1321      * @param onhashchange the new handler
1322      */
1323     @JsxSetter
1324     public void setOnhashchange(final Object onhashchange) {
1325         setHandlerForJavaScript(Event.TYPE_HASH_CHANGE, onhashchange);
1326     }
1327 
1328     /**
1329      * Returns the value of the window's {@code name} property.
1330      * @return the value of the window's {@code name} property
1331      */
1332     @JsxGetter
1333     public String getName() {
1334         return getWebWindow().getName();
1335     }
1336 
1337      /**
1338       * Sets the value of the window's {@code name} property.
1339       * @param name the value of the window's {@code name} property
1340       */
1341     @JsxSetter
1342     public void setName(final String name) {
1343         getWebWindow().setName(name);
1344     }
1345 
1346     /**
1347      * Returns the value of the window's {@code onbeforeunload} property.
1348      * @return the value of the window's {@code onbeforeunload} property
1349      */
1350     @JsxGetter
1351     public Function getOnbeforeunload() {
1352         return getEventHandler(Event.TYPE_BEFORE_UNLOAD);
1353     }
1354 
1355     /**
1356      * Sets the value of the window's {@code onbeforeunload} property.
1357      * @param onbeforeunload the value of the window's {@code onbeforeunload} property
1358      */
1359     @JsxSetter
1360     public void setOnbeforeunload(final Object onbeforeunload) {
1361         setHandlerForJavaScript(Event.TYPE_BEFORE_UNLOAD, onbeforeunload);
1362     }
1363 
1364     /**
1365      * Returns the value of the window's {@code onerror} property.
1366      * @return the value of the window's {@code onerror} property
1367      */
1368     @JsxGetter
1369     public Function getOnerror() {
1370         return getEventHandler(Event.TYPE_ERROR);
1371     }
1372 
1373     /**
1374      * Sets the value of the window's {@code onerror} property.
1375      * @param onerror the value of the window's {@code onerror} property
1376      */
1377     @JsxSetter
1378     public void setOnerror(final Object onerror) {
1379         setHandlerForJavaScript(Event.TYPE_ERROR, onerror);
1380     }
1381 
1382     /**
1383      * Returns the value of the window's {@code onmessage} property.
1384      * @return the value of the window's {@code onmessage} property
1385      */
1386     @JsxGetter
1387     public Function getOnmessage() {
1388         return getEventHandler(Event.TYPE_MESSAGE);
1389     }
1390 
1391     /**
1392      * Sets the value of the window's {@code onmessage} property.
1393      * @param onmessage the value of the window's {@code onmessage} property
1394      */
1395     @JsxSetter
1396     public void setOnmessage(final Object onmessage) {
1397         setHandlerForJavaScript(Event.TYPE_MESSAGE, onmessage);
1398     }
1399 
1400     /**
1401      * Triggers the {@code onerror} handler, if one has been set.
1402      * @param e the error that needs to be reported
1403      */
1404     public void triggerOnError(final ScriptException e) {
1405         final Function f = getOnerror();
1406         if (f != null) {
1407             String msg = e.getMessage();
1408             final String url = e.getPage().getUrl().toExternalForm();
1409 
1410             final int line = e.getFailingLineNumber();
1411             final int column = e.getFailingColumnNumber();
1412 
1413             Object jsError = e.getMessage();
1414             if (e.getCause() instanceof JavaScriptException) {
1415                 msg = "uncaught exception: " + e.getCause().getMessage();
1416                 jsError = ((JavaScriptException) e.getCause()).getValue();
1417             }
1418             else if (e.getCause() instanceof EcmaError) {
1419                 msg = "uncaught " + e.getCause().getMessage();
1420 
1421                 final EcmaError ecmaError = (EcmaError) e.getCause();
1422                 final Scriptable err = Context.getCurrentContext().newObject(this, "Error");
1423                 ScriptableObject.putProperty(err, "message", ecmaError.getMessage());
1424                 ScriptableObject.putProperty(err, "fileName", ecmaError.sourceName());
1425                 ScriptableObject.putProperty(err, "lineNumber", Integer.valueOf(ecmaError.lineNumber()));
1426                 jsError = err;
1427             }
1428 
1429             final Object[] args = {msg, url, Integer.valueOf(line), Integer.valueOf(column), jsError};
1430             f.call(Context.getCurrentContext(), this, this, args);
1431         }
1432     }
1433 
1434     private void setHandlerForJavaScript(final String eventName, final Object handler) {
1435         getEventListenersContainer().setEventHandler(eventName, handler);
1436     }
1437 
1438     /**
1439      * {@inheritDoc}
1440      */
1441     @Override
1442     protected Object getWithPreemption(final String name) {
1443         final DomNode domNode = getDomNodeOrNull();
1444         if (domNode == null) {
1445             return NOT_FOUND;
1446         }
1447 
1448         // May be attempting to retrieve a frame by name.
1449         final HtmlPage page = (HtmlPage) domNode.getPage();
1450         Object result = getFrameWindowByName(page, name);
1451 
1452         if (result == NOT_FOUND) {
1453             result = getElementsByName(page, name);
1454 
1455             if (result == NOT_FOUND) {
1456                 // May be attempting to retrieve element by ID (try map-backed operation again instead of XPath).
1457                 try {
1458                     final HtmlElement htmlElement = page.getHtmlElementById(name);
1459                     result = getScriptableFor(htmlElement);
1460                 }
1461                 catch (final ElementNotFoundException e) {
1462                     result = NOT_FOUND;
1463                 }
1464             }
1465         }
1466 
1467         if (result instanceof Window) {
1468             final WebWindow webWindow = ((Window) result).getWebWindow();
1469             result = getProxy(webWindow);
1470         }
1471 
1472         return result;
1473     }
1474 
1475     /**
1476      * {@inheritDoc}
1477      */
1478     @Override
1479     public Object get(final int index, final Scriptable start) {
1480         if (index < 0 || getWebWindow() == null) {
1481             return JavaScriptEngine.UNDEFINED;
1482         }
1483 
1484         final HTMLCollection frames = getFrames();
1485         if (frames == null || index >= frames.getLength()) {
1486             return JavaScriptEngine.UNDEFINED;
1487         }
1488         return frames.item(Integer.valueOf(index));
1489     }
1490 
1491     private static Object getFrameWindowByName(final HtmlPage page, final String name) {
1492         try {
1493             return page.getFrameByName(name).getScriptableObject();
1494         }
1495         catch (final ElementNotFoundException e) {
1496             return NOT_FOUND;
1497         }
1498     }
1499 
1500     private Object getElementsByName(final HtmlPage page, final String name) {
1501 
1502         // May be attempting to retrieve element(s) by name. IMPORTANT: We're using map-backed operations
1503         // like getHtmlElementsByName() and getHtmlElementById() as much as possible, so as to avoid XPath
1504         // overhead. We only use an XPath-based operation when we have to (where there is more than one
1505         // matching element). This optimization appears to improve performance in certain situations by ~15%
1506         // vs using XPath-based operations throughout.
1507         final List<DomElement> elements = page.getElementsByName(name);
1508 
1509         final Filter filter = new Filter(false);
1510 
1511         elements.removeIf(domElement -> !filter.matches(domElement));
1512 
1513         if (elements.isEmpty()) {
1514             return NOT_FOUND;
1515         }
1516 
1517         if (elements.size() == 1) {
1518             return getScriptableFor(elements.get(0));
1519         }
1520 
1521         // Null must be changed to '' for proper collection initialization.
1522         final String expElementName = "null".equals(name) ? "" : name;
1523 
1524         final HTMLCollection coll = new HTMLCollection(page, true);
1525         coll.setElementsSupplier(
1526                 (Supplier<List<DomNode>> & Serializable)
1527                 () -> {
1528                     final List<DomElement> expElements = page.getElementsByName(expElementName);
1529                     final List<DomNode> result = new ArrayList<>(expElements.size());
1530 
1531                     for (final DomElement domElement : expElements) {
1532                         if (filter.matches(domElement)) {
1533                             result.add(domElement);
1534                         }
1535                     }
1536                     return result;
1537                 });
1538 
1539         coll.setEffectOnCacheFunction(
1540                 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1541                 event -> {
1542                     if ("name".equals(event.getName())) {
1543                         return EffectOnCache.RESET;
1544                     }
1545                     return EffectOnCache.NONE;
1546                 });
1547 
1548         return coll;
1549     }
1550 
1551     /**
1552      * Returns the proxy for the specified window.
1553      * @param w the window whose proxy is to be returned
1554      * @return the proxy for the specified window
1555      */
1556     public static WindowProxy getProxy(final WebWindow w) {
1557         return ((Window) w.getScriptableObject()).windowProxy_;
1558     }
1559 
1560     /**
1561      * Returns the text from the status line.
1562      * @return the status line text
1563      */
1564     @JsxGetter
1565     public String getStatus() {
1566         return status_;
1567     }
1568 
1569     /**
1570      * Sets the text from the status line.
1571      * @param message the status line text
1572      */
1573     @JsxSetter
1574     public void setStatus(final String message) {
1575         status_ = message;
1576 
1577         final StatusHandler statusHandler = webWindow_.getWebClient().getStatusHandler();
1578         if (statusHandler != null) {
1579             statusHandler.statusMessageChanged(webWindow_.getEnclosedPage(), message);
1580         }
1581     }
1582 
1583     /**
1584      * Returns the {@code innerWidth}.
1585      * @return the {@code innerWidth}
1586      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref28.html">Mozilla doc</a>
1587      */
1588     @JsxGetter
1589     public int getInnerWidth() {
1590         return getWebWindow().getInnerWidth();
1591     }
1592 
1593     /**
1594      * Sets the {@code innerWidth}.
1595      * @param width the {@code innerWidth}
1596      */
1597     @JsxSetter
1598     public void setInnerWidth(final int width) {
1599         getWebWindow().setInnerWidth(width);
1600     }
1601 
1602     /**
1603      * Returns the {@code outerWidth}.
1604      * @return the {@code outerWidth}
1605      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref79.html">Mozilla doc</a>
1606      */
1607     @JsxGetter
1608     public int getOuterWidth() {
1609         return getWebWindow().getOuterWidth();
1610     }
1611 
1612     /**
1613      * Sets the {@code outerWidth}.
1614      * @param width the {@code outerWidth}
1615      */
1616     @JsxSetter
1617     public void setOuterWidth(final int width) {
1618         getWebWindow().setOuterWidth(width);
1619     }
1620 
1621     /**
1622      * Returns the {@code innerHeight}.
1623      * @return the {@code innerHeight}
1624      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref27.html">Mozilla doc</a>
1625      */
1626     @JsxGetter
1627     public int getInnerHeight() {
1628         return getWebWindow().getInnerHeight();
1629     }
1630 
1631     /**
1632      * Sets the {@code innerHeight}.
1633      * @param height the {@code innerHeight}
1634      */
1635     @JsxSetter
1636     public void setInnerHeight(final int height) {
1637         getWebWindow().setInnerHeight(height);
1638     }
1639 
1640     /**
1641      * Returns the {@code outerHeight}.
1642      * @return the {@code outerHeight}
1643      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref78.html">Mozilla doc</a>
1644      */
1645     @JsxGetter
1646     public int getOuterHeight() {
1647         return getWebWindow().getOuterHeight();
1648     }
1649 
1650     /**
1651      * Sets the {@code outerHeight}.
1652      * @param height the {@code outerHeight}
1653      */
1654     @JsxSetter
1655     public void setOuterHeight(final int height) {
1656         getWebWindow().setOuterHeight(height);
1657     }
1658 
1659     /**
1660      * Prints the current page. The current implementation uses the {@link PrintHandler}
1661      * defined for the {@link WebClient} to process the window.
1662      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref85.html">
1663      *     Mozilla documentation</a>
1664      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536672.aspx">MSDN documentation</a>
1665      */
1666     @JsxFunction
1667     public void print() {
1668         final PrintHandler handler = getWebWindow().getWebClient().getPrintHandler();
1669         if (handler == null) {
1670             LOG.info("No PrintHandler installed - window.print() ignored");
1671             return;
1672         }
1673 
1674         final SgmlPage sgmlPage = getDocument().getPage();
1675         if (!(sgmlPage instanceof HtmlPage)) {
1676             LOG.debug("Page is not an HtmlPage - window.print() ignored");
1677             return;
1678         }
1679 
1680         Event event = new Event(this, Event.TYPE_BEFOREPRINT);
1681         fireEvent(event);
1682 
1683         final HtmlPage page = (HtmlPage) sgmlPage;
1684         page.setPrinting(true);
1685         try {
1686             handler.handlePrint(page);
1687         }
1688         finally {
1689             page.setPrinting(false);
1690         }
1691         event = new Event(this, Event.TYPE_AFTERPRINT);
1692         fireEvent(event);
1693     }
1694 
1695     /**
1696      * Does nothing special anymore.
1697      * @param type the type of events to capture
1698      * @see HTMLDocument#captureEvents(String)
1699      */
1700     @JsxFunction
1701     public void captureEvents(final String type) {
1702         // Empty.
1703     }
1704 
1705     /**
1706      * Does nothing special anymore.
1707      * @param type the type of events to capture
1708      * @see HTMLDocument#releaseEvents(String)
1709      */
1710     @JsxFunction
1711     public void releaseEvents(final String type) {
1712         // Empty.
1713     }
1714 
1715     /**
1716      * Returns computed style of the element. Computed style represents the final computed values
1717      * of all CSS properties for the element. This method's return value is of the same type as
1718      * that of <code>element.style</code>, but the value returned by this method is read-only.
1719      *
1720      * @param element the element
1721      * @param pseudoElement a string specifying the pseudo-element to match (may be {@code null});
1722      *        e.g. ':before'
1723      * @return the computed style
1724      */
1725     @JsxFunction
1726     public ComputedCSSStyleDeclaration getComputedStyle(final Object element, final String pseudoElement) {
1727         if (!(element instanceof Element)) {
1728             throw JavaScriptEngine.typeError("parameter 1 is not of type 'Element'");
1729         }
1730         final Element e = (Element) element;
1731 
1732         final ComputedCssStyleDeclaration style = getWebWindow().getComputedStyle(e.getDomNodeOrDie(), pseudoElement);
1733         return new ComputedCSSStyleDeclaration(e, style);
1734     }
1735 
1736     /**
1737      * Returns the current selection.
1738      * @return the current selection
1739      */
1740     @JsxFunction
1741     public Selection getSelection() {
1742         final WebWindow webWindow = getWebWindow();
1743         // return null if the window is in a frame that is not displayed
1744         if (webWindow instanceof FrameWindow) {
1745             final FrameWindow frameWindow = (FrameWindow) webWindow;
1746             if (getBrowserVersion().hasFeature(JS_WINDOW_SELECTION_NULL_IF_INVISIBLE)
1747                     && !frameWindow.getFrameElement().isDisplayed()) {
1748                 return null;
1749             }
1750         }
1751         return getSelectionImpl();
1752     }
1753 
1754     /**
1755      * Returns the current selection.
1756      * @return the current selection
1757      */
1758     public Selection getSelectionImpl() {
1759         if (selection_ == null) {
1760             selection_ = new Selection();
1761             selection_.setParentScope(this);
1762             selection_.setPrototype(getPrototype(selection_.getClass()));
1763         }
1764         return selection_;
1765     }
1766 
1767     /**
1768      * Gets the {@code controllers}. The result doesn't currently matter but it is important to return an
1769      * object as some JavaScript libraries check it.
1770      * @see <a href="https://developer.mozilla.org/En/DOM/Window.controllers">Mozilla documentation</a>
1771      * @return some object
1772      */
1773     @JsxGetter({FF, FF_ESR})
1774     public Object getControllers() {
1775         return controllers_;
1776     }
1777 
1778     /**
1779      * Sets the {@code controllers}.
1780      * @param value the new value
1781      */
1782     @JsxSetter({FF, FF_ESR})
1783     public void setControllers(final Object value) {
1784         controllers_ = value;
1785     }
1786 
1787     /**
1788      * Returns the value of {@code mozInnerScreenX} property.
1789      * @return the value of {@code mozInnerScreenX} property
1790      */
1791     @JsxGetter(FF)
1792     public int getMozInnerScreenX() {
1793         return 12;
1794     }
1795 
1796     /**
1797      * Returns the value of {@code mozInnerScreenX} property.
1798      * @return the value of {@code mozInnerScreenX} property
1799      */
1800     @JsxGetter(value = FF_ESR, propertyName = "mozInnerScreenX")
1801     public int getMozInnerScreenXffesr_js() {
1802         return 10;
1803     }
1804 
1805     /**
1806      * Returns the value of {@code mozInnerScreenY} property.
1807      * @return the value of {@code mozInnerScreenY} property
1808      */
1809     @JsxGetter({FF, FF_ESR})
1810     public int getMozInnerScreenY() {
1811         return 89;
1812     }
1813 
1814     private static final class Filter {
1815         private final boolean includeFormFields_;
1816 
1817         Filter(final boolean includeFormFields) {
1818             includeFormFields_ = includeFormFields;
1819         }
1820 
1821         boolean matches(final Object object) {
1822             if (object instanceof HtmlEmbed
1823                 || object instanceof HtmlForm
1824                 || object instanceof HtmlImage
1825                 || object instanceof HtmlObject) {
1826                 return true;
1827             }
1828 
1829             return includeFormFields_
1830                     && (object instanceof HtmlAnchor
1831                         || object instanceof HtmlButton
1832                         || object instanceof HtmlInput
1833                         || object instanceof HtmlMap
1834                         || object instanceof HtmlSelect
1835                         || object instanceof HtmlTextArea);
1836         }
1837     }
1838 
1839     /**
1840      * Should implement the stop() function on the window object.
1841      * (currently empty implementation)
1842      * @see <a href="https://developer.mozilla.org/en/DOM/window.stop">window.stop</a>
1843      */
1844     @JsxFunction
1845     public void stop() {
1846         //empty
1847     }
1848 
1849     /**
1850      * Returns the value of {@code pageXOffset} property.
1851      * @return the value of {@code pageXOffset} property
1852      */
1853     @JsxGetter
1854     public int getPageXOffset() {
1855         return 0;
1856     }
1857 
1858     /**
1859      * Returns the value of {@code pageYOffset} property.
1860      * @return the value of {@code pageYOffset} property
1861      */
1862     @JsxGetter
1863     public int getPageYOffset() {
1864         return 0;
1865     }
1866 
1867     /**
1868      * Returns the value of {@code scrollX} property.
1869      * @return the value of {@code scrollX} property
1870      */
1871     @JsxGetter
1872     public int getScrollX() {
1873         return 0;
1874     }
1875 
1876     /**
1877      * Returns the value of {@code scrollY} property.
1878      * @return the value of {@code scrollY} property
1879      */
1880     @JsxGetter
1881     public int getScrollY() {
1882         return 0;
1883     }
1884 
1885     /**
1886      * @return the value of {@code netscape} property
1887      */
1888     @JsxGetter({FF, FF_ESR})
1889     public Netscape getNetscape() {
1890         return new Netscape(this);
1891     }
1892 
1893     /**
1894      * {@inheritDoc}
1895      * Used to allow re-declaration of constants (eg: "var undefined;").
1896      */
1897     @Override
1898     public boolean isConst(final String name) {
1899         if ("undefined".equals(name) || "Infinity".equals(name) || "NaN".equals(name)) {
1900             return false;
1901         }
1902 
1903         return super.isConst(name);
1904     }
1905 
1906     /**
1907      * {@inheritDoc}
1908      */
1909     @Override
1910     public boolean dispatchEvent(final Event event) {
1911         event.setTarget(this);
1912         final ScriptResult result = fireEvent(event);
1913         return !event.isAborted(result);
1914     }
1915 
1916     /**
1917      * Getter for the {@code onchange} event handler.
1918      * @return the handler
1919      */
1920     @JsxGetter
1921     public Function getOnchange() {
1922         return getEventHandler(Event.TYPE_CHANGE);
1923     }
1924 
1925     /**
1926      * Setter for the {@code onchange} event handler.
1927      * @param onchange the handler
1928      */
1929     @JsxSetter
1930     public void setOnchange(final Object onchange) {
1931         setHandlerForJavaScript(Event.TYPE_CHANGE, onchange);
1932     }
1933 
1934     /**
1935      * Getter for the {@code onsubmit} event handler.
1936      * @return the handler
1937      */
1938     @JsxGetter
1939     public Function getOnsubmit() {
1940         return getEventHandler(Event.TYPE_SUBMIT);
1941     }
1942 
1943     /**
1944      * Setter for the {@code onsubmit} event handler.
1945      * @param onsubmit the handler
1946      */
1947     @JsxSetter
1948     public void setOnsubmit(final Object onsubmit) {
1949         setHandlerForJavaScript(Event.TYPE_SUBMIT, onsubmit);
1950     }
1951 
1952     /**
1953      * Posts a message.
1954      * @param context the current context
1955      * @param scope the scope
1956      * @param thisObj this object
1957      * @param args the script(s) to import
1958      * @param funObj the JS function called
1959      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage">MDN documentation</a>
1960      */
1961     @JsxFunction
1962     public static void postMessage(final Context context, final Scriptable scope,
1963             final Scriptable thisObj, final Object[] args, final Function funObj) {
1964 
1965         // support the structured clone algorithm
1966         if (args.length < 1) {
1967             throw JavaScriptEngine.typeError("message not provided");
1968         }
1969         final Object message = args[0];
1970 
1971         String targetOrigin = "*";
1972         Object transfer = JavaScriptEngine.UNDEFINED;
1973 
1974         if (args.length > 1) {
1975             if (JavaScriptEngine.isArray(args[1])) {
1976                 transfer = args[1];
1977             }
1978             else {
1979                 targetOrigin = JavaScriptEngine.toString(args[1]);
1980             }
1981         }
1982 
1983         if (args.length > 2) {
1984             if (JavaScriptEngine.isArray(args[2])) {
1985                 transfer = args[2];
1986             }
1987         }
1988 
1989         final Window sender = (Window) scope;
1990         final Window receiver = (Window) thisObj;
1991         final URL receiverURL = receiver.getWebWindow().getEnclosedPage().getUrl();
1992 
1993         final WebWindow webWindow = sender.getWebWindow();
1994         final Page page = webWindow.getEnclosedPage();
1995         final URL senderURL = page.getUrl();
1996 
1997         if (!StringUtils.equalsChar('*', targetOrigin)) {
1998             final URL targetURL;
1999             if (StringUtils.equalsChar('/', targetOrigin)) {
2000                 targetURL = senderURL;
2001             }
2002             else {
2003                 try {
2004                     targetURL = new URL(targetOrigin);
2005                 }
2006                 catch (final Exception e) {
2007                     throw JavaScriptEngine.asJavaScriptException(
2008                             (HtmlUnitScriptable) getTopLevelScope(thisObj),
2009                             "Failed to execute 'postMessage' on 'Window': Invalid target origin '"
2010                                     + targetOrigin + "' was specified (reason: " + e.getMessage() + ".",
2011                             DOMException.SYNTAX_ERR);
2012                 }
2013             }
2014 
2015             if (getPort(targetURL) != getPort(receiverURL)) {
2016                 return;
2017             }
2018             if (!targetURL.getHost().equals(receiverURL.getHost())) {
2019                 return;
2020             }
2021             if (!targetURL.getProtocol().equals(receiverURL.getProtocol())) {
2022                 return;
2023             }
2024         }
2025 
2026         final String origin;
2027         try {
2028             final URL originUrl = UrlUtils.getUrlWithoutPathRefQuery(senderURL);
2029             origin = UrlUtils.removeRedundantPort(originUrl).toExternalForm();
2030         }
2031         catch (final MalformedURLException e) {
2032             throw JavaScriptEngine.throwAsScriptRuntimeEx(e);
2033         }
2034 
2035         final MessageEvent event = new MessageEvent();
2036         event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin, "", sender, transfer);
2037         event.setParentScope(scope);
2038         event.setPrototype(receiver.getPrototype(event.getClass()));
2039 
2040         final AbstractJavaScriptEngine<?> jsEngine = webWindow.getWebClient().getJavaScriptEngine();
2041         final PostponedAction action = new PostponedAction(page, "Window.postMessage") {
2042             @Override
2043             public void execute() {
2044                 final HtmlUnitContextFactory cf = jsEngine.getContextFactory();
2045                 cf.call(cx -> receiver.dispatchEvent(event));
2046             }
2047         };
2048         jsEngine.addPostponedAction(action);
2049     }
2050 
2051     /**
2052      * Returns the port of the specified URL.
2053      * @param url the URL
2054      * @return the port
2055      */
2056     public static int getPort(final URL url) {
2057         int port = url.getPort();
2058         if (port == -1) {
2059             if ("http".equals(url.getProtocol())) {
2060                 port = 80;
2061             }
2062             else {
2063                 port = 443;
2064             }
2065         }
2066         return port;
2067     }
2068 
2069     /**
2070      * The performance attribute is defined as replacable
2071      * (https://w3c.github.io/hr-time/#the-performance-attribute) but not implemented
2072      * as that.
2073      * @return the value of the {@code performance} property
2074      */
2075     @JsxGetter
2076     public Scriptable getPerformance() {
2077         if (performance_ == null) {
2078             final Performance performance = new Performance();
2079             performance.setParentScope(this);
2080             performance.setPrototype(getPrototype(performance.getClass()));
2081             performance_ = performance;
2082         }
2083         return performance_;
2084     }
2085 
2086     /**
2087      * The performance attribute is defined as replacable
2088      * (https://w3c.github.io/hr-time/#the-performance-attribute) but not implemented
2089      * as that.
2090      * <p>
2091      * Sets the {@code performance} property.
2092      * @param performance the value to overwrite the defined property value
2093      */
2094     @JsxSetter
2095     public void setPerformance(final Scriptable performance) {
2096         performance_ = performance;
2097     }
2098 
2099     /**
2100      * Returns the {@code devicePixelRatio} property.
2101      * @return the {@code devicePixelRatio} property
2102      */
2103     @JsxGetter
2104     public int getDevicePixelRatio() {
2105         return 1;
2106     }
2107 
2108     /**
2109      * Returns the {@code styleMedia} property.
2110      * @return the {@code styleMedia} property
2111      */
2112     @JsxGetter({CHROME, EDGE})
2113     public StyleMedia getStyleMedia() {
2114         final StyleMedia styleMedia = new StyleMedia();
2115         styleMedia.setParentScope(this);
2116         styleMedia.setPrototype(getPrototype(styleMedia.getClass()));
2117         return styleMedia;
2118     }
2119 
2120     /**
2121      * Returns a new MediaQueryList object representing the parsed results of the specified media query string.
2122      *
2123      * @param mediaQueryString the media query
2124      * @return a new MediaQueryList object
2125      */
2126     @JsxFunction
2127     public MediaQueryList matchMedia(final String mediaQueryString) {
2128         final MediaQueryList mediaQueryList = new MediaQueryList(mediaQueryString);
2129         mediaQueryList.setParentScope(this);
2130         mediaQueryList.setPrototype(getPrototype(mediaQueryList.getClass()));
2131         return mediaQueryList;
2132     }
2133 
2134     /**
2135      * Stub only at the moment.
2136      * @param search the text string for which to search
2137      * @param caseSensitive if true, specifies a case-sensitive search
2138      * @param backwards if true, specifies a backward search
2139      * @param wrapAround if true, specifies a wrap around search
2140      * @param wholeWord if true, specifies a whole word search
2141      * @param searchInFrames if true, specifies a search in frames
2142      * @param showDialog if true, specifies a show Dialog.
2143      * @return false
2144      */
2145     @JsxFunction
2146     public boolean find(final String search, final boolean caseSensitive,
2147             final boolean backwards, final boolean wrapAround,
2148             final boolean wholeWord, final boolean searchInFrames, final boolean showDialog) {
2149         return false;
2150     }
2151 
2152     /**
2153      * Returns the {@code speechSynthesis} property.
2154      * @return the {@code speechSynthesis} property
2155      */
2156     @JsxGetter({CHROME, EDGE})
2157     public SpeechSynthesis getSpeechSynthesis() {
2158         final SpeechSynthesis speechSynthesis = new SpeechSynthesis();
2159         speechSynthesis.setParentScope(this);
2160         speechSynthesis.setPrototype(getPrototype(speechSynthesis.getClass()));
2161         return speechSynthesis;
2162     }
2163 
2164     /**
2165      * Returns the {@code offscreenBuffering} property.
2166      * @return the {@code offscreenBuffering} property
2167      */
2168     @JsxGetter({CHROME, EDGE})
2169     public boolean isOffscreenBuffering() {
2170         return true;
2171     }
2172 
2173     /**
2174      * Returns the {@code crypto} property.
2175      * @return the {@code crypto} property
2176      */
2177     @JsxGetter
2178     public Crypto getCrypto() {
2179         if (crypto_ == null) {
2180             crypto_ = new Crypto(this);
2181         }
2182         return crypto_;
2183     }
2184 
2185     /**
2186      * {@inheritDoc}
2187      */
2188     @Override
2189     public void close() {
2190         // nothing to do
2191     }
2192 
2193     /**
2194      * Does nothing.
2195      * @param parent the new parent scope
2196      */
2197     @Override
2198     public void setParentScope(final Scriptable parent) {
2199         // nothing as the window is the top level scope and its parent scope should stay null
2200     }
2201 
2202     /**
2203      * Returns the {@code onfocus} event handler.
2204      * @return the {@code onfocus} event handler
2205      */
2206     @JsxGetter
2207     public Function getOnfocus() {
2208         return getEventHandler(Event.TYPE_FOCUS);
2209     }
2210 
2211     /**
2212      * Sets the {@code onfocus} event handler.
2213      * @param onfocus the {@code onfocus} event handler
2214      */
2215     @JsxSetter
2216     public void setOnfocus(final Object onfocus) {
2217         setHandlerForJavaScript(Event.TYPE_FOCUS, onfocus);
2218     }
2219 
2220     /**
2221      * Returns the {@code ondragend} event handler.
2222      * @return the {@code ondragend} event handler
2223      */
2224     @JsxGetter
2225     public Function getOndragend() {
2226         return getEventHandler(Event.TYPE_DRAGEND);
2227     }
2228 
2229     /**
2230      * Sets the {@code ondragend} event handler.
2231      * @param ondragend the {@code ondragend} event handler
2232      */
2233     @JsxSetter
2234     public void setOndragend(final Object ondragend) {
2235         setHandlerForJavaScript(Event.TYPE_DRAGEND, ondragend);
2236     }
2237 
2238     /**
2239      * Returns the {@code oninvalid} event handler.
2240      * @return the {@code oninvalid} event handler
2241      */
2242     @JsxGetter
2243     public Function getOninvalid() {
2244         return getEventHandler(Event.TYPE_INVALID);
2245     }
2246 
2247     /**
2248      * Sets the {@code oninvalid} event handler.
2249      * @param oninvalid the {@code oninvalid} event handler
2250      */
2251     @JsxSetter
2252     public void setOninvalid(final Object oninvalid) {
2253         setHandlerForJavaScript(Event.TYPE_INVALID, oninvalid);
2254     }
2255 
2256     /**
2257      * Returns the {@code onpointerout} event handler.
2258      * @return the {@code onpointerout} event handler
2259      */
2260     @JsxGetter({CHROME, EDGE})
2261     public Function getOnpointerout() {
2262         return getEventHandler(Event.TYPE_POINTEROUT);
2263     }
2264 
2265     /**
2266      * Sets the {@code onpointerout} event handler.
2267      * @param onpointerout the {@code onpointerout} event handler
2268      */
2269     @JsxSetter({CHROME, EDGE})
2270     public void setOnpointerout(final Object onpointerout) {
2271         setHandlerForJavaScript(Event.TYPE_POINTEROUT, onpointerout);
2272     }
2273 
2274     /**
2275      * Returns the {@code onratechange} event handler.
2276      * @return the {@code onratechange} event handler
2277      */
2278     @JsxGetter
2279     public Function getOnratechange() {
2280         return getEventHandler(Event.TYPE_RATECHANGE);
2281     }
2282 
2283     /**
2284      * Sets the {@code onratechange} event handler.
2285      * @param onratechange the {@code onratechange} event handler
2286      */
2287     @JsxSetter
2288     public void setOnratechange(final Object onratechange) {
2289         setHandlerForJavaScript(Event.TYPE_RATECHANGE, onratechange);
2290     }
2291 
2292     /**
2293      * Returns the {@code onanimationiteration} event handler.
2294      * @return the {@code onanimationiteration} event handler
2295      */
2296     @JsxGetter
2297     public Function getOnanimationiteration() {
2298         return getEventHandler(Event.TYPE_ANIMATIONITERATION);
2299     }
2300 
2301     /**
2302      * Sets the {@code onanimationiteration} event handler.
2303      * @param onanimationiteration the {@code onanimationiteration} event handler
2304      */
2305     @JsxSetter
2306     public void setOnanimationiteration(final Object onanimationiteration) {
2307         setHandlerForJavaScript(Event.TYPE_ANIMATIONITERATION, onanimationiteration);
2308     }
2309 
2310     /**
2311      * Returns the {@code oncanplaythrough} event handler.
2312      * @return the {@code oncanplaythrough} event handler
2313      */
2314     @JsxGetter
2315     public Function getOncanplaythrough() {
2316         return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2317     }
2318 
2319     /**
2320      * Sets the {@code oncanplaythrough} event handler.
2321      * @param oncanplaythrough the {@code oncanplaythrough} event handler
2322      */
2323     @JsxSetter
2324     public void setOncanplaythrough(final Object oncanplaythrough) {
2325         setHandlerForJavaScript(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2326     }
2327 
2328     /**
2329      * Returns the {@code oncancel} event handler.
2330      * @return the {@code oncancel} event handler
2331      */
2332     @JsxGetter({CHROME, EDGE})
2333     public Function getOncancel() {
2334         return getEventHandler(Event.TYPE_CANCEL);
2335     }
2336 
2337     /**
2338      * Sets the {@code oncancel} event handler.
2339      * @param oncancel the {@code oncancel} event handler
2340      */
2341     @JsxSetter({CHROME, EDGE})
2342     public void setOncancel(final Object oncancel) {
2343         setHandlerForJavaScript(Event.TYPE_CANCEL, oncancel);
2344     }
2345 
2346     /**
2347      * Returns the {@code onpointerenter} event handler.
2348      * @return the {@code onpointerenter} event handler
2349      */
2350     @JsxGetter({CHROME, EDGE})
2351     public Function getOnpointerenter() {
2352         return getEventHandler(Event.TYPE_POINTERENTER);
2353     }
2354 
2355     /**
2356      * Sets the {@code onpointerenter} event handler.
2357      * @param onpointerenter the {@code onpointerenter} event handler
2358      */
2359     @JsxSetter({CHROME, EDGE})
2360     public void setOnpointerenter(final Object onpointerenter) {
2361         setHandlerForJavaScript(Event.TYPE_POINTERENTER, onpointerenter);
2362     }
2363 
2364     /**
2365      * Returns the {@code onselect} event handler.
2366      * @return the {@code onselect} event handler
2367      */
2368     @JsxGetter
2369     public Function getOnselect() {
2370         return getEventHandler(Event.TYPE_SELECT);
2371     }
2372 
2373     /**
2374      * Sets the {@code onselect} event handler.
2375      * @param onselect the {@code onselect} event handler
2376      */
2377     @JsxSetter
2378     public void setOnselect(final Object onselect) {
2379         setHandlerForJavaScript(Event.TYPE_SELECT, onselect);
2380     }
2381 
2382     /**
2383      * Returns the {@code onauxclick} event handler.
2384      * @return the {@code onauxclick} event handler
2385      */
2386     @JsxGetter({CHROME, EDGE})
2387     public Function getOnauxclick() {
2388         return getEventHandler(Event.TYPE_AUXCLICK);
2389     }
2390 
2391     /**
2392      * Sets the {@code onauxclick} event handler.
2393      * @param onauxclick the {@code onauxclick} event handler
2394      */
2395     @JsxSetter({CHROME, EDGE})
2396     public void setOnauxclick(final Object onauxclick) {
2397         setHandlerForJavaScript(Event.TYPE_AUXCLICK, onauxclick);
2398     }
2399 
2400     /**
2401      * Returns the {@code onscroll} event handler.
2402      * @return the {@code onscroll} event handler
2403      */
2404     @JsxGetter
2405     public Function getOnscroll() {
2406         return getEventHandler(Event.TYPE_SCROLL);
2407     }
2408 
2409     /**
2410      * Sets the {@code onscroll} event handler.
2411      * @param onscroll the {@code onscroll} event handler
2412      */
2413     @JsxSetter
2414     public void setOnscroll(final Object onscroll) {
2415         setHandlerForJavaScript(Event.TYPE_SCROLL, onscroll);
2416     }
2417 
2418     /**
2419      * Returns the {@code onkeydown} event handler.
2420      * @return the {@code onkeydown} event handler
2421      */
2422     @JsxGetter
2423     public Function getOnkeydown() {
2424         return getEventHandler(Event.TYPE_KEY_DOWN);
2425     }
2426 
2427     /**
2428      * Sets the {@code onkeydown} event handler.
2429      * @param onkeydown the {@code onkeydown} event handler
2430      */
2431     @JsxSetter
2432     public void setOnkeydown(final Object onkeydown) {
2433         setHandlerForJavaScript(Event.TYPE_KEY_DOWN, onkeydown);
2434     }
2435 
2436     /**
2437      * Returns the {@code onwebkitanimationstart} event handler.
2438      * @return the {@code onwebkitanimationstart} event handler
2439      */
2440     @JsxGetter({CHROME, EDGE})
2441     public Function getOnwebkitanimationstart() {
2442         return getEventHandler(Event.TYPE_WEBANIMATIONSTART);
2443     }
2444 
2445     /**
2446      * Sets the {@code onwebkitanimationstart} event handler.
2447      * @param onwebkitanimationstart the {@code onwebkitanimationstart} event handler
2448      */
2449     @JsxSetter({CHROME, EDGE})
2450     public void setOnwebkitanimationstart(final Object onwebkitanimationstart) {
2451         setHandlerForJavaScript(Event.TYPE_WEBANIMATIONSTART, onwebkitanimationstart);
2452     }
2453 
2454     /**
2455      * Returns the {@code onkeyup} event handler.
2456      * @return the {@code onkeyup} event handler
2457      */
2458     @JsxGetter
2459     public Function getOnkeyup() {
2460         return getEventHandler(Event.TYPE_KEY_UP);
2461     }
2462 
2463     /**
2464      * Sets the {@code onkeyup} event handler.
2465      * @param onkeyup the {@code onkeyup} event handler
2466      */
2467     @JsxSetter
2468     public void setOnkeyup(final Object onkeyup) {
2469         setHandlerForJavaScript(Event.TYPE_KEY_UP, onkeyup);
2470     }
2471 
2472     /**
2473      * Returns the {@code onreset} event handler.
2474      * @return the {@code onreset} event handler
2475      */
2476     @JsxGetter
2477     public Function getOnreset() {
2478         return getEventHandler(Event.TYPE_RESET);
2479     }
2480 
2481     /**
2482      * Sets the {@code onreset} event handler.
2483      * @param onreset the {@code onreset} event handler
2484      */
2485     @JsxSetter
2486     public void setOnreset(final Object onreset) {
2487         setHandlerForJavaScript(Event.TYPE_RESET, onreset);
2488     }
2489 
2490     /**
2491      * Returns the {@code onkeypress} event handler.
2492      * @return the {@code onkeypress} event handler
2493      */
2494     @JsxGetter
2495     public Function getOnkeypress() {
2496         return getEventHandler(Event.TYPE_KEY_PRESS);
2497     }
2498 
2499     /**
2500      * Sets the {@code onkeypress} event handler.
2501      * @param onkeypress the {@code onkeypress} event handler
2502      */
2503     @JsxSetter
2504     public void setOnkeypress(final Object onkeypress) {
2505         setHandlerForJavaScript(Event.TYPE_KEY_PRESS, onkeypress);
2506     }
2507 
2508     /**
2509      * Returns the {@code ondrag} event handler.
2510      * @return the {@code ondrag} event handler
2511      */
2512     @JsxGetter
2513     public Function getOndrag() {
2514         return getEventHandler(Event.TYPE_DRAG);
2515     }
2516 
2517     /**
2518      * Sets the {@code ondrag} event handler.
2519      * @param ondrag the {@code ondrag} event handler
2520      */
2521     @JsxSetter
2522     public void setOndrag(final Object ondrag) {
2523         setHandlerForJavaScript(Event.TYPE_DRAG, ondrag);
2524     }
2525 
2526     /**
2527      * Returns the {@code onseeked} event handler.
2528      * @return the {@code onseeked} event handler
2529      */
2530     @JsxGetter
2531     public Function getOnseeked() {
2532         return getEventHandler(Event.TYPE_SEEKED);
2533     }
2534 
2535     /**
2536      * Sets the {@code onseeked} event handler.
2537      * @param onseeked the {@code onseeked} event handler
2538      */
2539     @JsxSetter
2540     public void setOnseeked(final Object onseeked) {
2541         setHandlerForJavaScript(Event.TYPE_SEEKED, onseeked);
2542     }
2543 
2544     /**
2545      * Returns the {@code onoffline} event handler.
2546      * @return the {@code onoffline} event handler
2547      */
2548     @JsxGetter
2549     public Function getOnoffline() {
2550         return getEventHandler(Event.TYPE_OFFLINE);
2551     }
2552 
2553     /**
2554      * Sets the {@code onoffline} event handler.
2555      * @param onoffline the {@code onoffline} event handler
2556      */
2557     @JsxSetter
2558     public void setOnoffline(final Object onoffline) {
2559         setHandlerForJavaScript(Event.TYPE_OFFLINE, onoffline);
2560     }
2561 
2562     /**
2563      * Returns the {@code ondeviceorientation} event handler.
2564      * @return the {@code ondeviceorientation} event handler
2565      */
2566     @JsxGetter
2567     public Function getOndeviceorientation() {
2568         return getEventHandler(Event.TYPE_DEVICEORIENTATION);
2569     }
2570 
2571     /**
2572      * Sets the {@code ondeviceorientation} event handler.
2573      * @param ondeviceorientation the {@code ondeviceorientation} event handler
2574      */
2575     @JsxSetter
2576     public void setOndeviceorientation(final Object ondeviceorientation) {
2577         setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATION, ondeviceorientation);
2578     }
2579 
2580     /**
2581      * Returns the {@code ontoggle} event handler.
2582      * @return the {@code ontoggle} event handler
2583      */
2584     @JsxGetter({CHROME, EDGE})
2585     public Function getOntoggle() {
2586         return getEventHandler(Event.TYPE_TOGGLE);
2587     }
2588 
2589     /**
2590      * Sets the {@code ontoggle} event handler.
2591      * @param ontoggle the {@code ontoggle} event handler
2592      */
2593     @JsxSetter({CHROME, EDGE})
2594     public void setOntoggle(final Object ontoggle) {
2595         setHandlerForJavaScript(Event.TYPE_TOGGLE, ontoggle);
2596     }
2597 
2598     /**
2599      * Returns the {@code onplay} event handler.
2600      * @return the {@code onplay} event handler
2601      */
2602     @JsxGetter
2603     public Function getOnplay() {
2604         return getEventHandler(Event.TYPE_PLAY);
2605     }
2606 
2607     /**
2608      * Sets the {@code onplay} event handler.
2609      * @param onplay the {@code onplay} event handler
2610      */
2611     @JsxSetter
2612     public void setOnplay(final Object onplay) {
2613         setHandlerForJavaScript(Event.TYPE_PLAY, onplay);
2614     }
2615 
2616     /**
2617      * Returns the {@code oncontextmenu} event handler.
2618      * @return the {@code oncontextmenu} event handler
2619      */
2620     @JsxGetter
2621     public Function getOncontextmenu() {
2622         return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
2623     }
2624 
2625     /**
2626      * Sets the {@code oncontextmenu} event handler.
2627      * @param oncontextmenu the {@code oncontextmenu} event handler
2628      */
2629     @JsxSetter
2630     public void setOncontextmenu(final Object oncontextmenu) {
2631         setHandlerForJavaScript(MouseEvent.TYPE_CONTEXT_MENU, oncontextmenu);
2632     }
2633 
2634     /**
2635      * Returns the {@code onmousemove} event handler.
2636      * @return the {@code onmousemove} event handler
2637      */
2638     @JsxGetter
2639     public Function getOnmousemove() {
2640         return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
2641     }
2642 
2643     /**
2644      * Sets the {@code onmousemove} event handler.
2645      * @param onmousemove the {@code onmousemove} event handler
2646      */
2647     @JsxSetter
2648     public void setOnmousemove(final Object onmousemove) {
2649         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_MOVE, onmousemove);
2650     }
2651 
2652     /**
2653      * Returns the {@code onpointermove} event handler.
2654      * @return the {@code onpointermove} event handler
2655      */
2656     @JsxGetter({CHROME, EDGE})
2657     public Function getOnpointermove() {
2658         return getEventHandler(Event.TYPE_POINTERMOVE);
2659     }
2660 
2661     /**
2662      * Sets the {@code onpointermove} event handler.
2663      * @param onpointermove the {@code onpointermove} event handler
2664      */
2665     @JsxSetter({CHROME, EDGE})
2666     public void setOnpointermove(final Object onpointermove) {
2667         setHandlerForJavaScript(Event.TYPE_POINTERMOVE, onpointermove);
2668     }
2669 
2670     /**
2671      * Returns the {@code onmouseover} event handler.
2672      * @return the {@code onmouseover} event handler
2673      */
2674     @JsxGetter
2675     public Function getOnmouseover() {
2676         return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
2677     }
2678 
2679     /**
2680      * Sets the {@code onmouseover} event handler.
2681      * @param onmouseover the {@code onmouseover} event handler
2682      */
2683     @JsxSetter
2684     public void setOnmouseover(final Object onmouseover) {
2685         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OVER, onmouseover);
2686     }
2687 
2688     /**
2689      * Returns the {@code onlostpointercapture} event handler.
2690      * @return the {@code onlostpointercapture} event handler
2691      */
2692     @JsxGetter({CHROME, EDGE})
2693     public Function getOnlostpointercapture() {
2694         return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2695     }
2696 
2697     /**
2698      * Sets the {@code onlostpointercapture} event handler.
2699      * @param onlostpointercapture the {@code onlostpointercapture} event handler
2700      */
2701     @JsxSetter({CHROME, EDGE})
2702     public void setOnlostpointercapture(final Object onlostpointercapture) {
2703         setHandlerForJavaScript(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2704     }
2705 
2706     /**
2707      * Returns the {@code onpointerover} event handler.
2708      * @return the {@code onpointerover} event handler
2709      */
2710     @JsxGetter({CHROME, EDGE})
2711     public Function getOnpointerover() {
2712         return getEventHandler(Event.TYPE_POINTEROVER);
2713     }
2714 
2715     /**
2716      * Sets the {@code onpointerover} event handler.
2717      * @param onpointerover the {@code onpointerover} event handler
2718      */
2719     @JsxSetter({CHROME, EDGE})
2720     public void setOnpointerover(final Object onpointerover) {
2721         setHandlerForJavaScript(Event.TYPE_POINTEROVER, onpointerover);
2722     }
2723 
2724     /**
2725      * Returns the {@code onclose} event handler.
2726      * @return the {@code onclose} event handler
2727      */
2728     @JsxGetter({CHROME, EDGE})
2729     public Function getOnclose() {
2730         return getEventHandler(Event.TYPE_CLOSE);
2731     }
2732 
2733     /**
2734      * Sets the {@code onclose} event handler.
2735      * @param onclose the {@code onclose} event handler
2736      */
2737     @JsxSetter({CHROME, EDGE})
2738     public void setOnclose(final Object onclose) {
2739         setHandlerForJavaScript(Event.TYPE_CLOSE, onclose);
2740     }
2741 
2742     /**
2743      * Returns the {@code onanimationend} event handler.
2744      * @return the {@code onanimationend} event handler
2745      */
2746     @JsxGetter
2747     public Function getOnanimationend() {
2748         return getEventHandler(Event.TYPE_ANIMATIONEND);
2749     }
2750 
2751     /**
2752      * Sets the {@code onanimationend} event handler.
2753      * @param onanimationend the {@code onanimationend} event handler
2754      */
2755     @JsxSetter
2756     public void setOnanimationend(final Object onanimationend) {
2757         setHandlerForJavaScript(Event.TYPE_ANIMATIONEND, onanimationend);
2758     }
2759 
2760     /**
2761      * Returns the {@code ondragenter} event handler.
2762      * @return the {@code ondragenter} event handler
2763      */
2764     @JsxGetter
2765     public Function getOndragenter() {
2766         return getEventHandler(Event.TYPE_DRAGENTER);
2767     }
2768 
2769     /**
2770      * Sets the {@code ondragenter} event handler.
2771      * @param ondragenter the {@code ondragenter} event handler
2772      */
2773     @JsxSetter
2774     public void setOndragenter(final Object ondragenter) {
2775         setHandlerForJavaScript(Event.TYPE_DRAGENTER, ondragenter);
2776     }
2777 
2778     /**
2779      * Returns the {@code onafterprint} event handler.
2780      * @return the {@code onafterprint} event handler
2781      */
2782     @JsxGetter({FF, FF_ESR})
2783     public Function getOnafterprint() {
2784         return getEventHandler(Event.TYPE_AFTERPRINT);
2785     }
2786 
2787     /**
2788      * Sets the {@code onafterprint} event handler.
2789      * @param onafterprint the {@code onafterprint} event handler
2790      */
2791     @JsxSetter({FF, FF_ESR})
2792     public void setOnafterprint(final Object onafterprint) {
2793         setHandlerForJavaScript(Event.TYPE_AFTERPRINT, onafterprint);
2794     }
2795 
2796     /**
2797      * Returns the {@code onmozfullscreenerror} event handler.
2798      * @return the {@code onmozfullscreenerror} event handler
2799      */
2800     @JsxGetter({FF, FF_ESR})
2801     public Function getOnmozfullscreenerror() {
2802         return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
2803     }
2804 
2805     /**
2806      * Sets the {@code onmozfullscreenerror} event handler.
2807      * @param onmozfullscreenerror the {@code onmozfullscreenerror} event handler
2808      */
2809     @JsxSetter({FF, FF_ESR})
2810     public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
2811         setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
2812     }
2813 
2814     /**
2815      * Returns the {@code onmouseleave} event handler.
2816      * @return the {@code onmouseleave} event handler
2817      */
2818     @JsxGetter
2819     public Function getOnmouseleave() {
2820         return getEventHandler(Event.TYPE_MOUSELEAVE);
2821     }
2822 
2823     /**
2824      * Sets the {@code onmouseleave} event handler.
2825      * @param onmouseleave the {@code onmouseleave} event handler
2826      */
2827     @JsxSetter
2828     public void setOnmouseleave(final Object onmouseleave) {
2829         setHandlerForJavaScript(Event.TYPE_MOUSELEAVE, onmouseleave);
2830     }
2831 
2832     /**
2833      * Returns the {@code onmousewheel} event handler.
2834      * @return the {@code onmousewheel} event handler
2835      */
2836     @JsxGetter({CHROME, EDGE})
2837     public Function getOnmousewheel() {
2838         return getEventHandler(Event.TYPE_MOUSEWHEEL);
2839     }
2840 
2841     /**
2842      * Sets the {@code onmousewheel} event handler.
2843      * @param onmousewheel the {@code onmousewheel} event handler
2844      */
2845     @JsxSetter({CHROME, EDGE})
2846     public void setOnmousewheel(final Object onmousewheel) {
2847         setHandlerForJavaScript(Event.TYPE_MOUSEWHEEL, onmousewheel);
2848     }
2849 
2850     /**
2851      * Returns the {@code onseeking} event handler.
2852      * @return the {@code onseeking} event handler
2853      */
2854     @JsxGetter
2855     public Function getOnseeking() {
2856         return getEventHandler(Event.TYPE_SEEKING);
2857     }
2858 
2859     /**
2860      * Sets the {@code onseeking} event handler.
2861      * @param onseeking the {@code onseeking} event handler
2862      */
2863     @JsxSetter
2864     public void setOnseeking(final Object onseeking) {
2865         setHandlerForJavaScript(Event.TYPE_SEEKING, onseeking);
2866     }
2867 
2868     /**
2869      * Returns the {@code oncuechange} event handler.
2870      * @return the {@code oncuechange} event handler
2871      */
2872     @JsxGetter({CHROME, EDGE})
2873     public Function getOncuechange() {
2874         return getEventHandler(Event.TYPE_CUECHANGE);
2875     }
2876 
2877     /**
2878      * Sets the {@code oncuechange} event handler.
2879      * @param oncuechange the {@code oncuechange} event handler
2880      */
2881     @JsxSetter({CHROME, EDGE})
2882     public void setOncuechange(final Object oncuechange) {
2883         setHandlerForJavaScript(Event.TYPE_CUECHANGE, oncuechange);
2884     }
2885 
2886     /**
2887      * Returns the {@code onpageshow} event handler.
2888      * @return the {@code onpageshow} event handler
2889      */
2890     @JsxGetter
2891     public Function getOnpageshow() {
2892         return getEventHandler(Event.TYPE_PAGESHOW);
2893     }
2894 
2895     /**
2896      * Sets the {@code onpageshow} event handler.
2897      * @param onpageshow the {@code onpageshow} event handler
2898      */
2899     @JsxSetter
2900     public void setOnpageshow(final Object onpageshow) {
2901         setHandlerForJavaScript(Event.TYPE_PAGESHOW, onpageshow);
2902     }
2903 
2904     /**
2905      * Returns the {@code onmozfullscreenchange} event handler.
2906      * @return the {@code onmozfullscreenchange} event handler
2907      */
2908     @JsxGetter({FF, FF_ESR})
2909     public Function getOnmozfullscreenchange() {
2910         return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
2911     }
2912 
2913     /**
2914      * Sets the {@code onmozfullscreenchange} event handler.
2915      * @param onmozfullscreenchange the {@code onmozfullscreenchange} event handler
2916      */
2917     @JsxSetter({FF, FF_ESR})
2918     public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
2919         setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
2920     }
2921 
2922     /**
2923      * Returns the {@code ondurationchange} event handler.
2924      * @return the {@code ondurationchange} event handler
2925      */
2926     @JsxGetter
2927     public Function getOndurationchange() {
2928         return getEventHandler(Event.TYPE_DURATIONCHANGE);
2929     }
2930 
2931     /**
2932      * Sets the {@code ondurationchange} event handler.
2933      * @param ondurationchange the {@code ondurationchange} event handler
2934      */
2935     @JsxSetter
2936     public void setOndurationchange(final Object ondurationchange) {
2937         setHandlerForJavaScript(Event.TYPE_DURATIONCHANGE, ondurationchange);
2938     }
2939 
2940     /**
2941      * Returns the {@code onplaying} event handler.
2942      * @return the {@code onplaying} event handler
2943      */
2944     @JsxGetter
2945     public Function getOnplaying() {
2946         return getEventHandler(Event.TYPE_PLAYING);
2947     }
2948 
2949     /**
2950      * Sets the {@code onplaying} event handler.
2951      * @param onplaying the {@code onplaying} event handler
2952      */
2953     @JsxSetter
2954     public void setOnplaying(final Object onplaying) {
2955         setHandlerForJavaScript(Event.TYPE_PLAYING, onplaying);
2956     }
2957 
2958     /**
2959      * Returns the {@code onended} event handler.
2960      * @return the {@code onended} event handler
2961      */
2962     @JsxGetter
2963     public Function getOnended() {
2964         return getEventHandler(Event.TYPE_ENDED);
2965     }
2966 
2967     /**
2968      * Sets the {@code onended} event handler.
2969      * @param onended the {@code onended} event handler
2970      */
2971     @JsxSetter
2972     public void setOnended(final Object onended) {
2973         setHandlerForJavaScript(Event.TYPE_ENDED, onended);
2974     }
2975 
2976     /**
2977      * Returns the {@code onloadeddata} event handler.
2978      * @return the {@code onloadeddata} event handler
2979      */
2980     @JsxGetter
2981     public Function getOnloadeddata() {
2982         return getEventHandler(Event.TYPE_LOADEDDATA);
2983     }
2984 
2985     /**
2986      * Sets the {@code onloadeddata} event handler.
2987      * @param onloadeddata the {@code onloadeddata} event handler
2988      */
2989     @JsxSetter
2990     public void setOnloadeddata(final Object onloadeddata) {
2991         setHandlerForJavaScript(Event.TYPE_LOADEDDATA, onloadeddata);
2992     }
2993 
2994     /**
2995      * Returns the {@code onunhandledrejection} event handler.
2996      * @return the {@code onunhandledrejection} event handler
2997      */
2998     @JsxGetter({CHROME, EDGE})
2999     public Function getOnunhandledrejection() {
3000         return getEventHandler(Event.TYPE_UNHANDLEDREJECTION);
3001     }
3002 
3003     /**
3004      * Sets the {@code onunhandledrejection} event handler.
3005      * @param onunhandledrejection the {@code onunhandledrejection} event handler
3006      */
3007     @JsxSetter({CHROME, EDGE})
3008     public void setOnunhandledrejection(final Object onunhandledrejection) {
3009         setHandlerForJavaScript(Event.TYPE_UNHANDLEDREJECTION, onunhandledrejection);
3010     }
3011 
3012     /**
3013      * Returns the {@code onmouseout} event handler.
3014      * @return the {@code onmouseout} event handler
3015      */
3016     @JsxGetter
3017     public Function getOnmouseout() {
3018         return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
3019     }
3020 
3021     /**
3022      * Sets the {@code onmouseout} event handler.
3023      * @param onmouseout the {@code onmouseout} event handler
3024      */
3025     @JsxSetter
3026     public void setOnmouseout(final Object onmouseout) {
3027         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OUT, onmouseout);
3028     }
3029 
3030     /**
3031      * Returns the {@code onsuspend} event handler.
3032      * @return the {@code onsuspend} event handler
3033      */
3034     @JsxGetter
3035     public Function getOnsuspend() {
3036         return getEventHandler(Event.TYPE_SUSPEND);
3037     }
3038 
3039     /**
3040      * Sets the {@code onsuspend} event handler.
3041      * @param onsuspend the {@code onsuspend} event handler
3042      */
3043     @JsxSetter
3044     public void setOnsuspend(final Object onsuspend) {
3045         setHandlerForJavaScript(Event.TYPE_SUSPEND, onsuspend);
3046     }
3047 
3048     /**
3049      * Returns the {@code onwaiting} event handler.
3050      * @return the {@code onwaiting} event handler
3051      */
3052     @JsxGetter
3053     public Function getOnwaiting() {
3054         return getEventHandler(Event.TYPE_WAITING);
3055     }
3056 
3057     /**
3058      * Sets the {@code onwaiting} event handler.
3059      * @param onwaiting the {@code onwaiting} event handler
3060      */
3061     @JsxSetter
3062     public void setOnwaiting(final Object onwaiting) {
3063         setHandlerForJavaScript(Event.TYPE_WAITING, onwaiting);
3064     }
3065 
3066     /**
3067      * Returns the {@code oncanplay} event handler.
3068      * @return the {@code oncanplay} event handler
3069      */
3070     @JsxGetter
3071     public Function getOncanplay() {
3072         return getEventHandler(Event.TYPE_CANPLAY);
3073     }
3074 
3075     /**
3076      * Sets the {@code oncanplay} event handler.
3077      * @param oncanplay the {@code oncanplay} event handler
3078      */
3079     @JsxSetter
3080     public void setOncanplay(final Object oncanplay) {
3081         setHandlerForJavaScript(Event.TYPE_CANPLAY, oncanplay);
3082     }
3083 
3084     /**
3085      * Returns the {@code onmousedown} event handler.
3086      * @return the {@code onmousedown} event handler
3087      */
3088     @JsxGetter
3089     public Function getOnmousedown() {
3090         return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
3091     }
3092 
3093     /**
3094      * Sets the {@code onmousedown} event handler.
3095      * @param onmousedown the {@code onmousedown} event handler
3096      */
3097     @JsxSetter
3098     public void setOnmousedown(final Object onmousedown) {
3099         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_DOWN, onmousedown);
3100     }
3101 
3102     /**
3103      * Returns the {@code onlanguagechange} event handler.
3104      * @return the {@code onlanguagechange} event handler
3105      */
3106     @JsxGetter
3107     public Function getOnlanguagechange() {
3108         return getEventHandler(Event.TYPE_LANGUAGECHANGE);
3109     }
3110 
3111     /**
3112      * Sets the {@code onlanguagechange} event handler.
3113      * @param onlanguagechange the {@code onlanguagechange} event handler
3114      */
3115     @JsxSetter
3116     public void setOnlanguagechange(final Object onlanguagechange) {
3117         setHandlerForJavaScript(Event.TYPE_LANGUAGECHANGE, onlanguagechange);
3118     }
3119 
3120     /**
3121      * Returns the {@code onemptied} event handler.
3122      * @return the {@code onemptied} event handler
3123      */
3124     @JsxGetter
3125     public Function getOnemptied() {
3126         return getEventHandler(Event.TYPE_EMPTIED);
3127     }
3128 
3129     /**
3130      * Sets the {@code onemptied} event handler.
3131      * @param onemptied the {@code onemptied} event handler
3132      */
3133     @JsxSetter
3134     public void setOnemptied(final Object onemptied) {
3135         setHandlerForJavaScript(Event.TYPE_EMPTIED, onemptied);
3136     }
3137 
3138     /**
3139      * Returns the {@code onrejectionhandled} event handler.
3140      * @return the {@code onrejectionhandled} event handler
3141      */
3142     @JsxGetter({CHROME, EDGE})
3143     public Function getOnrejectionhandled() {
3144         return getEventHandler(Event.TYPE_REJECTIONHANDLED);
3145     }
3146 
3147     /**
3148      * Sets the {@code onrejectionhandled} event handler.
3149      * @param onrejectionhandled the {@code onrejectionhandled} event handler
3150      */
3151     @JsxSetter({CHROME, EDGE})
3152     public void setOnrejectionhandled(final Object onrejectionhandled) {
3153         setHandlerForJavaScript(Event.TYPE_REJECTIONHANDLED, onrejectionhandled);
3154     }
3155 
3156     /**
3157      * Returns the {@code onpointercancel} event handler.
3158      * @return the {@code onpointercancel} event handler
3159      */
3160     @JsxGetter({CHROME, EDGE})
3161     public Function getOnpointercancel() {
3162         return getEventHandler(Event.TYPE_POINTERCANCEL);
3163     }
3164 
3165     /**
3166      * Sets the {@code onpointercancel} event handler.
3167      * @param onpointercancel the {@code onpointercancel} event handler
3168      */
3169     @JsxSetter({CHROME, EDGE})
3170     public void setOnpointercancel(final Object onpointercancel) {
3171         setHandlerForJavaScript(Event.TYPE_POINTERCANCEL, onpointercancel);
3172     }
3173 
3174     /**
3175      * Returns the {@code onresize} event handler.
3176      * @return the {@code onresize} event handler
3177      */
3178     @JsxGetter
3179     public Function getOnresize() {
3180         return getEventHandler(Event.TYPE_RESIZE);
3181     }
3182 
3183     /**
3184      * Sets the {@code onresize} event handler.
3185      * @param onresize the {@code onresize} event handler
3186      */
3187     @JsxSetter
3188     public void setOnresize(final Object onresize) {
3189         setHandlerForJavaScript(Event.TYPE_RESIZE, onresize);
3190     }
3191 
3192     /**
3193      * Returns the {@code onpause} event handler.
3194      * @return the {@code onpause} event handler
3195      */
3196     @JsxGetter
3197     public Function getOnpause() {
3198         return getEventHandler(Event.TYPE_PAUSE);
3199     }
3200 
3201     /**
3202      * Sets the {@code onpause} event handler.
3203      * @param onpause the {@code onpause} event handler
3204      */
3205     @JsxSetter
3206     public void setOnpause(final Object onpause) {
3207         setHandlerForJavaScript(Event.TYPE_PAUSE, onpause);
3208     }
3209 
3210     /**
3211      * Returns the {@code onloadstart} event handler.
3212      * @return the {@code onloadstart} event handler
3213      */
3214     @JsxGetter
3215     public Function getOnloadstart() {
3216         return getEventHandler(Event.TYPE_LOAD_START);
3217     }
3218 
3219     /**
3220      * Sets the {@code onloadstart} event handler.
3221      * @param onloadstart the {@code onloadstart} event handler
3222      */
3223     @JsxSetter
3224     public void setOnloadstart(final Object onloadstart) {
3225         setHandlerForJavaScript(Event.TYPE_LOAD_START, onloadstart);
3226     }
3227 
3228     /**
3229      * Returns the {@code onprogress} event handler.
3230      * @return the {@code onprogress} event handler
3231      */
3232     @JsxGetter
3233     public Function getOnprogress() {
3234         return getEventHandler(Event.TYPE_PROGRESS);
3235     }
3236 
3237     /**
3238      * Sets the {@code onprogress} event handler.
3239      * @param onprogress the {@code onprogress} event handler
3240      */
3241     @JsxSetter
3242     public void setOnprogress(final Object onprogress) {
3243         setHandlerForJavaScript(Event.TYPE_PROGRESS, onprogress);
3244     }
3245 
3246     /**
3247      * Returns the {@code onpointerup} event handler.
3248      * @return the {@code onpointerup} event handler
3249      */
3250     @JsxGetter({CHROME, EDGE})
3251     public Function getOnpointerup() {
3252         return getEventHandler(Event.TYPE_POINTERUP);
3253     }
3254 
3255     /**
3256      * Sets the {@code onpointerup} event handler.
3257      * @param onpointerup the {@code onpointerup} event handler
3258      */
3259     @JsxSetter({CHROME, EDGE})
3260     public void setOnpointerup(final Object onpointerup) {
3261         setHandlerForJavaScript(Event.TYPE_POINTERUP, onpointerup);
3262     }
3263 
3264     /**
3265      * Returns the {@code onwheel} event handler.
3266      * @return the {@code onwheel} event handler
3267      */
3268     @JsxGetter
3269     public Function getOnwheel() {
3270         return getEventHandler(Event.TYPE_WHEEL);
3271     }
3272 
3273     /**
3274      * Sets the {@code onwheel} event handler.
3275      * @param onwheel the {@code onwheel} event handler
3276      */
3277     @JsxSetter
3278     public void setOnwheel(final Object onwheel) {
3279         setHandlerForJavaScript(Event.TYPE_WHEEL, onwheel);
3280     }
3281 
3282     /**
3283      * Returns the {@code onpointerleave} event handler.
3284      * @return the {@code onpointerleave} event handler
3285      */
3286     @JsxGetter({CHROME, EDGE})
3287     public Function getOnpointerleave() {
3288         return getEventHandler(Event.TYPE_POINTERLEAVE);
3289     }
3290 
3291     /**
3292      * Sets the {@code onpointerleave} event handler.
3293      * @param onpointerleave the {@code onpointerleave} event handler
3294      */
3295     @JsxSetter({CHROME, EDGE})
3296     public void setOnpointerleave(final Object onpointerleave) {
3297         setHandlerForJavaScript(Event.TYPE_POINTERLEAVE, onpointerleave);
3298     }
3299 
3300     /**
3301      * Returns the {@code onbeforeprint} event handler.
3302      * @return the {@code onbeforeprint} event handler
3303      */
3304     @JsxGetter({FF, FF_ESR})
3305     public Function getOnbeforeprint() {
3306         return getEventHandler(Event.TYPE_BEFOREPRINT);
3307     }
3308 
3309     /**
3310      * Sets the {@code onbeforeprint} event handler.
3311      * @param onbeforeprint the {@code onbeforeprint} event handler
3312      */
3313     @JsxSetter({FF, FF_ESR})
3314     public void setOnbeforeprint(final Object onbeforeprint) {
3315         setHandlerForJavaScript(Event.TYPE_BEFOREPRINT, onbeforeprint);
3316     }
3317 
3318     /**
3319      * Returns the {@code onstorage} event handler.
3320      * @return the {@code onstorage} event handler
3321      */
3322     @JsxGetter
3323     public Function getOnstorage() {
3324         return getEventHandler(Event.TYPE_STORAGE);
3325     }
3326 
3327     /**
3328      * Sets the {@code onstorage} event handler.
3329      * @param onstorage the {@code onstorage} event handler
3330      */
3331     @JsxSetter
3332     public void setOnstorage(final Object onstorage) {
3333         setHandlerForJavaScript(Event.TYPE_STORAGE, onstorage);
3334     }
3335 
3336     /**
3337      * Returns the {@code onanimationstart} event handler.
3338      * @return the {@code onanimationstart} event handler
3339      */
3340     @JsxGetter
3341     public Function getOnanimationstart() {
3342         return getEventHandler(Event.TYPE_ANIMATIONSTART);
3343     }
3344 
3345     /**
3346      * Sets the {@code onanimationstart} event handler.
3347      * @param onanimationstart the {@code onanimationstart} event handler
3348      */
3349     @JsxSetter
3350     public void setOnanimationstart(final Object onanimationstart) {
3351         setHandlerForJavaScript(Event.TYPE_ANIMATIONSTART, onanimationstart);
3352     }
3353 
3354     /**
3355      * Returns the {@code ontimeupdate} event handler.
3356      * @return the {@code ontimeupdate} event handler
3357      */
3358     @JsxGetter
3359     public Function getOntimeupdate() {
3360         return getEventHandler(Event.TYPE_TIMEUPDATE);
3361     }
3362 
3363     /**
3364      * Sets the {@code ontimeupdate} event handler.
3365      * @param ontimeupdate the {@code ontimeupdate} event handler
3366      */
3367     @JsxSetter
3368     public void setOntimeupdate(final Object ontimeupdate) {
3369         setHandlerForJavaScript(Event.TYPE_TIMEUPDATE, ontimeupdate);
3370     }
3371 
3372     /**
3373      * Returns the {@code onpagehide} event handler.
3374      * @return the {@code onpagehide} event handler
3375      */
3376     @JsxGetter
3377     public Function getOnpagehide() {
3378         return getEventHandler(Event.TYPE_PAGEHIDE);
3379     }
3380 
3381     /**
3382      * Sets the {@code onpagehide} event handler.
3383      * @param onpagehide the {@code onpagehide} event handler
3384      */
3385     @JsxSetter
3386     public void setOnpagehide(final Object onpagehide) {
3387         setHandlerForJavaScript(Event.TYPE_PAGEHIDE, onpagehide);
3388     }
3389 
3390     /**
3391      * Returns the {@code onwebkitanimationiteration} event handler.
3392      * @return the {@code onwebkitanimationiteration} event handler
3393      */
3394     @JsxGetter({CHROME, EDGE})
3395     public Function getOnwebkitanimationiteration() {
3396         return getEventHandler(Event.TYPE_WEBKITANIMATIONITERATION);
3397     }
3398 
3399     /**
3400      * Sets the {@code onwebkitanimationiteration} event handler.
3401      * @param onwebkitanimationiteration the {@code onwebkitanimationiteration} event handler
3402      */
3403     @JsxSetter({CHROME, EDGE})
3404     public void setOnwebkitanimationiteration(final Object onwebkitanimationiteration) {
3405         setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONITERATION, onwebkitanimationiteration);
3406     }
3407 
3408     /**
3409      * Returns the {@code onabort} event handler.
3410      * @return the {@code onabort} event handler
3411      */
3412     @JsxGetter
3413     public Function getOnabort() {
3414         return getEventHandler(Event.TYPE_ABORT);
3415     }
3416 
3417     /**
3418      * Sets the {@code onabort} event handler.
3419      * @param onabort the {@code onabort} event handler
3420      */
3421     @JsxSetter
3422     public void setOnabort(final Object onabort) {
3423         setHandlerForJavaScript(Event.TYPE_ABORT, onabort);
3424     }
3425 
3426     /**
3427      * Returns the {@code onloadedmetadata} event handler.
3428      * @return the {@code onloadedmetadata} event handler
3429      */
3430     @JsxGetter
3431     public Function getOnloadedmetadata() {
3432         return getEventHandler(Event.TYPE_LOADEDMETADATA);
3433     }
3434 
3435     /**
3436      * Sets the {@code onloadedmetadata} event handler.
3437      * @param onloadedmetadata the {@code onloadedmetadata} event handler
3438      */
3439     @JsxSetter
3440     public void setOnloadedmetadata(final Object onloadedmetadata) {
3441         setHandlerForJavaScript(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
3442     }
3443 
3444     /**
3445      * Returns the {@code onmouseup} event handler.
3446      * @return the {@code onmouseup} event handler
3447      */
3448     @JsxGetter
3449     public Function getOnmouseup() {
3450         return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
3451     }
3452 
3453     /**
3454      * Sets the {@code onmouseup} event handler.
3455      * @param onmouseup the {@code onmouseup} event handler
3456      */
3457     @JsxSetter
3458     public void setOnmouseup(final Object onmouseup) {
3459         setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_UP, onmouseup);
3460     }
3461 
3462     /**
3463      * Returns the {@code ondragover} event handler.
3464      * @return the {@code ondragover} event handler
3465      */
3466     @JsxGetter
3467     public Function getOndragover() {
3468         return getEventHandler(Event.TYPE_DRAGOVER);
3469     }
3470 
3471     /**
3472      * Sets the {@code ondragover} event handler.
3473      * @param ondragover the {@code ondragover} event handler
3474      */
3475     @JsxSetter
3476     public void setOndragover(final Object ondragover) {
3477         setHandlerForJavaScript(Event.TYPE_DRAGOVER, ondragover);
3478     }
3479 
3480     /**
3481      * Returns the {@code ononline} event handler.
3482      * @return the {@code ononline} event handler
3483      */
3484     @JsxGetter
3485     public Function getOnonline() {
3486         return getEventHandler(Event.TYPE_ONLINE);
3487     }
3488 
3489     /**
3490      * Sets the {@code ononline} event handler.
3491      * @param ononline the {@code ononline} event handler
3492      */
3493     @JsxSetter
3494     public void setOnonline(final Object ononline) {
3495         setHandlerForJavaScript(Event.TYPE_ONLINE, ononline);
3496     }
3497 
3498     /**
3499      * Returns the {@code onsearch} event handler.
3500      * @return the {@code onsearch} event handler
3501      */
3502     @JsxGetter({CHROME, EDGE})
3503     public Function getOnsearch() {
3504         return getEventHandler(Event.TYPE_SEARCH);
3505     }
3506 
3507     /**
3508      * Sets the {@code onsearch} event handler.
3509      * @param onsearch the {@code onsearch} event handler
3510      */
3511     @JsxSetter({CHROME, EDGE})
3512     public void setOnsearch(final Object onsearch) {
3513         setHandlerForJavaScript(Event.TYPE_SEARCH, onsearch);
3514     }
3515 
3516     /**
3517      * Returns the {@code oninput} event handler.
3518      * @return the {@code oninput} event handler
3519      */
3520     @JsxGetter
3521     public Function getOninput() {
3522         return getEventHandler(Event.TYPE_INPUT);
3523     }
3524 
3525     /**
3526      * Sets the {@code oninput} event handler.
3527      * @param oninput the {@code oninput} event handler
3528      */
3529     @JsxSetter
3530     public void setOninput(final Object oninput) {
3531         setHandlerForJavaScript(Event.TYPE_INPUT, oninput);
3532     }
3533 
3534     /**
3535      * Returns the {@code onwebkittransitionend} event handler.
3536      * @return the {@code onwebkittransitionend} event handler
3537      */
3538     @JsxGetter({CHROME, EDGE})
3539     public Function getOnwebkittransitionend() {
3540         return getEventHandler(Event.TYPE_WEBKITTRANSITIONEND);
3541     }
3542 
3543     /**
3544      * Sets the {@code onwebkittransitionend} event handler.
3545      * @param onwebkittransitionend the {@code onwebkittransitionend} event handler
3546      */
3547     @JsxSetter({CHROME, EDGE})
3548     public void setOnwebkittransitionend(final Object onwebkittransitionend) {
3549         setHandlerForJavaScript(Event.TYPE_WEBKITTRANSITIONEND, onwebkittransitionend);
3550     }
3551 
3552     /**
3553      * Returns the {@code ondevicemotion} event handler.
3554      * @return the {@code ondevicemotion} event handler
3555      */
3556     @JsxGetter
3557     public Function getOndevicemotion() {
3558         return getEventHandler(Event.TYPE_DEVICEMOTION);
3559     }
3560 
3561     /**
3562      * Sets the {@code ondevicemotion} event handler.
3563      * @param ondevicemotion the {@code ondevicemotion} event handler
3564      */
3565     @JsxSetter
3566     public void setOndevicemotion(final Object ondevicemotion) {
3567         setHandlerForJavaScript(Event.TYPE_DEVICEMOTION, ondevicemotion);
3568     }
3569 
3570     /**
3571      * Returns the {@code onstalled} event handler.
3572      * @return the {@code onstalled} event handler
3573      */
3574     @JsxGetter
3575     public Function getOnstalled() {
3576         return getEventHandler(Event.TYPE_STALLED);
3577     }
3578 
3579     /**
3580      * Sets the {@code onstalled} event handler.
3581      * @param onstalled the {@code onstalled} event handler
3582      */
3583     @JsxSetter
3584     public void setOnstalled(final Object onstalled) {
3585         setHandlerForJavaScript(Event.TYPE_STALLED, onstalled);
3586     }
3587 
3588     /**
3589      * Returns the {@code onmouseenter} event handler.
3590      * @return the {@code onmouseenter} event handler
3591      */
3592     @JsxGetter
3593     public Function getOnmouseenter() {
3594         return getEventHandler(Event.TYPE_MOUDEENTER);
3595     }
3596 
3597     /**
3598      * Sets the {@code onmouseenter} event handler.
3599      * @param onmouseenter the {@code onmouseenter} event handler
3600      */
3601     @JsxSetter
3602     public void setOnmouseenter(final Object onmouseenter) {
3603         setHandlerForJavaScript(Event.TYPE_MOUDEENTER, onmouseenter);
3604     }
3605 
3606     /**
3607      * Returns the {@code ondragleave} event handler.
3608      * @return the {@code ondragleave} event handler
3609      */
3610     @JsxGetter
3611     public Function getOndragleave() {
3612         return getEventHandler(Event.TYPE_DRAGLEAVE);
3613     }
3614 
3615     /**
3616      * Sets the {@code ondragleave} event handler.
3617      * @param ondragleave the {@code ondragleave} event handler
3618      */
3619     @JsxSetter
3620     public void setOndragleave(final Object ondragleave) {
3621         setHandlerForJavaScript(Event.TYPE_DRAGLEAVE, ondragleave);
3622     }
3623 
3624     /**
3625      * Returns the {@code onpointerdown} event handler.
3626      * @return the {@code onpointerdown} event handler
3627      */
3628     @JsxGetter({CHROME, EDGE})
3629     public Function getOnpointerdown() {
3630         return getEventHandler(Event.TYPE_POINTERDOWN);
3631     }
3632 
3633     /**
3634      * Sets the {@code onpointerdown} event handler.
3635      * @param onpointerdown the {@code onpointerdown} event handler
3636      */
3637     @JsxSetter({CHROME, EDGE})
3638     public void setOnpointerdown(final Object onpointerdown) {
3639         setHandlerForJavaScript(Event.TYPE_POINTERDOWN, onpointerdown);
3640     }
3641 
3642     /**
3643      * Returns the {@code ondrop} event handler.
3644      * @return the {@code ondrop} event handler
3645      */
3646     @JsxGetter
3647     public Function getOndrop() {
3648         return getEventHandler(Event.TYPE_DROP);
3649     }
3650 
3651     /**
3652      * Sets the {@code ondrop} event handler.
3653      * @param ondrop the {@code ondrop} event handler
3654      */
3655     @JsxSetter
3656     public void setOndrop(final Object ondrop) {
3657         setHandlerForJavaScript(Event.TYPE_DROP, ondrop);
3658     }
3659 
3660     /**
3661      * Returns the {@code onunload} event handler.
3662      * @return the {@code onunload} event handler
3663      */
3664     @JsxGetter
3665     public Function getOnunload() {
3666         return getEventHandler(Event.TYPE_UNLOAD);
3667     }
3668 
3669     /**
3670      * Sets the {@code onunload} event handler.
3671      * @param onunload the {@code onunload} event handler
3672      */
3673     @JsxSetter
3674     public void setOnunload(final Object onunload) {
3675         setHandlerForJavaScript(Event.TYPE_UNLOAD, onunload);
3676     }
3677 
3678     /**
3679      * Returns the {@code onwebkitanimationend} event handler.
3680      * @return the {@code onwebkitanimationend} event handler
3681      */
3682     @JsxGetter({CHROME, EDGE})
3683     public Function getOnwebkitanimationend() {
3684         return getEventHandler(Event.TYPE_WEBKITANIMATIONEND);
3685     }
3686 
3687     /**
3688      * Sets the {@code onwebkitanimationend} event handler.
3689      * @param onwebkitanimationend the {@code onwebkitanimationend} event handler
3690      */
3691     @JsxSetter({CHROME, EDGE})
3692     public void setOnwebkitanimationend(final Object onwebkitanimationend) {
3693         setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONEND, onwebkitanimationend);
3694     }
3695 
3696     /**
3697      * Returns the {@code ondragstart} event handler.
3698      * @return the {@code ondragstart} event handler
3699      */
3700     @JsxGetter
3701     public Function getOndragstart() {
3702         return getEventHandler(Event.TYPE_DRAGSTART);
3703     }
3704 
3705     /**
3706      * Sets the {@code ondragstart} event handler.
3707      * @param ondragstart the {@code ondragstart} event handler
3708      */
3709     @JsxSetter
3710     public void setOndragstart(final Object ondragstart) {
3711         setHandlerForJavaScript(Event.TYPE_DRAGSTART, ondragstart);
3712     }
3713 
3714     /**
3715      * Returns the {@code ontransitionend} event handler.
3716      * @return the {@code ontransitionend} event handler
3717      */
3718     @JsxGetter({CHROME, EDGE})
3719     public Function getOntransitionend() {
3720         return getEventHandler(Event.TYPE_TRANSITIONEND);
3721     }
3722 
3723     /**
3724      * Sets the {@code ontransitionend} event handler.
3725      * @param ontransitionend the {@code ontransitionend} event handler
3726      */
3727     @JsxSetter({CHROME, EDGE})
3728     public void setOntransitionend(final Object ontransitionend) {
3729         setHandlerForJavaScript(Event.TYPE_TRANSITIONEND, ontransitionend);
3730     }
3731 
3732     /**
3733      * Returns the {@code ondeviceorientationabsolute} event handler.
3734      * @return the {@code ondeviceorientationabsolute} event handler
3735      */
3736     @JsxGetter({CHROME, EDGE})
3737     public Function getOndeviceorientationabsolute() {
3738         return getEventHandler(Event.TYPE_DEVICEORIENTATIONABSOLUTE);
3739     }
3740 
3741     /**
3742      * Sets the {@code ondeviceorientationabsolute} event handler.
3743      * @param ondeviceorientationabsolute the {@code ondeviceorientationabsolute} event handler
3744      */
3745     @JsxSetter({CHROME, EDGE})
3746     public void setOndeviceorientationabsolute(final Object ondeviceorientationabsolute) {
3747         setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATIONABSOLUTE, ondeviceorientationabsolute);
3748     }
3749 
3750     /**
3751      * Returns the {@code onvolumechange} event handler.
3752      * @return the {@code onvolumechange} event handler
3753      */
3754     @JsxGetter
3755     public Function getOnvolumechange() {
3756         return getEventHandler(Event.TYPE_VOLUMECHANGE);
3757     }
3758 
3759     /**
3760      * Sets the {@code onvolumechange} event handler.
3761      * @param onvolumechange the {@code onvolumechange} event handler
3762      */
3763     @JsxSetter
3764     public void setOnvolumechange(final Object onvolumechange) {
3765         setHandlerForJavaScript(Event.TYPE_VOLUMECHANGE, onvolumechange);
3766     }
3767 
3768     /**
3769      * Returns the {@code ongotpointercapture} event handler.
3770      * @return the {@code ongotpointercapture} event handler
3771      */
3772     @JsxGetter({CHROME, EDGE})
3773     public Function getOngotpointercapture() {
3774         return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
3775     }
3776 
3777     /**
3778      * Sets the {@code ongotpointercapture} event handler.
3779      * @param ongotpointercapture the {@code ongotpointercapture} event handler
3780      */
3781     @JsxSetter({CHROME, EDGE})
3782     public void setOngotpointercapture(final Object ongotpointercapture) {
3783         setHandlerForJavaScript(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
3784     }
3785 
3786     /**
3787      * Returns the {@code onpopstate} event handler.
3788      * @return the {@code onpopstate} event handler
3789      */
3790     @JsxGetter
3791     public Function getOnpopstate() {
3792         return getEventHandler(Event.TYPE_POPSTATE);
3793     }
3794 
3795     /**
3796      * Sets the {@code onpopstate} event handler.
3797      * @param onpopstate the {@code onpopstate} event handler
3798      */
3799     @JsxSetter
3800     public void setOnpopstate(final Object onpopstate) {
3801         setHandlerForJavaScript(Event.TYPE_POPSTATE, onpopstate);
3802     }
3803 
3804     /**
3805      * {@inheritDoc}
3806      * optimized version
3807      */
3808     @Override
3809     public BrowserVersion getBrowserVersion() {
3810         return getWebWindow().getWebClient().getBrowserVersion();
3811     }
3812 
3813     @Override
3814     public void put(final String name, final Scriptable start, final Object value) {
3815         // see https://dom.spec.whatwg.org/#window-current-event
3816         // because event is replaceable we need this hack here
3817         if ("event".equals(name)) {
3818             final Slot slot = querySlot(Context.getCurrentContext(), "event");
3819             if (slot instanceof AccessorSlot) {
3820                 delete("event");
3821             }
3822         }
3823         super.put(name, start, value);
3824     }
3825 
3826     /**
3827      * @return a boolean indicating whether the current context is secure (true) or not (false).
3828      */
3829     @JsxGetter
3830     public boolean isIsSecureContext() {
3831         final Page page = getWebWindow().getEnclosedPage();
3832         if (page != null) {
3833             final String protocol = page.getUrl().getProtocol();
3834             if ("https".equals(protocol)
3835                     || "wss".equals(protocol)
3836                     || "file".equals(protocol)) {
3837                 return true;
3838             }
3839 
3840             final String host = page.getUrl().getHost();
3841             if ("localhost".equals(host)
3842                     || "localhost.".equals(host)
3843                     || host.endsWith(".localhost")
3844                     || host.endsWith(".localhost.")) {
3845                 return true;
3846             }
3847         }
3848 
3849         return false;
3850     }
3851 }
3852 
3853 class HTMLCollectionFrames extends HTMLCollection {
3854     private static final Log LOG = LogFactory.getLog(HTMLCollectionFrames.class);
3855 
3856     HTMLCollectionFrames(final HtmlPage page) {
3857         super(page, false);
3858         this.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof BaseFrameElement);
3859     }
3860 
3861     @Override
3862     protected Scriptable getScriptableForElement(final Object obj) {
3863         final WebWindow window;
3864         if (obj instanceof BaseFrameElement) {
3865             window = ((BaseFrameElement) obj).getEnclosedWindow();
3866         }
3867         else {
3868             window = ((FrameWindow) obj).getFrameElement().getEnclosedWindow();
3869         }
3870 
3871         return window.getScriptableObject();
3872     }
3873 
3874     @Override
3875     protected Object getWithPreemption(final String name) {
3876         final List<DomNode> elements = getElements();
3877 
3878         for (final Object next : elements) {
3879             final BaseFrameElement frameElt = (BaseFrameElement) next;
3880             final WebWindow window = frameElt.getEnclosedWindow();
3881             if (name.equals(window.getName())) {
3882                 if (LOG.isDebugEnabled()) {
3883                     LOG.debug("Property \"" + name + "\" evaluated (by name) to " + window);
3884                 }
3885                 return getScriptableForElement(window);
3886             }
3887         }
3888 
3889         return NOT_FOUND;
3890     }
3891 }