View Javadoc
1   /*
2    * Copyright (c) 2002-2017 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    * http://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 com.gargoylesoftware.htmlunit.javascript.host;
16  
17  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_CHANGE_OPENER_ONLY_WINDOW_OBJECT;
18  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_FORMFIELDS_ACCESSIBLE_BY_NAME;
19  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_FRAMES_ACCESSIBLE_BY_ID;
20  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_FRAME_BY_ID_RETURNS_WINDOW;
21  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_SELECTION_NULL_IF_INVISIBLE;
22  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_TOP_WRITABLE;
23  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
24  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
25  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
26  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
27  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
28  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
29  
30  import java.io.IOException;
31  import java.io.ObjectInputStream;
32  import java.net.MalformedURLException;
33  import java.net.URL;
34  import java.util.ArrayList;
35  import java.util.Arrays;
36  import java.util.HashMap;
37  import java.util.HashSet;
38  import java.util.Iterator;
39  import java.util.List;
40  import java.util.Locale;
41  import java.util.Map;
42  import java.util.Set;
43  import java.util.WeakHashMap;
44  
45  import org.apache.commons.codec.binary.Base64;
46  import org.apache.commons.lang3.StringUtils;
47  import org.apache.commons.logging.Log;
48  import org.apache.commons.logging.LogFactory;
49  
50  import com.gargoylesoftware.htmlunit.AlertHandler;
51  import com.gargoylesoftware.htmlunit.ConfirmHandler;
52  import com.gargoylesoftware.htmlunit.DialogWindow;
53  import com.gargoylesoftware.htmlunit.ElementNotFoundException;
54  import com.gargoylesoftware.htmlunit.Page;
55  import com.gargoylesoftware.htmlunit.PromptHandler;
56  import com.gargoylesoftware.htmlunit.ScriptException;
57  import com.gargoylesoftware.htmlunit.ScriptResult;
58  import com.gargoylesoftware.htmlunit.SgmlPage;
59  import com.gargoylesoftware.htmlunit.StatusHandler;
60  import com.gargoylesoftware.htmlunit.StorageHolder.Type;
61  import com.gargoylesoftware.htmlunit.TopLevelWindow;
62  import com.gargoylesoftware.htmlunit.WebAssert;
63  import com.gargoylesoftware.htmlunit.WebClient;
64  import com.gargoylesoftware.htmlunit.WebWindow;
65  import com.gargoylesoftware.htmlunit.WebWindowNotFoundException;
66  import com.gargoylesoftware.htmlunit.html.BaseFrameElement;
67  import com.gargoylesoftware.htmlunit.html.DomChangeEvent;
68  import com.gargoylesoftware.htmlunit.html.DomChangeListener;
69  import com.gargoylesoftware.htmlunit.html.DomElement;
70  import com.gargoylesoftware.htmlunit.html.DomNode;
71  import com.gargoylesoftware.htmlunit.html.FrameWindow;
72  import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
73  import com.gargoylesoftware.htmlunit.html.HtmlAttributeChangeEvent;
74  import com.gargoylesoftware.htmlunit.html.HtmlAttributeChangeListener;
75  import com.gargoylesoftware.htmlunit.html.HtmlButton;
76  import com.gargoylesoftware.htmlunit.html.HtmlElement;
77  import com.gargoylesoftware.htmlunit.html.HtmlEmbed;
78  import com.gargoylesoftware.htmlunit.html.HtmlForm;
79  import com.gargoylesoftware.htmlunit.html.HtmlFrame;
80  import com.gargoylesoftware.htmlunit.html.HtmlImage;
81  import com.gargoylesoftware.htmlunit.html.HtmlInput;
82  import com.gargoylesoftware.htmlunit.html.HtmlLink;
83  import com.gargoylesoftware.htmlunit.html.HtmlMap;
84  import com.gargoylesoftware.htmlunit.html.HtmlObject;
85  import com.gargoylesoftware.htmlunit.html.HtmlPage;
86  import com.gargoylesoftware.htmlunit.html.HtmlSelect;
87  import com.gargoylesoftware.htmlunit.html.HtmlStyle;
88  import com.gargoylesoftware.htmlunit.html.HtmlTextArea;
89  import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
90  import com.gargoylesoftware.htmlunit.javascript.PostponedAction;
91  import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
92  import com.gargoylesoftware.htmlunit.javascript.background.BackgroundJavaScriptFactory;
93  import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJob;
94  import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnly;
95  import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnlyStatus;
96  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
97  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
98  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
99  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
100 import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
101 import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
102 import com.gargoylesoftware.htmlunit.javascript.host.crypto.Crypto;
103 import com.gargoylesoftware.htmlunit.javascript.host.css.CSS2Properties;
104 import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleDeclaration;
105 import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleSheet;
106 import com.gargoylesoftware.htmlunit.javascript.host.css.MediaQueryList;
107 import com.gargoylesoftware.htmlunit.javascript.host.css.StyleMedia;
108 import com.gargoylesoftware.htmlunit.javascript.host.css.StyleSheetList;
109 import com.gargoylesoftware.htmlunit.javascript.host.dom.Document;
110 import com.gargoylesoftware.htmlunit.javascript.host.dom.Selection;
111 import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
112 import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget;
113 import com.gargoylesoftware.htmlunit.javascript.host.event.MessageEvent;
114 import com.gargoylesoftware.htmlunit.javascript.host.event.MouseEvent;
115 import com.gargoylesoftware.htmlunit.javascript.host.html.DataTransfer;
116 import com.gargoylesoftware.htmlunit.javascript.host.html.DocumentProxy;
117 import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLBodyElement;
118 import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLCollection;
119 import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
120 import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement;
121 import com.gargoylesoftware.htmlunit.javascript.host.performance.Performance;
122 import com.gargoylesoftware.htmlunit.javascript.host.speech.SpeechSynthesis;
123 import com.gargoylesoftware.htmlunit.javascript.host.xml.XMLDocument;
124 import com.gargoylesoftware.htmlunit.xml.XmlPage;
125 
126 import net.sourceforge.htmlunit.corejs.javascript.Context;
127 import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
128 import net.sourceforge.htmlunit.corejs.javascript.ContextFactory;
129 import net.sourceforge.htmlunit.corejs.javascript.Function;
130 import net.sourceforge.htmlunit.corejs.javascript.FunctionObject;
131 import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
132 import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
133 import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
134 import net.sourceforge.htmlunit.corejs.javascript.Undefined;
135 
136 /**
137  * A JavaScript object for {@code Window}.
138  *
139  * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
140  * @author <a href="mailto:chen_jun@users.sourceforge.net">Chen Jun</a>
141  * @author David K. Taylor
142  * @author <a href="mailto:cse@dynabean.de">Christian Sell</a>
143  * @author Darrell DeBoer
144  * @author Marc Guillemot
145  * @author Dierk Koenig
146  * @author Daniel Gredler
147  * @author David D. Kilzer
148  * @author Chris Erskine
149  * @author Ahmed Ashour
150  * @author Ronald Brill
151  * @author Frank Danek
152  * @author Carsten Steul
153  * @see <a href="http://msdn.microsoft.com/en-us/library/ms535873.aspx">MSDN documentation</a>
154  */
155 @JsxClass
156 public class Window extends EventTarget implements Function, AutoCloseable {
157 
158     private static final Log LOG = LogFactory.getLog(Window.class);
159 
160     /** To be documented. */
161     @JsxConstant(CHROME)
162     public static final short TEMPORARY = 0;
163 
164     /** To be documented. */
165     @JsxConstant(CHROME)
166     public static final short PERSISTENT = 1;
167 
168     /**
169      * The minimum delay that can be used with setInterval() or setTimeout(). Browser minimums are
170      * usually in the 10ms to 15ms range, but there's really no reason for us to waste that much time.
171      * http://jsninja.com/Timers#Minimum_Timer_Delay_and_Reliability
172      */
173     private static final int MIN_TIMER_DELAY = 1;
174 
175     private Document document_;
176     private DocumentProxy documentProxy_;
177     private Navigator navigator_;
178     private WebWindow webWindow_;
179     private WindowProxy windowProxy_;
180     private Screen screen_;
181     private History history_;
182     private Location location_;
183     private ScriptableObject console_;
184     private ApplicationCache applicationCache_;
185     private Selection selection_;
186     private Event currentEvent_;
187     private String status_ = "";
188     private Map<Class<? extends Scriptable>, Scriptable> prototypes_ = new HashMap<>();
189     private Map<String, Scriptable> prototypesPerJSName_ = new HashMap<>();
190     private Object controllers_;
191     private Object opener_;
192     private Object top_ = NOT_FOUND; // top can be set from JS to any value!
193     private Crypto crypto_;
194 
195     /**
196      * Cache computed styles when possible, because their calculation is very expensive.
197      * We use a weak hash map because we don't want this cache to be the only reason
198      * nodes are kept around in the JVM, if all other references to them are gone.
199      */
200     private transient WeakHashMap<Element, Map<String, CSS2Properties>> computedStyles_ = new WeakHashMap<>();
201 
202     private final Map<Type, Storage> storages_ = new HashMap<>();
203 
204     /**
205      * Creates an instance.
206      */
207     public Window() {
208     }
209 
210     /**
211      * Creates an instance.
212      *
213      * @param cx the current context
214      * @param args the arguments to the ActiveXObject constructor
215      * @param ctorObj the function object
216      * @param inNewExpr Is new or not
217      * @return the java object to allow JavaScript to access
218      */
219     @JsxConstructor({CHROME, FF, EDGE})
220     public static Scriptable jsConstructor(final Context cx, final Object[] args, final Function ctorObj,
221             final boolean inNewExpr) {
222         throw ScriptRuntime.typeError("Illegal constructor");
223     }
224 
225     /**
226      * Restores the transient {@link #computedStyles_} map during deserialization.
227      * @param stream the stream to read the object from
228      * @throws IOException if an IO error occurs
229      * @throws ClassNotFoundException if a class is not found
230      */
231     private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException {
232         stream.defaultReadObject();
233         computedStyles_ = new WeakHashMap<>();
234     }
235 
236     /**
237      * Returns the prototype object corresponding to the specified HtmlUnit class inside the window scope.
238      * @param jsClass the class whose prototype is to be returned
239      * @return the prototype object corresponding to the specified class inside the specified scope
240      */
241     @Override
242     public Scriptable getPrototype(final Class<? extends SimpleScriptable> jsClass) {
243         return prototypes_.get(jsClass);
244     }
245 
246     /**
247      * Returns the prototype object corresponding to the specified HtmlUnit class inside the window scope.
248      * @param className the class name whose prototype is to be returned
249      * @return the prototype object corresponding to the specified class inside the specified scope
250      */
251     public Scriptable getPrototype(final String className) {
252         return prototypesPerJSName_.get(className);
253     }
254 
255     /**
256      * Sets the prototypes for HtmlUnit host classes.
257      * @param map a Map of ({@link Class}, {@link Scriptable})
258      * @param prototypesPerJSName map of {@link String} and {@link Scriptable}
259      */
260     public void setPrototypes(final Map<Class<? extends Scriptable>, Scriptable> map,
261             final Map<String, Scriptable> prototypesPerJSName) {
262         prototypes_ = map;
263         prototypesPerJSName_ = prototypesPerJSName;
264     }
265 
266     /**
267      * The JavaScript function {@code alert()}.
268      * @param message the message
269      */
270     @JsxFunction
271     public void alert(final Object message) {
272         // use Object as parameter and perform String conversion by ourself
273         // this allows to place breakpoint here and "see" the message object and its properties
274         final String stringMessage = Context.toString(message);
275         final AlertHandler handler = getWebWindow().getWebClient().getAlertHandler();
276         if (handler == null) {
277             LOG.warn("window.alert(\"" + stringMessage + "\") no alert handler installed");
278         }
279         else {
280             handler.handleAlert(document_.getPage(), stringMessage);
281         }
282     }
283 
284     /**
285      * Creates a base-64 encoded ASCII string from a string of binary data.
286      * @param stringToEncode string to encode
287      * @return the encoded string
288      */
289     @JsxFunction
290     public String btoa(final String stringToEncode) {
291         return new String(Base64.encodeBase64(stringToEncode.getBytes()));
292     }
293 
294     /**
295      * Decodes a string of data which has been encoded using base-64 encoding..
296      * @param encodedData the encoded string
297      * @return the decoded value
298      */
299     @JsxFunction
300     public String atob(final String encodedData) {
301         return new String(Base64.decodeBase64(encodedData.getBytes()));
302     }
303 
304     /**
305      * The JavaScript function {@code confirm}.
306      * @param message the message
307      * @return true if ok was pressed, false if cancel was pressed
308      */
309     @JsxFunction
310     public boolean confirm(final String message) {
311         final ConfirmHandler handler = getWebWindow().getWebClient().getConfirmHandler();
312         if (handler == null) {
313             LOG.warn("window.confirm(\""
314                     + message + "\") no confirm handler installed, simulating the OK button");
315             return true;
316         }
317         return handler.handleConfirm(document_.getPage(), message);
318     }
319 
320     /**
321      * The JavaScript function {@code prompt}.
322      * @param message the message
323      * @param defaultValue the default value displayed in the text input field
324      * @return the value typed in or {@code null} if the user pressed {@code cancel}
325      */
326     @JsxFunction
327     public String prompt(final String message, Object defaultValue) {
328         final PromptHandler handler = getWebWindow().getWebClient().getPromptHandler();
329         if (handler == null) {
330             LOG.warn("window.prompt(\"" + message + "\") no prompt handler installed");
331             return null;
332         }
333         if (defaultValue == Undefined.instance) {
334             defaultValue = null;
335         }
336         else {
337             defaultValue = Context.toString(defaultValue);
338         }
339         return handler.handlePrompt(document_.getPage(), message, (String) defaultValue);
340     }
341 
342     /**
343      * Returns the JavaScript property {@code document}.
344      * @return the document
345      */
346     @JsxGetter(propertyName = "document")
347     public DocumentProxy getDocument_js() {
348         return documentProxy_;
349     }
350 
351     /**
352      * Returns the window's current document.
353      * @return the window's current document
354      */
355     public Document getDocument() {
356         return document_;
357     }
358 
359     /**
360      * Returns the application cache.
361      * @return the application cache
362      */
363     @JsxGetter
364     public ApplicationCache getApplicationCache() {
365         return applicationCache_;
366     }
367 
368     /**
369      * Returns the current event.
370      * @return the current event, or {@code null} if no event is currently available
371      */
372     @JsxGetter({IE, CHROME})
373     public Object getEvent() {
374         return currentEvent_;
375     }
376 
377     /**
378      * Returns the current event (used internally regardless of the emulation mode).
379      * @return the current event, or {@code null} if no event is currently available
380      */
381     public Event getCurrentEvent() {
382         return currentEvent_;
383     }
384 
385     /**
386      * Sets the current event.
387      * @param event the current event
388      */
389     public void setCurrentEvent(final Event event) {
390         currentEvent_ = event;
391     }
392 
393     /**
394      * Opens a new window.
395      *
396      * @param url when a new document is opened, <i>url</i> is a String that specifies a MIME type for the document.
397      *        When a new window is opened, <i>url</i> is a String that specifies the URL to render in the new window
398      * @param name the name
399      * @param features the features
400      * @param replace whether to replace in the history list or no
401      * @return the newly opened window, or {@code null} if popup windows have been disabled
402      * @see com.gargoylesoftware.htmlunit.WebClientOptions#isPopupBlockerEnabled()
403      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536651.aspx">MSDN documentation</a>
404      */
405     @JsxFunction
406     public WindowProxy open(final Object url, final Object name, final Object features,
407             final Object replace) {
408         String urlString = null;
409         if (url != Undefined.instance) {
410             urlString = Context.toString(url);
411         }
412         String windowName = "";
413         if (name != Undefined.instance) {
414             windowName = Context.toString(name);
415         }
416         String featuresString = null;
417         if (features != Undefined.instance) {
418             featuresString = Context.toString(features);
419         }
420         final WebClient webClient = getWebWindow().getWebClient();
421 
422         if (webClient.getOptions().isPopupBlockerEnabled()) {
423             if (LOG.isDebugEnabled()) {
424                 LOG.debug("Ignoring window.open() invocation because popups are blocked.");
425             }
426             return null;
427         }
428 
429         boolean replaceCurrentEntryInBrowsingHistory = false;
430         if (replace != Undefined.instance) {
431             replaceCurrentEntryInBrowsingHistory = Context.toBoolean(replace);
432         }
433         if ((featuresString != null || replaceCurrentEntryInBrowsingHistory) && LOG.isDebugEnabled()) {
434             LOG.debug(
435                    "window.open: features and replaceCurrentEntryInBrowsingHistory "
436                     + "not implemented: url=[" + urlString
437                     + "] windowName=[" + windowName
438                     + "] features=[" + featuresString
439                     + "] replaceCurrentEntry=[" + replaceCurrentEntryInBrowsingHistory
440                     + "]");
441         }
442 
443         // if specified name is the name of an existing window, then hold it
444         if (StringUtils.isEmpty(urlString) && !"".equals(windowName)) {
445             try {
446                 final WebWindow webWindow = webClient.getWebWindowByName(windowName);
447                 return getProxy(webWindow);
448             }
449             catch (final WebWindowNotFoundException e) {
450                 // nothing
451             }
452         }
453         final URL newUrl = makeUrlForOpenWindow(urlString);
454         final WebWindow newWebWindow = webClient.openWindow(newUrl, windowName, webWindow_);
455         return getProxy(newWebWindow);
456     }
457 
458     private URL makeUrlForOpenWindow(final String urlString) {
459         if (urlString.isEmpty()) {
460             return WebClient.URL_ABOUT_BLANK;
461         }
462 
463         try {
464             final Page page = getWebWindow().getEnclosedPage();
465             if (page != null && page.isHtmlPage()) {
466                 return ((HtmlPage) page).getFullyQualifiedUrl(urlString);
467             }
468             return new URL(urlString);
469         }
470         catch (final MalformedURLException e) {
471             LOG.error("Unable to create URL for openWindow: relativeUrl=[" + urlString + "]", e);
472             return null;
473         }
474     }
475 
476     /**
477      * Sets a chunk of JavaScript to be invoked at some specified time later.
478      * The invocation occurs only if the window is opened after the delay
479      * and does not contain an other page than the one that originated the setTimeout.
480      *
481      * @param code specifies the function pointer or string that indicates the code to be executed
482      *        when the specified interval has elapsed
483      * @param timeout specifies the number of milliseconds
484      * @param language specifies language
485      * @return the id of the created timer
486      */
487     @JsxFunction
488     public int setTimeout(final Object code, int timeout, final Object language) {
489         if (timeout < MIN_TIMER_DELAY) {
490             timeout = MIN_TIMER_DELAY;
491         }
492         if (code == null) {
493             throw Context.reportRuntimeError("Function not provided.");
494         }
495 
496         final int id;
497         final WebWindow webWindow = getWebWindow();
498         final Page page = (Page) getDomNodeOrNull();
499         if (code instanceof String) {
500             final String s = (String) code;
501             final String description = "window.setTimeout(" + s + ", " + timeout + ")";
502             final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
503                     createJavaScriptJob(timeout, null, description, webWindow, s);
504             id = webWindow.getJobManager().addJob(job, page);
505         }
506         else if (code instanceof Function) {
507             final Function f = (Function) code;
508             final String functionName;
509             if (f instanceof FunctionObject) {
510                 functionName = ((FunctionObject) f).getFunctionName();
511             }
512             else {
513                 functionName = String.valueOf(f); // can this happen?
514             }
515 
516             final String description = "window.setTimeout(" + functionName + ", " + timeout + ")";
517             final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
518                     createJavaScriptJob(timeout, null, description, webWindow, f);
519             id = webWindow.getJobManager().addJob(job, page);
520         }
521         else {
522             throw Context.reportRuntimeError("Unknown type for function.");
523         }
524         return id;
525     }
526 
527     /**
528      * Cancels a time-out previously set with the {@link #setTimeout(Object, int, Object)} method.
529      *
530      * @param timeoutId identifier for the timeout to clear (returned by {@link #setTimeout(Object, int, Object)})
531      */
532     @JsxFunction
533     public void clearTimeout(final int timeoutId) {
534         if (LOG.isDebugEnabled()) {
535             LOG.debug("clearTimeout(" + timeoutId + ")");
536         }
537         getWebWindow().getJobManager().removeJob(timeoutId);
538     }
539 
540     /**
541      * Returns the JavaScript property {@code navigator}.
542      * @return the navigator
543      */
544     @JsxGetter
545     public Navigator getNavigator() {
546         return navigator_;
547     }
548 
549     /**
550      * Returns the JavaScript property {@code clientInformation}.
551      * @return the client information
552      */
553     @JsxGetter({IE, CHROME})
554     public Navigator getClientInformation() {
555         return navigator_;
556     }
557 
558     /**
559      * Returns the JavaScript property {@code clipboardData}.
560      * @return the {@link DataTransfer}
561      */
562     @JsxGetter(IE)
563     public DataTransfer getClipboardData() {
564         final DataTransfer dataTransfer = new DataTransfer();
565         dataTransfer.setParentScope(this);
566         dataTransfer.setPrototype(getPrototype(dataTransfer.getClass()));
567         return dataTransfer;
568     }
569 
570     /**
571      * Returns the window property. This is a synonym for {@code self}.
572      * @return the window property (a reference to <tt>this</tt>)
573      */
574     @JsxGetter(propertyName = "window")
575     public Window getWindow_js() {
576         return this;
577     }
578 
579     /**
580      * Returns the {@code self} property.
581      * @return this
582      */
583     @JsxGetter
584     public Window getSelf() {
585         return this;
586     }
587 
588     /**
589      * Returns the {@code localStorage} property.
590      * @return the {@code localStorage} property
591      */
592     @JsxGetter
593     public Storage getLocalStorage() {
594         return getStorage(Type.LOCAL_STORAGE);
595     }
596 
597     /**
598      * Returns the {@code sessionStorage} property.
599      * @return the {@code sessionStorage} property
600      */
601     @JsxGetter
602     public Storage getSessionStorage() {
603         return getStorage(Type.SESSION_STORAGE);
604     }
605 
606     /**
607      * Gets the storage of the specified type.
608      * @param storageType the type
609      * @return the storage
610      */
611     public Storage getStorage(final Type storageType) {
612         Storage storage = storages_.get(storageType);
613         if (storage == null) {
614             final WebWindow webWindow = getWebWindow();
615             final Map<String, String> store = webWindow.getWebClient().getStorageHolder().getStore(storageType,
616                 webWindow.getEnclosedPage());
617             storage = new Storage(this, store);
618             storages_.put(storageType, storage);
619         }
620 
621         return storage;
622     }
623 
624     /**
625      * Returns the {@code location} property.
626      * @return the {@code location} property
627      */
628     @JsxGetter
629     public Location getLocation() {
630         return location_;
631     }
632 
633     /**
634      * Sets the {@code location} property. This will cause a reload of the window.
635      * @param newLocation the URL of the new content
636      * @throws IOException when location loading fails
637      */
638     @JsxSetter
639     public void setLocation(final String newLocation) throws IOException {
640         location_.setHref(newLocation);
641     }
642 
643     /**
644      * Returns the {@code console} property.
645      * @return the {@code console} property
646      */
647     @JsxGetter
648     public ScriptableObject getConsole() {
649         return console_;
650     }
651 
652     /**
653      * Sets the {@code console}.
654      * @param console the console
655      */
656     @JsxSetter
657     public void setConsole(final ScriptableObject console) {
658         console_ = console;
659     }
660 
661     /**
662      * Prints messages to the {@code console}.
663      * @param message the message to log
664      */
665     @JsxFunction(FF)
666     public void dump(final String message) {
667         if (console_ instanceof Console) {
668             Console.log(null, console_, new Object[] {message}, null);
669         }
670     }
671 
672     /**
673      * Dummy implementation for {@code requestAnimationFrame}.
674      * @param callback the function to call when it's time to update the animation
675      * @return an identification id
676      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame">MDN Doc</a>
677      */
678     @JsxFunction
679     public int requestAnimationFrame(final Object callback) {
680         // nothing for now
681         return 1;
682     }
683 
684     /**
685      * Dummy implementation for {@code cancelAnimationFrame}.
686      * @param requestId the ID value returned by the call to window.requestAnimationFrame()
687      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame">MDN Doc</a>
688      */
689     @JsxFunction
690     public void cancelAnimationFrame(final Object requestId) {
691         // nothing for now
692     }
693 
694     /**
695      * Returns the {@code screen} property.
696      * @return the {@code screen} property
697      */
698     @JsxGetter
699     public Screen getScreen() {
700         return screen_;
701     }
702 
703     /**
704      * Returns the {@code history} property.
705      * @return the {@code history} property
706      */
707     @JsxGetter
708     public History getHistory() {
709         return history_;
710     }
711 
712     /**
713      * Returns the {@code external} property.
714      * @return the {@code external} property
715      */
716     @JsxGetter
717     public External getExternal() {
718         final External external = new External();
719         external.setParentScope(this);
720         external.setPrototype(getPrototype(external.getClass()));
721         return external;
722     }
723 
724     /**
725      * Initializes this window.
726      * @param webWindow the web window corresponding to this window
727      */
728     public void initialize(final WebWindow webWindow) {
729         webWindow_ = webWindow;
730         webWindow_.setScriptableObject(this);
731 
732         windowProxy_ = new WindowProxy(webWindow_);
733 
734         final Page enclosedPage = webWindow.getEnclosedPage();
735         if (enclosedPage instanceof XmlPage) {
736             document_ = new XMLDocument();
737         }
738         else {
739             document_ = new HTMLDocument();
740         }
741         document_.setParentScope(this);
742         document_.setPrototype(getPrototype(document_.getClass()));
743         document_.setWindow(this);
744 
745         if (enclosedPage instanceof SgmlPage) {
746             final SgmlPage page = (SgmlPage) enclosedPage;
747             document_.setDomNode(page);
748 
749             final DomHtmlAttributeChangeListenerImpl listener = new DomHtmlAttributeChangeListenerImpl();
750             page.addDomChangeListener(listener);
751 
752             if (page.isHtmlPage()) {
753                 ((HtmlPage) page).addHtmlAttributeChangeListener(listener);
754                 ((HtmlPage) page).addAutoCloseable(this);
755             }
756         }
757 
758         documentProxy_ = new DocumentProxy(webWindow_);
759 
760         navigator_ = new Navigator();
761         navigator_.setParentScope(this);
762         navigator_.setPrototype(getPrototype(navigator_.getClass()));
763 
764         screen_ = new Screen();
765         screen_.setParentScope(this);
766         screen_.setPrototype(getPrototype(screen_.getClass()));
767 
768         history_ = new History();
769         history_.setParentScope(this);
770         history_.setPrototype(getPrototype(history_.getClass()));
771 
772         location_ = new Location();
773         location_.setParentScope(this);
774         location_.setPrototype(getPrototype(location_.getClass()));
775         location_.initialize(this);
776 
777         console_ = new Console();
778         ((Console) console_).setWebWindow(webWindow_);
779         console_.setParentScope(this);
780         ((Console) console_).setPrototype(getPrototype(((SimpleScriptable) console_).getClass()));
781 
782         applicationCache_ = new ApplicationCache();
783         applicationCache_.setParentScope(this);
784         applicationCache_.setPrototype(getPrototype(applicationCache_.getClass()));
785 
786         // like a JS new Object()
787         final Context ctx = Context.getCurrentContext();
788         controllers_ = ctx.newObject(this);
789 
790         if (webWindow_ instanceof TopLevelWindow) {
791             final WebWindow opener = ((TopLevelWindow) webWindow_).getOpener();
792             if (opener != null) {
793                 opener_ = opener.getScriptableObject();
794             }
795         }
796     }
797 
798     /**
799      * Initialize the object.
800      * @param enclosedPage the page containing the JavaScript
801      */
802     public void initialize(final Page enclosedPage) {
803         if (enclosedPage != null && enclosedPage.isHtmlPage()) {
804             final HtmlPage htmlPage = (HtmlPage) enclosedPage;
805 
806             // Windows don't have corresponding DomNodes so set the domNode
807             // variable to be the page. If this isn't set then SimpleScriptable.get()
808             // won't work properly
809             setDomNode(htmlPage);
810             clearEventListenersContainer();
811 
812             WebAssert.notNull("document_", document_);
813             document_.setDomNode(htmlPage);
814         }
815     }
816 
817     /**
818      * Initializes the object. Only called for Windows with no contents.
819      */
820     public void initialize() {
821         // Empty.
822     }
823 
824     /**
825      * Returns the value of the {@code top} property.
826      * @return the value of {@code top}
827      */
828     @JsxGetter
829     public Object getTop() {
830         if (top_ != NOT_FOUND) {
831             return top_;
832         }
833 
834         final WebWindow top = getWebWindow().getTopWindow();
835         return top.getScriptableObject();
836     }
837 
838     /**
839      * Sets the value of the {@code top} property.
840      * @param o the new value
841      */
842     @JsxSetter
843     public void setTop(final Object o) {
844         if (getBrowserVersion().hasFeature(JS_WINDOW_TOP_WRITABLE)) {
845             top_ = o;
846         }
847     }
848 
849     /**
850      * Returns the value of the {@code parent} property.
851      * @return the value of the {@code parent} property
852      */
853     @JsxGetter
854     public ScriptableObject getParent() {
855         final WebWindow parent = getWebWindow().getParentWindow();
856         return parent.getScriptableObject();
857     }
858 
859     /**
860      * Returns the value of the {@code opener} property.
861      * @return the value of the {@code opener}, or {@code null} for a top level window
862      */
863     @JsxGetter
864     public Object getOpener() {
865         Object opener = opener_;
866         if (opener instanceof Window) {
867             opener = ((Window) opener).windowProxy_;
868         }
869         return opener;
870     }
871 
872     /**
873      * Sets the {@code opener} property.
874      * @param newValue the new value
875      */
876     @JsxSetter
877     public void setOpener(final Object newValue) {
878         if (getBrowserVersion().hasFeature(JS_WINDOW_CHANGE_OPENER_ONLY_WINDOW_OBJECT)
879             && newValue != null && newValue != Undefined.instance && !(newValue instanceof Window)) {
880             throw Context.reportRuntimeError("Can't set opener to something other than a window!");
881         }
882         opener_ = newValue;
883     }
884 
885     /**
886      * Returns the (i)frame in which the window is contained.
887      * @return {@code null} for a top level window
888      */
889     @JsxGetter
890     public Object getFrameElement() {
891         final WebWindow window = getWebWindow();
892         if (window instanceof FrameWindow) {
893             return ((FrameWindow) window).getFrameElement().getScriptableObject();
894         }
895         return null;
896     }
897 
898     /**
899      * Returns the value of the {@code frames} property.
900      * @return the value of the {@code frames} property
901      */
902     @JsxGetter(propertyName = "frames")
903     public Window getFrames_js() {
904         return this;
905     }
906 
907     /**
908      * Returns the number of frames contained by this window.
909      * @return the number of frames contained by this window
910      */
911     @JsxGetter
912     public int getLength() {
913         return getFrames().getLength();
914     }
915 
916     /**
917      * Returns the live collection of frames contained by this window.
918      * @return the live collection of frames contained by this window
919      */
920     private HTMLCollection getFrames() {
921         final HtmlPage page = (HtmlPage) getWebWindow().getEnclosedPage();
922         return new HTMLCollectionFrames(page);
923     }
924 
925     /**
926      * Returns the WebWindow associated with this Window.
927      * @return the WebWindow
928      */
929     public WebWindow getWebWindow() {
930         return webWindow_;
931     }
932 
933     /**
934      * Sets the focus to this element.
935      */
936     @JsxFunction
937     public void focus() {
938         final WebWindow window = getWebWindow();
939         window.getWebClient().setCurrentWindow(window);
940     }
941 
942     /**
943      * Removes focus from this element.
944      */
945     @JsxFunction
946     public void blur() {
947         if (LOG.isDebugEnabled()) {
948             LOG.debug("window.blur() not implemented");
949         }
950     }
951 
952     /**
953      * Closes this window.
954      */
955     @JsxFunction(functionName = "close")
956     public void close_js() {
957         final WebWindow webWindow = getWebWindow();
958         if (webWindow instanceof TopLevelWindow) {
959             ((TopLevelWindow) webWindow).close();
960         }
961         else {
962             webWindow.getWebClient().deregisterWebWindow(webWindow);
963         }
964     }
965 
966     /**
967      * Indicates if this window is closed.
968      * @return {@code true} if this window is closed
969      */
970     @JsxGetter
971     @CanSetReadOnly(CanSetReadOnlyStatus.IGNORE)
972     public boolean isClosed() {
973         final WebWindow webWindow = getWebWindow();
974         return !webWindow.getWebClient().containsWebWindow(webWindow);
975     }
976 
977     /**
978      * Does nothing.
979      * @param x the horizontal position
980      * @param y the vertical position
981      */
982     @JsxFunction
983     public void moveTo(final int x, final int y) {
984         if (LOG.isDebugEnabled()) {
985             LOG.debug("window.moveTo() not implemented");
986         }
987     }
988 
989     /**
990      * Does nothing.
991      * @param x the horizontal position
992      * @param y the vertical position
993      */
994     @JsxFunction
995     public void moveBy(final int x, final int y) {
996         if (LOG.isDebugEnabled()) {
997             LOG.debug("window.moveBy() not implemented");
998         }
999     }
1000 
1001     /**
1002      * Loads the new HTML document corresponding to the specified URL.
1003      * @param url the location of the new HTML document to load
1004      * @throws IOException if loading the specified location fails
1005      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536638%28VS.85%29.aspx">MSDN Documentation</a>
1006      */
1007     @JsxFunction(IE)
1008     public void navigate(final String url) throws IOException {
1009         getLocation().assign(url);
1010     }
1011 
1012     /**
1013      * Does nothing.
1014      * @param width the width offset
1015      * @param height the height offset
1016      */
1017     @JsxFunction
1018     public void resizeBy(final int width, final int height) {
1019         if (LOG.isDebugEnabled()) {
1020             LOG.debug("window.resizeBy() not implemented");
1021         }
1022     }
1023 
1024     /**
1025      * Does nothing.
1026      * @param width the width of the Window in pixel after resize
1027      * @param height the height of the Window in pixel after resize
1028      */
1029     @JsxFunction
1030     public void resizeTo(final int width, final int height) {
1031         if (LOG.isDebugEnabled()) {
1032             LOG.debug("window.resizeTo() not implemented");
1033         }
1034     }
1035 
1036     /**
1037      * Scrolls to the specified location on the page.
1038      * @param x the horizontal position to scroll to
1039      * @param y the vertical position to scroll to
1040      */
1041     @JsxFunction
1042     public void scroll(final int x, final int y) {
1043         scrollTo(x, y);
1044     }
1045 
1046     /**
1047      * Scrolls the window content the specified distance.
1048      * @param x the horizontal distance to scroll by
1049      * @param y the vertical distance to scroll by
1050      */
1051     @JsxFunction
1052     public void scrollBy(final int x, final int y) {
1053         final HTMLElement body = ((HTMLDocument) document_).getBody();
1054         if (body != null) {
1055             body.setScrollLeft(body.getScrollLeft() + x);
1056             body.setScrollTop(body.getScrollTop() + y);
1057         }
1058     }
1059 
1060     /**
1061      * Scrolls the window content down by the specified number of lines.
1062      * @param lines the number of lines to scroll down
1063      */
1064     @JsxFunction(FF)
1065     public void scrollByLines(final int lines) {
1066         final HTMLElement body = ((HTMLDocument) document_).getBody();
1067         if (body != null) {
1068             body.setScrollTop(body.getScrollTop() + (19 * lines));
1069         }
1070     }
1071 
1072     /**
1073      * Scrolls the window content down by the specified number of pages.
1074      * @param pages the number of pages to scroll down
1075      */
1076     @JsxFunction(FF)
1077     public void scrollByPages(final int pages) {
1078         final HTMLElement body = ((HTMLDocument) document_).getBody();
1079         if (body != null) {
1080             body.setScrollTop(body.getScrollTop() + (getInnerHeight() * pages));
1081         }
1082     }
1083 
1084     /**
1085      * Scrolls to the specified location on the page.
1086      * @param x the horizontal position to scroll to
1087      * @param y the vertical position to scroll to
1088      */
1089     @JsxFunction
1090     public void scrollTo(final int x, final int y) {
1091         final HTMLElement body = ((HTMLDocument) document_).getBody();
1092         if (body != null) {
1093             body.setScrollLeft(x);
1094             body.setScrollTop(y);
1095         }
1096     }
1097 
1098     /**
1099      * Returns the {@code onload} property. Note that this is not necessarily a function if something else has been set.
1100      * @return the {@code onload} property
1101      */
1102     @JsxGetter
1103     public Object getOnload() {
1104         final Object onload = getEventHandler("load");
1105         if (onload == null) {
1106             final HtmlPage page = (HtmlPage) getWebWindow().getEnclosedPage();
1107             final HtmlElement body = page.getBody();
1108             if (body != null) {
1109                 final HTMLBodyElement b = (HTMLBodyElement) body.getScriptableObject();
1110                 return b.getEventHandler("onload");
1111             }
1112             return null;
1113         }
1114         return onload;
1115     }
1116 
1117     /**
1118      * Sets the value of the {@code onload} event handler.
1119      * @param onload the new handler
1120      */
1121     @JsxSetter
1122     public void setOnload(final Object onload) {
1123         getEventListenersContainer().setEventHandler(Event.TYPE_LOAD, onload);
1124     }
1125 
1126     /**
1127      * Sets the value of the {@code onblur} event handler.
1128      * @param onblur the new handler
1129      */
1130     @JsxSetter
1131     public void setOnblur(final Object onblur) {
1132         getEventListenersContainer().setEventHandler(Event.TYPE_BLUR, onblur);
1133     }
1134 
1135     /**
1136      * Returns the {@code onblur} property (not necessary a function if something else has been set).
1137      * @return the {@code onblur} property
1138      */
1139     @JsxGetter
1140     public Object getOnblur() {
1141         return getEventHandler(Event.TYPE_BLUR);
1142     }
1143 
1144     /**
1145      * Returns the {@code onclick} property (not necessary a function if something else has been set).
1146      * @return the {@code onclick} property
1147      */
1148     @JsxGetter
1149     public Object getOnclick() {
1150         return getEventHandler(MouseEvent.TYPE_CLICK);
1151     }
1152 
1153     /**
1154      * Sets the value of the {@code onclick} event handler.
1155      * @param onclick the new handler
1156      */
1157     @JsxSetter
1158     public void setOnclick(final Object onclick) {
1159         setHandlerForJavaScript(MouseEvent.TYPE_CLICK, onclick);
1160     }
1161 
1162     /**
1163      * Returns the {@code ondblclick} property (not necessary a function if something else has been set).
1164      * @return the {@code ondblclick} property
1165      */
1166     @JsxGetter
1167     public Object getOndblclick() {
1168         return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
1169     }
1170 
1171     /**
1172      * Sets the value of the {@code ondblclick} event handler.
1173      * @param ondblclick the new handler
1174      */
1175     @JsxSetter
1176     public void setOndblclick(final Object ondblclick) {
1177         setHandlerForJavaScript(MouseEvent.TYPE_DBL_CLICK, ondblclick);
1178     }
1179 
1180     /**
1181      * Returns the {@code onhashchange} property (not necessary a function if something else has been set).
1182      * @return the {@code onhashchange} property
1183      */
1184     @JsxGetter
1185     public Object getOnhashchange() {
1186         return getEventHandler(Event.TYPE_HASH_CHANGE);
1187     }
1188 
1189     /**
1190      * Sets the value of the {@code onhashchange} event handler.
1191      * @param onhashchange the new handler
1192      */
1193     @JsxSetter
1194     public void setOnhashchange(final Object onhashchange) {
1195         setHandlerForJavaScript(Event.TYPE_HASH_CHANGE, onhashchange);
1196     }
1197 
1198     /**
1199      * Returns the value of the window's {@code name} property.
1200      * @return the value of the window's {@code name} property
1201      */
1202     @JsxGetter
1203     public String getName() {
1204         return getWebWindow().getName();
1205     }
1206 
1207      /**
1208      * Sets the value of the window's {@code name} property.
1209      * @param name the value of the window's {@code name} property
1210      */
1211     @JsxSetter
1212     public void setName(final String name) {
1213         getWebWindow().setName(name);
1214     }
1215 
1216     /**
1217      * Returns the value of the window's {@code onbeforeunload} property.
1218      * @return the value of the window's {@code onbeforeunload} property
1219      */
1220     @JsxGetter
1221     public Object getOnbeforeunload() {
1222         return getEventHandler(Event.TYPE_BEFORE_UNLOAD);
1223     }
1224 
1225     /**
1226      * Sets the value of the window's {@code onbeforeunload} property.
1227      * @param onbeforeunload the value of the window's {@code onbeforeunload} property
1228      */
1229     @JsxSetter
1230     public void setOnbeforeunload(final Object onbeforeunload) {
1231         setHandlerForJavaScript(Event.TYPE_BEFORE_UNLOAD, onbeforeunload);
1232     }
1233 
1234     /**
1235      * Returns the value of the window's {@code onerror} property.
1236      * @return the value of the window's {@code onerror} property
1237      */
1238     @JsxGetter
1239     public Object getOnerror() {
1240         return getEventHandler(Event.TYPE_ERROR);
1241     }
1242 
1243     /**
1244      * Sets the value of the window's {@code onerror} property.
1245      * @param onerror the value of the window's {@code onerror} property
1246      */
1247     @JsxSetter
1248     public void setOnerror(final Object onerror) {
1249         setHandlerForJavaScript(Event.TYPE_ERROR, onerror);
1250     }
1251 
1252     /**
1253      * Returns the value of the window's {@code onmessage} property.
1254      * @return the value of the window's {@code onmessage} property
1255      */
1256     @JsxGetter
1257     public Object getOnmessage() {
1258         return getEventHandler(Event.TYPE_MESSAGE);
1259     }
1260 
1261     /**
1262      * Sets the value of the window's {@code onmessage} property.
1263      * @param onmessage the value of the window's {@code onmessage} property
1264      */
1265     @JsxSetter
1266     public void setOnmessage(final Object onmessage) {
1267         setHandlerForJavaScript(Event.TYPE_MESSAGE, onmessage);
1268     }
1269 
1270     /**
1271      * Triggers the {@code onerror} handler, if one has been set.
1272      * @param e the error that needs to be reported
1273      */
1274     public void triggerOnError(final ScriptException e) {
1275         final Object o = getOnerror();
1276         if (o instanceof Function) {
1277             final Function f = (Function) o;
1278             final String msg = e.getMessage();
1279             final String url = e.getPage().getUrl().toExternalForm();
1280             final int line = e.getFailingLineNumber();
1281 
1282             final int column = e.getFailingColumnNumber();
1283             final Object[] args = new Object[] {msg, url, Integer.valueOf(line), Integer.valueOf(column), e};
1284             f.call(Context.getCurrentContext(), this, this, args);
1285         }
1286     }
1287 
1288     private void setHandlerForJavaScript(final String eventName, final Object handler) {
1289         if (handler == null || handler instanceof Function) {
1290             getEventListenersContainer().setEventHandler(eventName, handler);
1291         }
1292         // Otherwise, fail silently.
1293     }
1294 
1295     /**
1296      * {@inheritDoc}
1297      */
1298     @Override
1299     public Object call(final Context cx, final Scriptable scope, final Scriptable thisObj, final Object[] args) {
1300         throw Context.reportRuntimeError("Window is not a function.");
1301     }
1302 
1303     /**
1304      * {@inheritDoc}
1305      */
1306     @Override
1307     public Scriptable construct(final Context cx, final Scriptable scope, final Object[] args) {
1308         throw Context.reportRuntimeError("Window is not a function.");
1309     }
1310 
1311     /**
1312      * To be called when the property detection fails in normal scenarios.
1313      *
1314      * @param name the name
1315      * @return the found object, or {@link Scriptable#NOT_FOUND}
1316      */
1317     public Object getWithFallback(final String name) {
1318         Object result = NOT_FOUND;
1319 
1320         final DomNode domNode = getDomNodeOrNull();
1321         if (domNode != null) {
1322 
1323             // May be attempting to retrieve a frame by name.
1324             final HtmlPage page = (HtmlPage) domNode.getPage();
1325             result = getFrameWindowByName(page, name);
1326 
1327             if (result == NOT_FOUND) {
1328                 result = getElementsByName(page, name);
1329 
1330                 if (result == NOT_FOUND) {
1331                     // May be attempting to retrieve element by ID (try map-backed operation again instead of XPath).
1332                     try {
1333                         final HtmlElement htmlElement = page.getHtmlElementById(name);
1334                         if (getBrowserVersion().hasFeature(JS_WINDOW_FRAME_BY_ID_RETURNS_WINDOW)
1335                                 && htmlElement instanceof HtmlFrame) {
1336                             final HtmlFrame frame = (HtmlFrame) htmlElement;
1337                             result = getScriptableFor(frame.getEnclosedWindow());
1338                         }
1339                         else {
1340                             result = getScriptableFor(htmlElement);
1341                         }
1342                     }
1343                     catch (final ElementNotFoundException e) {
1344                         result = NOT_FOUND;
1345                     }
1346                 }
1347             }
1348 
1349             if (result instanceof Window) {
1350                 final WebWindow webWindow = ((Window) result).getWebWindow();
1351                 result = getProxy(webWindow);
1352             }
1353         }
1354 
1355         return result;
1356     }
1357 
1358     /**
1359      * {@inheritDoc}
1360      */
1361     @Override
1362     public Object get(final int index, final Scriptable start) {
1363         if (getWebWindow() == null) {
1364             return Undefined.instance;
1365         }
1366 
1367         final HTMLCollection frames = getFrames();
1368         if (index < 0 || index >= frames.getLength()) {
1369             return Undefined.instance;
1370         }
1371         return frames.item(Integer.valueOf(index));
1372     }
1373 
1374     private static Object getFrameWindowByName(final HtmlPage page, final String name) {
1375         try {
1376             return page.getFrameByName(name).getScriptableObject();
1377         }
1378         catch (final ElementNotFoundException e) {
1379             return NOT_FOUND;
1380         }
1381     }
1382 
1383     private Object getElementsByName(final HtmlPage page, final String name) {
1384 
1385         // May be attempting to retrieve element(s) by name. IMPORTANT: We're using map-backed operations
1386         // like getHtmlElementsByName() and getHtmlElementById() as much as possible, so as to avoid XPath
1387         // overhead. We only use an XPath-based operation when we have to (where there is more than one
1388         // matching element). This optimization appears to improve performance in certain situations by ~15%
1389         // vs using XPath-based operations throughout.
1390         final List<DomElement> elements = page.getElementsByName(name);
1391 
1392         final boolean includeFormFields = getBrowserVersion().hasFeature(JS_WINDOW_FORMFIELDS_ACCESSIBLE_BY_NAME);
1393         final Filter filter = new Filter(includeFormFields);
1394 
1395         final Iterator<DomElement> it = elements.iterator();
1396         while (it.hasNext()) {
1397             if (!filter.matches(it.next())) {
1398                 it.remove();
1399             }
1400         }
1401 
1402         if (elements.isEmpty()) {
1403             return NOT_FOUND;
1404         }
1405 
1406         if (elements.size() == 1) {
1407             return getScriptableFor(elements.get(0));
1408         }
1409 
1410         // Null must be changed to '' for proper collection initialization.
1411         final String expElementName = "null".equals(name) ? "" : name;
1412 
1413         return new HTMLCollection(page, true) {
1414             @Override
1415             protected List<DomNode> computeElements() {
1416                 final List<DomElement> expElements = page.getElementsByName(expElementName);
1417                 final List<DomNode> result = new ArrayList<>(expElements.size());
1418 
1419                 for (DomElement domElement : expElements) {
1420                     if (filter.matches(domElement)) {
1421                         result.add(domElement);
1422                     }
1423                 }
1424                 return result;
1425             }
1426 
1427             @Override
1428             protected EffectOnCache getEffectOnCache(final HtmlAttributeChangeEvent event) {
1429                 if ("name".equals(event.getName())) {
1430                     return EffectOnCache.RESET;
1431                 }
1432                 return EffectOnCache.NONE;
1433             }
1434         };
1435     }
1436 
1437     /**
1438      * Returns the proxy for the specified window.
1439      * @param w the window whose proxy is to be returned
1440      * @return the proxy for the specified window
1441      */
1442     public static WindowProxy getProxy(final WebWindow w) {
1443         return ((Window) w.getScriptableObject()).windowProxy_;
1444     }
1445 
1446     /**
1447      * Returns the text from the status line.
1448      * @return the status line text
1449      */
1450     @JsxGetter
1451     public String getStatus() {
1452         return status_;
1453     }
1454 
1455     /**
1456      * Sets the text from the status line.
1457      * @param message the status line text
1458      */
1459     @JsxSetter
1460     public void setStatus(final String message) {
1461         status_ = message;
1462 
1463         final StatusHandler statusHandler = webWindow_.getWebClient().getStatusHandler();
1464         if (statusHandler != null) {
1465             statusHandler.statusMessageChanged(webWindow_.getEnclosedPage(), message);
1466         }
1467     }
1468 
1469     /**
1470      * Sets a chunk of JavaScript to be invoked each time a specified number of milliseconds has elapsed.
1471      *
1472      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536749.aspx">MSDN documentation</a>
1473      * @param code specifies the function pointer or string that indicates the code to be executed
1474      *        when the specified interval has elapsed
1475      * @param timeout specifies the number of milliseconds
1476      * @param language specifies language
1477      * @return the id of the created interval
1478      */
1479     @JsxFunction
1480     public int setInterval(final Object code, int timeout, final Object language) {
1481         if (timeout < MIN_TIMER_DELAY) {
1482             timeout = MIN_TIMER_DELAY;
1483         }
1484         final int id;
1485         final WebWindow w = getWebWindow();
1486         final Page page = (Page) getDomNodeOrNull();
1487         final String description = "window.setInterval(" + timeout + ")";
1488         if (code == null) {
1489             throw Context.reportRuntimeError("Function not provided.");
1490         }
1491         else if (code instanceof String) {
1492             final String s = (String) code;
1493             final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
1494                 createJavaScriptJob(timeout, Integer.valueOf(timeout), description, w, s);
1495             id = w.getJobManager().addJob(job, page);
1496         }
1497         else if (code instanceof Function) {
1498             final Function f = (Function) code;
1499             final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
1500                 createJavaScriptJob(timeout, Integer.valueOf(timeout), description, w, f);
1501             id = w.getJobManager().addJob(job, page);
1502         }
1503         else {
1504             throw Context.reportRuntimeError("Unknown type for function.");
1505         }
1506         return id;
1507     }
1508 
1509     /**
1510      * Cancels the interval previously started using the {@link #setInterval(Object, int, Object)} method.
1511      * Current implementation does nothing.
1512      * @param intervalID specifies the interval to cancel as returned by the
1513      *        {@link #setInterval(Object, int, Object)} method
1514      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536353.aspx">MSDN documentation</a>
1515      */
1516     @JsxFunction
1517     public void clearInterval(final int intervalID) {
1518         if (LOG.isDebugEnabled()) {
1519             LOG.debug("clearInterval(" + intervalID + ")");
1520         }
1521         getWebWindow().getJobManager().removeJob(intervalID);
1522     }
1523 
1524     /**
1525      * Returns the {@code innerWidth}.
1526      * @return the {@code innerWidth}
1527      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref28.html">Mozilla doc</a>
1528      */
1529     @JsxGetter
1530     public int getInnerWidth() {
1531         return getWebWindow().getInnerWidth();
1532     }
1533 
1534     /**
1535      * Returns the {@code outerWidth}.
1536      * @return the {@code outerWidth}
1537      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref79.html">Mozilla doc</a>
1538      */
1539     @JsxGetter
1540     public int getOuterWidth() {
1541         return getWebWindow().getOuterWidth();
1542     }
1543 
1544     /**
1545      * Returns the {@code innerHeight}.
1546      * @return the {@code innerHeight}
1547      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref27.html">Mozilla doc</a>
1548      */
1549     @JsxGetter
1550     public int getInnerHeight() {
1551         return getWebWindow().getInnerHeight();
1552     }
1553 
1554     /**
1555      * Returns the {@code outerHeight}.
1556      * @return the {@code outerHeight}
1557      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref78.html">Mozilla doc</a>
1558      */
1559     @JsxGetter
1560     public int getOuterHeight() {
1561         return getWebWindow().getOuterHeight();
1562     }
1563 
1564     /**
1565      * Prints the current page. The current implementation does nothing.
1566      * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref85.html">
1567      * Mozilla documentation</a>
1568      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536672.aspx">MSDN documentation</a>
1569      */
1570     @JsxFunction
1571     public void print() {
1572         if (LOG.isDebugEnabled()) {
1573             LOG.debug("window.print() not implemented");
1574         }
1575     }
1576 
1577     /**
1578      * Does nothing special anymore.
1579      * @param type the type of events to capture
1580      * @see HTMLDocument#captureEvents(String)
1581      */
1582     @JsxFunction
1583     public void captureEvents(final String type) {
1584         // Empty.
1585     }
1586 
1587     /**
1588      * Does nothing special anymore.
1589      * @param type the type of events to capture
1590      * @see HTMLDocument#releaseEvents(String)
1591      */
1592     @JsxFunction
1593     public void releaseEvents(final String type) {
1594         // Empty.
1595     }
1596 
1597     /**
1598      * An undocumented IE function.
1599      */
1600     @JsxFunction(IE)
1601     public void CollectGarbage() {
1602         // Empty.
1603     }
1604 
1605     /**
1606      * Returns computed style of the element. Computed style represents the final computed values
1607      * of all CSS properties for the element. This method's return value is of the same type as
1608      * that of <tt>element.style</tt>, but the value returned by this method is read-only.
1609      *
1610      * @param element the element
1611      * @param pseudoElement a string specifying the pseudo-element to match (may be {@code null})
1612      * @return the computed style
1613      */
1614     @JsxFunction
1615     public CSS2Properties getComputedStyle(final Object element, final String pseudoElement) {
1616         if (!(element instanceof Element)) {
1617             throw ScriptRuntime.typeError("parameter 1 is not of type 'Element'");
1618         }
1619         final Element e = (Element) element;
1620         synchronized (computedStyles_) {
1621             final Map<String, CSS2Properties> elementMap = computedStyles_.get(e);
1622             if (elementMap != null) {
1623                 final CSS2Properties style = elementMap.get(pseudoElement);
1624                 if (style != null) {
1625                     return style;
1626                 }
1627             }
1628         }
1629 
1630         final CSSStyleDeclaration original = e.getStyle();
1631         final CSS2Properties style = new CSS2Properties(original);
1632 
1633         if (e.getOwnerDocument() instanceof HTMLDocument) {
1634             final StyleSheetList sheets = ((HTMLDocument) e.getOwnerDocument()).getStyleSheets();
1635             final boolean trace = LOG.isTraceEnabled();
1636             for (int i = 0; i < sheets.getLength(); i++) {
1637                 final CSSStyleSheet sheet = (CSSStyleSheet) sheets.item(i);
1638                 if (sheet.isActive() && sheet.isEnabled()) {
1639                     if (trace) {
1640                         LOG.trace("modifyIfNecessary: " + sheet + ", " + style + ", " + e);
1641                     }
1642                     sheet.modifyIfNecessary(style, e, pseudoElement);
1643                 }
1644             }
1645 
1646             synchronized (computedStyles_) {
1647                 Map<String, CSS2Properties> elementMap = computedStyles_.get(element);
1648                 if (elementMap == null) {
1649                     elementMap = new WeakHashMap<>();
1650                     computedStyles_.put(e, elementMap);
1651                 }
1652                 elementMap.put(pseudoElement, style);
1653             }
1654         }
1655         return style;
1656     }
1657 
1658     /**
1659      * Returns the current selection.
1660      * @return the current selection
1661      */
1662     @JsxFunction
1663     public Selection getSelection() {
1664         final WebWindow webWindow = getWebWindow();
1665         // return null if the window is in a frame that is not displayed
1666         if (webWindow instanceof FrameWindow) {
1667             final FrameWindow frameWindow = (FrameWindow) webWindow;
1668             if (getBrowserVersion().hasFeature(JS_WINDOW_SELECTION_NULL_IF_INVISIBLE)
1669                     && !frameWindow.getFrameElement().isDisplayed()) {
1670                 return null;
1671             }
1672         }
1673         return getSelectionImpl();
1674     }
1675 
1676     /**
1677      * Returns the current selection.
1678      * @return the current selection
1679      */
1680     public Selection getSelectionImpl() {
1681         if (selection_ == null) {
1682             selection_ = new Selection();
1683             selection_.setParentScope(this);
1684             selection_.setPrototype(getPrototype(selection_.getClass()));
1685         }
1686         return selection_;
1687     }
1688 
1689     /**
1690      * Creates a modal dialog box that displays the specified HTML document.
1691      * @param url the URL of the document to load and display
1692      * @param arguments object to be made available via <tt>window.dialogArguments</tt> in the dialog window
1693      * @param features string that specifies the window ornaments for the dialog window
1694      * @return the value of the {@code returnValue} property as set by the modal dialog's window
1695      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536759.aspx">MSDN Documentation</a>
1696      * @see <a href="https://developer.mozilla.org/en/DOM/window.showModalDialog">Mozilla Documentation</a>
1697      */
1698     @JsxFunction({IE, FF})
1699     public Object showModalDialog(final String url, final Object arguments, final String features) {
1700         final WebWindow webWindow = getWebWindow();
1701         final WebClient client = webWindow.getWebClient();
1702         try {
1703             final URL completeUrl = ((HtmlPage) getDomNodeOrDie()).getFullyQualifiedUrl(url);
1704             final DialogWindow dialog = client.openDialogWindow(completeUrl, webWindow, arguments);
1705             // TODO: Theoretically, we shouldn't return until the dialog window has been close()'ed...
1706             // But we have to return so that the window can be close()'ed...
1707             // Maybe we can use Rhino's continuation support to save state and restart when
1708             // the dialog window is close()'ed? Would only work in interpreted mode, though.
1709             final ScriptableObject jsDialog = dialog.getScriptableObject();
1710             return jsDialog.get("returnValue", jsDialog);
1711         }
1712         catch (final IOException e) {
1713             throw Context.throwAsScriptRuntimeEx(e);
1714         }
1715     }
1716 
1717     /**
1718      * Creates a modeless dialog box that displays the specified HTML document.
1719      * @param url the URL of the document to load and display
1720      * @param arguments object to be made available via <tt>window.dialogArguments</tt> in the dialog window
1721      * @param features string that specifies the window ornaments for the dialog window
1722      * @return a reference to the new window object created for the modeless dialog
1723      * @see <a href="http://msdn.microsoft.com/en-us/library/ms536761.aspx">MSDN Documentation</a>
1724      */
1725     @JsxFunction(IE)
1726     public Object showModelessDialog(final String url, final Object arguments, final String features) {
1727         final WebWindow webWindow = getWebWindow();
1728         final WebClient client = webWindow.getWebClient();
1729         try {
1730             final URL completeUrl = ((HtmlPage) getDomNodeOrDie()).getFullyQualifiedUrl(url);
1731             final DialogWindow dialog = client.openDialogWindow(completeUrl, webWindow, arguments);
1732             final Window jsDialog = (Window) dialog.getScriptableObject();
1733             return jsDialog;
1734         }
1735         catch (final IOException e) {
1736             throw Context.throwAsScriptRuntimeEx(e);
1737         }
1738     }
1739 
1740     /**
1741      * Gets the {@code controllers}. The result doesn't currently matter but it is important to return an
1742      * object as some JavaScript libraries check it.
1743      * @see <a href="https://developer.mozilla.org/En/DOM/Window.controllers">Mozilla documentation</a>
1744      * @return some object
1745      */
1746     @JsxGetter(FF)
1747     public Object getControllers() {
1748         return controllers_;
1749     }
1750 
1751     /**
1752      * Sets the {@code controllers}.
1753      * @param value the new value
1754      */
1755     @JsxSetter(FF)
1756     public void setControllers(final Object value) {
1757         controllers_ = value;
1758     }
1759 
1760     /**
1761      * Returns the value of {@code mozInnerScreenX} property.
1762      * @return the value of {@code mozInnerScreenX} property
1763      */
1764     @JsxGetter(FF)
1765     public int getMozInnerScreenX() {
1766         return 11;
1767     }
1768 
1769     /**
1770      * Returns the value of {@code mozInnerScreenY} property.
1771      * @return the value of {@code mozInnerScreenY} property
1772      */
1773     @JsxGetter(FF)
1774     public int getMozInnerScreenY() {
1775         return 91;
1776     }
1777 
1778     /**
1779      * Returns the value of {@code mozPaintCount} property.
1780      * @return the value of {@code mozPaintCount} property
1781      */
1782     @JsxGetter(FF)
1783     public int getMozPaintCount() {
1784         return 0;
1785     }
1786 
1787     /** Definition of special cases for the smart DomHtmlAttributeChangeListenerImpl */
1788     private static final Set<String> ATTRIBUTES_AFFECTING_PARENT = new HashSet<>(Arrays.asList(
1789             "style",
1790             "class",
1791             "height",
1792             "width"));
1793 
1794     private static final class Filter {
1795         private final boolean includeFormFields_;
1796 
1797         private Filter(final boolean includeFormFields) {
1798             includeFormFields_ = includeFormFields;
1799         }
1800 
1801         private boolean matches(final Object object) {
1802             if (object instanceof HtmlEmbed
1803                 || object instanceof HtmlForm
1804                 || object instanceof HtmlImage
1805                 || object instanceof HtmlObject) {
1806                 return true;
1807             }
1808             if (includeFormFields_ && (
1809                     object instanceof HtmlAnchor
1810                     || object instanceof HtmlButton
1811                     || object instanceof HtmlInput
1812                     || object instanceof HtmlMap
1813                     || object instanceof HtmlSelect
1814                     || object instanceof HtmlTextArea)) {
1815                 return true;
1816             }
1817             return false;
1818         }
1819     }
1820 
1821     /**
1822      * Clears the computed styles.
1823      */
1824     public void clearComputedStyles() {
1825         synchronized (computedStyles_) {
1826             computedStyles_.clear();
1827         }
1828     }
1829 
1830     /**
1831      * Clears the computed styles for a specific {@link Element}.
1832      * @param element the element to clear its cache
1833      */
1834     public void clearComputedStyles(final Element element) {
1835         synchronized (computedStyles_) {
1836             computedStyles_.remove(element);
1837         }
1838     }
1839 
1840     /**
1841      * <p>Listens for changes anywhere in the document and evicts cached computed styles whenever something relevant
1842      * changes. Note that the very lazy way of doing this (completely clearing the cache every time something happens)
1843      * results in very meager performance gains. In order to get good (but still correct) performance, we need to be
1844      * a little smarter.</p>
1845      *
1846      * <p>CSS 2.1 has the following <a href="http://www.w3.org/TR/CSS21/selector.html">selector types</a> (where "SN" is
1847      * shorthand for "the selected node"):</p>
1848      *
1849      * <ol>
1850      *   <li><em>Universal</em> (i.e. "*"): Affected by the removal of SN from the document.</li>
1851      *   <li><em>Type</em> (i.e. "div"): Affected by the removal of SN from the document.</li>
1852      *   <li><em>Descendant</em> (i.e. "div span"): Affected by changes to SN or to any of its ancestors.</li>
1853      *   <li><em>Child</em> (i.e. "div &gt; span"): Affected by changes to SN or to its parent.</li>
1854      *   <li><em>Adjacent Sibling</em> (i.e. "table + p"): Affected by changes to SN or its previous sibling.</li>
1855      *   <li><em>Attribute</em> (i.e. "div.up, div[class~=up]"): Affected by changes to an attribute of SN.</li>
1856      *   <li><em>ID</em> (i.e. "#header): Affected by changes to the <tt>id</tt> attribute of SN.</li>
1857      *   <li><em>Pseudo-Elements and Pseudo-Classes</em> (i.e. "p:first-child"): Affected by changes to parent.</li>
1858      * </ol>
1859      *
1860      * <p>Together, these rules dictate that the smart (but still lazy) way of removing elements from the computed style
1861      * cache is as follows -- whenever a node changes in any way, the cache needs to be cleared of styles for nodes
1862      * which:</p>
1863      *
1864      * <ul>
1865      *   <li>are actually the same node as the node that changed</li>
1866      *   <li>are siblings of the node that changed</li>
1867      *   <li>are descendants of the node that changed</li>
1868      * </ul>
1869      *
1870      * <p>Additionally, whenever a <tt>style</tt> node or a <tt>link</tt> node with <tt>rel=stylesheet</tt> is added or
1871      * removed, all elements should be removed from the computed style cache.</p>
1872      */
1873     private class DomHtmlAttributeChangeListenerImpl implements DomChangeListener, HtmlAttributeChangeListener {
1874 
1875         /**
1876          * {@inheritDoc}
1877          */
1878         @Override
1879         public void nodeAdded(final DomChangeEvent event) {
1880             nodeChanged(event.getChangedNode(), null);
1881         }
1882 
1883         /**
1884          * {@inheritDoc}
1885          */
1886         @Override
1887         public void nodeDeleted(final DomChangeEvent event) {
1888             nodeChanged(event.getChangedNode(), null);
1889         }
1890 
1891         /**
1892          * {@inheritDoc}
1893          */
1894         @Override
1895         public void attributeAdded(final HtmlAttributeChangeEvent event) {
1896             nodeChanged(event.getHtmlElement(), event.getName());
1897         }
1898 
1899         /**
1900          * {@inheritDoc}
1901          */
1902         @Override
1903         public void attributeRemoved(final HtmlAttributeChangeEvent event) {
1904             nodeChanged(event.getHtmlElement(), event.getName());
1905         }
1906 
1907         /**
1908          * {@inheritDoc}
1909          */
1910         @Override
1911         public void attributeReplaced(final HtmlAttributeChangeEvent event) {
1912             nodeChanged(event.getHtmlElement(), event.getName());
1913         }
1914 
1915         private void nodeChanged(final DomNode changed, final String attribName) {
1916             // If a stylesheet was changed, all of our calculations could be off; clear the cache.
1917             if (changed instanceof HtmlStyle) {
1918                 clearComputedStyles();
1919                 return;
1920             }
1921             if (changed instanceof HtmlLink) {
1922                 final String rel = ((HtmlLink) changed).getRelAttribute().toLowerCase(Locale.ROOT);
1923                 if ("stylesheet".equals(rel)) {
1924                     clearComputedStyles();
1925                     return;
1926                 }
1927             }
1928             // Apparently it wasn't a stylesheet that changed; be semi-smart about what we evict and when.
1929             synchronized (computedStyles_) {
1930                 final boolean clearParents = ATTRIBUTES_AFFECTING_PARENT.contains(attribName);
1931                 for (final Iterator<Map.Entry<Element, Map<String, CSS2Properties>>> i
1932                         = computedStyles_.entrySet().iterator(); i.hasNext();) {
1933                     final Map.Entry<Element, Map<String, CSS2Properties>> entry = i.next();
1934                     final DomNode node = entry.getKey().getDomNodeOrDie();
1935                     if (changed == node
1936                         || changed.getParentNode() == node.getParentNode()
1937                         || changed.isAncestorOf(node)
1938                         || clearParents && node.isAncestorOf(changed)) {
1939                         i.remove();
1940                     }
1941                 }
1942             }
1943         }
1944     }
1945 
1946     /**
1947      * Gets the name of the scripting engine.
1948      * @see <a href="http://msdn.microsoft.com/en-us/library/efy5bay1.aspx">MSDN doc</a>
1949      * @return "JScript"
1950      */
1951     @JsxFunction(IE)
1952     public String ScriptEngine() {
1953         return "JScript";
1954     }
1955 
1956     /**
1957      * Gets the build version of the scripting engine.
1958      * @see <a href="http://msdn.microsoft.com/en-us/library/yftk84kt.aspx">MSDN doc</a>
1959      * @return the build version
1960      */
1961     @JsxFunction(IE)
1962     public int ScriptEngineBuildVersion() {
1963         return 12345;
1964     }
1965 
1966     /**
1967      * Gets the major version of the scripting engine.
1968      * @see <a href="http://msdn.microsoft.com/en-us/library/x7cbaet3.aspx">MSDN doc</a>
1969      * @return the major version
1970      */
1971     @JsxFunction(IE)
1972     public int ScriptEngineMajorVersion() {
1973         return getBrowserVersion().getBrowserVersionNumeric();
1974     }
1975 
1976     /**
1977      * Gets the minor version of the scripting engine.
1978      * @see <a href="http://msdn.microsoft.com/en-us/library/wzaz8hhz.aspx">MSDN doc</a>
1979      * @return the minor version
1980      */
1981     @JsxFunction(IE)
1982     public int ScriptEngineMinorVersion() {
1983         return 0;
1984     }
1985 
1986     /**
1987      * Should implement the stop() function on the window object.
1988      * (currently empty implementation)
1989      * @see <a href="https://developer.mozilla.org/en/DOM/window.stop">window.stop</a>
1990      */
1991     @JsxFunction({CHROME, FF})
1992     public void stop() {
1993         //empty
1994     }
1995 
1996     /**
1997      * Returns the value of {@code pageXOffset} property.
1998      * @return the value of {@code pageXOffset} property
1999      */
2000     @JsxGetter
2001     public int getPageXOffset() {
2002         return 0;
2003     }
2004 
2005     /**
2006      * Returns the value of {@code pageYOffset} property.
2007      * @return the value of {@code pageYOffset} property
2008      */
2009     @JsxGetter
2010     public int getPageYOffset() {
2011         return 0;
2012     }
2013 
2014     /**
2015      * Returns the value of {@code scrollX} property.
2016      * @return the value of {@code scrollX} property
2017      */
2018     @JsxGetter({CHROME, FF})
2019     public int getScrollX() {
2020         return 0;
2021     }
2022 
2023     /**
2024      * Returns the value of {@code scrollY} property.
2025      * @return the value of {@code scrollY} property
2026      */
2027     @JsxGetter({CHROME, FF})
2028     public int getScrollY() {
2029         return 0;
2030     }
2031 
2032     /**
2033      * Returns the value of {@code netscape} property.
2034      * @return the value of {@code netscape} property
2035      */
2036     @JsxGetter(FF)
2037     public Netscape getNetscape() {
2038         return new Netscape(this);
2039     }
2040 
2041     /**
2042      * {@inheritDoc}
2043      * Used to allow re-declaration of constants (eg: "var undefined;").
2044      */
2045     @Override
2046     public boolean isConst(final String name) {
2047         if ("undefined".equals(name) || "Infinity".equals(name) || "NaN".equals(name)) {
2048             return false;
2049         }
2050 
2051         return super.isConst(name);
2052     }
2053 
2054     /**
2055      * {@inheritDoc}
2056      */
2057     @Override
2058     public boolean dispatchEvent(final Event event) {
2059         event.setTarget(this);
2060         final ScriptResult result = fireEvent(event);
2061         return !event.isAborted(result);
2062     }
2063 
2064     /**
2065      * Getter for the {@code onchange} event handler.
2066      * @return the handler
2067      */
2068     @JsxGetter
2069     public Object getOnchange() {
2070         return getEventHandler(Event.TYPE_CHANGE);
2071     }
2072 
2073     /**
2074      * Setter for the {@code onchange} event handler.
2075      * @param onchange the handler
2076      */
2077     @JsxSetter
2078     public void setOnchange(final Object onchange) {
2079         setHandlerForJavaScript(Event.TYPE_CHANGE, onchange);
2080     }
2081 
2082     /**
2083      * Getter for the {@code onsubmit} event handler.
2084      * @return the handler
2085      */
2086     @JsxGetter
2087     public Object getOnsubmit() {
2088         return getEventHandler(Event.TYPE_SUBMIT);
2089     }
2090 
2091     /**
2092      * Setter for the {@code onsubmit} event handler.
2093      * @param onsubmit the handler
2094      */
2095     @JsxSetter
2096     public void setOnsubmit(final Object onsubmit) {
2097         setHandlerForJavaScript(Event.TYPE_SUBMIT, onsubmit);
2098     }
2099 
2100     /**
2101      * Posts a message.
2102      * @param message the object passed to the window
2103      * @param targetOrigin the origin this window must be for the event to be dispatched
2104      * @param transfer an optional sequence of Transferable objects
2105      * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage">MDN documentation</a>
2106      */
2107     @JsxFunction
2108     public void postMessage(final String message, final String targetOrigin, final Object transfer) {
2109         final URL currentURL = getWebWindow().getEnclosedPage().getUrl();
2110 
2111         if (!"*".equals(targetOrigin) && !"/".equals(targetOrigin)) {
2112             URL targetURL = null;
2113             try {
2114                 targetURL = new URL(targetOrigin);
2115             }
2116             catch (final Exception e) {
2117                 throw Context.throwAsScriptRuntimeEx(
2118                         new Exception(
2119                                 "SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin '"
2120                                 + targetOrigin + "' was specified (reason: " + e.getMessage() + "."));
2121             }
2122 
2123             if (getPort(targetURL) != getPort(currentURL)) {
2124                 return;
2125             }
2126             if (!targetURL.getHost().equals(currentURL.getHost())) {
2127                 return;
2128             }
2129             if (!targetURL.getProtocol().equals(currentURL.getProtocol())) {
2130                 return;
2131             }
2132         }
2133         final MessageEvent event = new MessageEvent();
2134         final String origin = currentURL.getProtocol() + "://" + currentURL.getHost() + ':' + currentURL.getPort();
2135         event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin, "", this, transfer);
2136         event.setParentScope(this);
2137         event.setPrototype(getPrototype(event.getClass()));
2138 
2139         final JavaScriptEngine jsEngine
2140             = (JavaScriptEngine) getWebWindow().getWebClient().getJavaScriptEngine();
2141         final PostponedAction action = new PostponedAction(getDomNodeOrDie().getPage()) {
2142             @Override
2143             public void execute() throws Exception {
2144                 final ContextAction contextAction = new ContextAction() {
2145                     @Override
2146                     public Object run(final Context cx) {
2147                         return dispatchEvent(event);
2148                     }
2149                 };
2150 
2151                 final ContextFactory cf = jsEngine.getContextFactory();
2152                 cf.call(contextAction);
2153             }
2154         };
2155         jsEngine.addPostponedAction(action);
2156     }
2157 
2158     /**
2159      * Returns the port of the specified URL.
2160      * @param url the URL
2161      * @return the port
2162      */
2163     public static int getPort(final URL url) {
2164         int port = url.getPort();
2165         if (port == -1) {
2166             if ("http".equals(url.getProtocol())) {
2167                 port = 80;
2168             }
2169             else {
2170                 port = 443;
2171             }
2172         }
2173         return port;
2174     }
2175 
2176     /**
2177      * Returns the {@code performance} property.
2178      * @return the {@code performance} property
2179      */
2180     @JsxGetter
2181     public Performance getPerformance() {
2182         final Performance performance = new Performance();
2183         performance.setParentScope(this);
2184         performance.setPrototype(getPrototype(performance.getClass()));
2185         return performance;
2186     }
2187 
2188     /**
2189      * Returns the {@code devicePixelRatio} property.
2190      * @return the {@code devicePixelRatio} property
2191      */
2192     @JsxGetter
2193     public int getDevicePixelRatio() {
2194         return 1;
2195     }
2196 
2197     /**
2198      * Returns the {@code styleMedia} property.
2199      * @return the {@code styleMedia} property
2200      */
2201     @JsxGetter({CHROME, IE})
2202     public StyleMedia getStyleMedia() {
2203         final StyleMedia styleMedia = new StyleMedia();
2204         styleMedia.setParentScope(this);
2205         styleMedia.setPrototype(getPrototype(styleMedia.getClass()));
2206         return styleMedia;
2207     }
2208 
2209     /**
2210      * Returns a new MediaQueryList object representing the parsed results of the specified media query string.
2211      *
2212      * @param mediaQueryString the media query
2213      * @return a new MediaQueryList object
2214      */
2215     @JsxFunction
2216     public MediaQueryList matchMedia(final String mediaQueryString) {
2217         final MediaQueryList mediaQueryList = new MediaQueryList(mediaQueryString);
2218         mediaQueryList.setParentScope(this);
2219         mediaQueryList.setPrototype(getPrototype(mediaQueryList.getClass()));
2220         return mediaQueryList;
2221     }
2222 
2223     /**
2224      * Stub only at the moment.
2225      * @param search the text string for which to search
2226      * @param caseSensitive if true, specifies a case-sensitive search
2227      * @param backwards if true, specifies a backward search
2228      * @param wrapAround if true, specifies a wrap around search
2229      * @param wholeWord if true, specifies a whole word search
2230      * @param searchInFrames if true, specifies a search in frames
2231      * @param showDialog if true, specifies a show Dialog.
2232      * @return false
2233      */
2234     @JsxFunction({CHROME, FF})
2235     public boolean find(final String search, final boolean caseSensitive,
2236             final boolean backwards, final boolean wrapAround,
2237             final boolean wholeWord, final boolean searchInFrames, final boolean showDialog) {
2238         return false;
2239     }
2240 
2241     /**
2242      * Returns the {@code speechSynthesis} property.
2243      * @return the {@code speechSynthesis} property
2244      */
2245     @JsxGetter(CHROME)
2246     public SpeechSynthesis getSpeechSynthesis() {
2247         final SpeechSynthesis speechSynthesis = new SpeechSynthesis();
2248         speechSynthesis.setParentScope(this);
2249         speechSynthesis.setPrototype(getPrototype(speechSynthesis.getClass()));
2250         return speechSynthesis;
2251     }
2252 
2253     /**
2254      * Returns the {@code offscreenBuffering} property.
2255      * @return the {@code offscreenBuffering} property
2256      */
2257     @JsxGetter({CHROME, IE})
2258     public Object getOffscreenBuffering() {
2259         if (getBrowserVersion().hasFeature(JS_WINDOW_FRAMES_ACCESSIBLE_BY_ID)) {
2260             return "auto";
2261         }
2262         return true;
2263     }
2264 
2265     /**
2266      * Returns the {@code crypto} property.
2267      * @return the {@code crypto} property
2268      */
2269     @JsxGetter({CHROME, FF})
2270     public Crypto getCrypto() {
2271         if (crypto_ == null) {
2272             crypto_ = new Crypto(this);
2273         }
2274         return crypto_;
2275     }
2276 
2277     /**
2278      * {@inheritDoc}
2279      */
2280     @Override
2281     public void close() {
2282         Symbol.remove(this);
2283     }
2284 
2285     /**
2286      * Does nothing.
2287      * @param parent the new parent scope
2288      */
2289     @Override
2290     public void setParentScope(final Scriptable parent) {
2291         // nothing as the window is the top level scope and its parent scope should stay null
2292     }
2293 
2294     /**
2295      * Returns the {@code onfocusin} event handler.
2296      * @return the {@code onfocusin} event handler
2297      */
2298     @JsxGetter(IE)
2299     public Function getOnfocusin() {
2300         return getEventHandler("focusin");
2301     }
2302 
2303     /**
2304      * Sets the {@code onfocusin} event handler.
2305      * @param onfocusin the {@code onfocusin} event handler
2306      */
2307     @JsxSetter(IE)
2308     public void setOnfocusin(final Object onfocusin) {
2309         setHandlerForJavaScript("focusin", onfocusin);
2310     }
2311 
2312     /**
2313      * Returns the {@code onfocus} event handler.
2314      * @return the {@code onfocus} event handler
2315      */
2316     @JsxGetter
2317     public Function getOnfocus() {
2318         return getEventHandler("focus");
2319     }
2320 
2321     /**
2322      * Sets the {@code onfocus} event handler.
2323      * @param onfocus the {@code onfocus} event handler
2324      */
2325     @JsxSetter
2326     public void setOnfocus(final Object onfocus) {
2327         setHandlerForJavaScript("focus", onfocus);
2328     }
2329 
2330     /**
2331      * Returns the {@code ondragend} event handler.
2332      * @return the {@code ondragend} event handler
2333      */
2334     @JsxGetter
2335     public Function getOndragend() {
2336         return getEventHandler("dragend");
2337     }
2338 
2339     /**
2340      * Sets the {@code ondragend} event handler.
2341      * @param ondragend the {@code ondragend} event handler
2342      */
2343     @JsxSetter
2344     public void setOndragend(final Object ondragend) {
2345         setHandlerForJavaScript("dragend", ondragend);
2346     }
2347 
2348     /**
2349      * Returns the {@code oninvalid} event handler.
2350      * @return the {@code oninvalid} event handler
2351      */
2352     @JsxGetter({CHROME, FF})
2353     public Function getOninvalid() {
2354         return getEventHandler("invalid");
2355     }
2356 
2357     /**
2358      * Sets the {@code oninvalid} event handler.
2359      * @param oninvalid the {@code oninvalid} event handler
2360      */
2361     @JsxSetter({CHROME, FF})
2362     public void setOninvalid(final Object oninvalid) {
2363         setHandlerForJavaScript("invalid", oninvalid);
2364     }
2365 
2366     /**
2367      * Returns the {@code onpointerout} event handler.
2368      * @return the {@code onpointerout} event handler
2369      */
2370     @JsxGetter({CHROME, IE})
2371     public Function getOnpointerout() {
2372         return getEventHandler("pointerout");
2373     }
2374 
2375     /**
2376      * Sets the {@code onpointerout} event handler.
2377      * @param onpointerout the {@code onpointerout} event handler
2378      */
2379     @JsxSetter({CHROME, IE})
2380     public void setOnpointerout(final Object onpointerout) {
2381         setHandlerForJavaScript("pointerout", onpointerout);
2382     }
2383 
2384     /**
2385      * Returns the {@code onhelp} event handler.
2386      * @return the {@code onhelp} event handler
2387      */
2388     @JsxGetter(IE)
2389     public Function getOnhelp() {
2390         return getEventHandler("help");
2391     }
2392 
2393     /**
2394      * Sets the {@code onhelp} event handler.
2395      * @param onhelp the {@code onhelp} event handler
2396      */
2397     @JsxSetter(IE)
2398     public void setOnhelp(final Object onhelp) {
2399         setHandlerForJavaScript("help", onhelp);
2400     }
2401 
2402     /**
2403      * Returns the {@code onratechange} event handler.
2404      * @return the {@code onratechange} event handler
2405      */
2406     @JsxGetter
2407     public Function getOnratechange() {
2408         return getEventHandler("ratechange");
2409     }
2410 
2411     /**
2412      * Sets the {@code onratechange} event handler.
2413      * @param onratechange the {@code onratechange} event handler
2414      */
2415     @JsxSetter
2416     public void setOnratechange(final Object onratechange) {
2417         setHandlerForJavaScript("ratechange", onratechange);
2418     }
2419 
2420     /**
2421      * Returns the {@code onanimationiteration} event handler.
2422      * @return the {@code onanimationiteration} event handler
2423      */
2424     @JsxGetter({CHROME, FF52})
2425     public Function getOnanimationiteration() {
2426         return getEventHandler("animationiteration");
2427     }
2428 
2429     /**
2430      * Sets the {@code onanimationiteration} event handler.
2431      * @param onanimationiteration the {@code onanimationiteration} event handler
2432      */
2433     @JsxSetter({CHROME, FF52})
2434     public void setOnanimationiteration(final Object onanimationiteration) {
2435         setHandlerForJavaScript("animationiteration", onanimationiteration);
2436     }
2437 
2438     /**
2439      * Returns the {@code oncanplaythrough} event handler.
2440      * @return the {@code oncanplaythrough} event handler
2441      */
2442     @JsxGetter
2443     public Function getOncanplaythrough() {
2444         return getEventHandler("canplaythrough");
2445     }
2446 
2447     /**
2448      * Sets the {@code oncanplaythrough} event handler.
2449      * @param oncanplaythrough the {@code oncanplaythrough} event handler
2450      */
2451     @JsxSetter
2452     public void setOncanplaythrough(final Object oncanplaythrough) {
2453         setHandlerForJavaScript("canplaythrough", oncanplaythrough);
2454     }
2455 
2456     /**
2457      * Returns the {@code oncancel} event handler.
2458      * @return the {@code oncancel} event handler
2459      */
2460     @JsxGetter(CHROME)
2461     public Function getOncancel() {
2462         return getEventHandler("cancel");
2463     }
2464 
2465     /**
2466      * Sets the {@code oncancel} event handler.
2467      * @param oncancel the {@code oncancel} event handler
2468      */
2469     @JsxSetter(CHROME)
2470     public void setOncancel(final Object oncancel) {
2471         setHandlerForJavaScript("cancel", oncancel);
2472     }
2473 
2474     /**
2475      * Returns the {@code onpointerenter} event handler.
2476      * @return the {@code onpointerenter} event handler
2477      */
2478     @JsxGetter({CHROME, IE})
2479     public Function getOnpointerenter() {
2480         return getEventHandler("pointerenter");
2481     }
2482 
2483     /**
2484      * Sets the {@code onpointerenter} event handler.
2485      * @param onpointerenter the {@code onpointerenter} event handler
2486      */
2487     @JsxSetter({CHROME, IE})
2488     public void setOnpointerenter(final Object onpointerenter) {
2489         setHandlerForJavaScript("pointerenter", onpointerenter);
2490     }
2491 
2492     /**
2493      * Returns the {@code onselect} event handler.
2494      * @return the {@code onselect} event handler
2495      */
2496     @JsxGetter
2497     public Function getOnselect() {
2498         return getEventHandler("select");
2499     }
2500 
2501     /**
2502      * Sets the {@code onselect} event handler.
2503      * @param onselect the {@code onselect} event handler
2504      */
2505     @JsxSetter
2506     public void setOnselect(final Object onselect) {
2507         setHandlerForJavaScript("select", onselect);
2508     }
2509 
2510     /**
2511      * Returns the {@code onauxclick} event handler.
2512      * @return the {@code onauxclick} event handler
2513      */
2514     @JsxGetter(CHROME)
2515     public Function getOnauxclick() {
2516         return getEventHandler("auxclick");
2517     }
2518 
2519     /**
2520      * Sets the {@code onauxclick} event handler.
2521      * @param onauxclick the {@code onauxclick} event handler
2522      */
2523     @JsxSetter(CHROME)
2524     public void setOnauxclick(final Object onauxclick) {
2525         setHandlerForJavaScript("auxclick", onauxclick);
2526     }
2527 
2528     /**
2529      * Returns the {@code onscroll} event handler.
2530      * @return the {@code onscroll} event handler
2531      */
2532     @JsxGetter
2533     public Function getOnscroll() {
2534         return getEventHandler("scroll");
2535     }
2536 
2537     /**
2538      * Sets the {@code onscroll} event handler.
2539      * @param onscroll the {@code onscroll} event handler
2540      */
2541     @JsxSetter
2542     public void setOnscroll(final Object onscroll) {
2543         setHandlerForJavaScript("scroll", onscroll);
2544     }
2545 
2546     /**
2547      * Returns the {@code onkeydown} event handler.
2548      * @return the {@code onkeydown} event handler
2549      */
2550     @JsxGetter
2551     public Function getOnkeydown() {
2552         return getEventHandler("keydown");
2553     }
2554 
2555     /**
2556      * Sets the {@code onkeydown} event handler.
2557      * @param onkeydown the {@code onkeydown} event handler
2558      */
2559     @JsxSetter
2560     public void setOnkeydown(final Object onkeydown) {
2561         setHandlerForJavaScript("keydown", onkeydown);
2562     }
2563 
2564     /**
2565      * Returns the {@code onmspointerleave} event handler.
2566      * @return the {@code onmspointerleave} event handler
2567      */
2568     @JsxGetter(IE)
2569     public Function getOnmspointerleave() {
2570         return getEventHandler("mspointerleave");
2571     }
2572 
2573     /**
2574      * Sets the {@code onmspointerleave} event handler.
2575      * @param onmspointerleave the {@code onmspointerleave} event handler
2576      */
2577     @JsxSetter(IE)
2578     public void setOnmspointerleave(final Object onmspointerleave) {
2579         setHandlerForJavaScript("mspointerleave", onmspointerleave);
2580     }
2581 
2582     /**
2583      * Returns the {@code onmozpointerlockchange} event handler.
2584      * @return the {@code onmozpointerlockchange} event handler
2585      */
2586     @JsxGetter(FF45)
2587     public Function getOnmozpointerlockchange() {
2588         return getEventHandler("mozpointerlockchange");
2589     }
2590 
2591     /**
2592      * Sets the {@code onmozpointerlockchange} event handler.
2593      * @param onmozpointerlockchange the {@code onmozpointerlockchange} event handler
2594      */
2595     @JsxSetter(FF45)
2596     public void setOnmozpointerlockchange(final Object onmozpointerlockchange) {
2597         setHandlerForJavaScript("mozpointerlockchange", onmozpointerlockchange);
2598     }
2599 
2600     /**
2601      * Returns the {@code onwebkitanimationstart} event handler.
2602      * @return the {@code onwebkitanimationstart} event handler
2603      */
2604     @JsxGetter({CHROME, FF52})
2605     public Function getOnwebkitanimationstart() {
2606         return getEventHandler("webkitanimationstart");
2607     }
2608 
2609     /**
2610      * Sets the {@code onwebkitanimationstart} event handler.
2611      * @param onwebkitanimationstart the {@code onwebkitanimationstart} event handler
2612      */
2613     @JsxSetter({CHROME, FF52})
2614     public void setOnwebkitanimationstart(final Object onwebkitanimationstart) {
2615         setHandlerForJavaScript("webkitanimationstart", onwebkitanimationstart);
2616     }
2617 
2618     /**
2619      * Returns the {@code onkeyup} event handler.
2620      * @return the {@code onkeyup} event handler
2621      */
2622     @JsxGetter
2623     public Function getOnkeyup() {
2624         return getEventHandler("keyup");
2625     }
2626 
2627     /**
2628      * Sets the {@code onkeyup} event handler.
2629      * @param onkeyup the {@code onkeyup} event handler
2630      */
2631     @JsxSetter
2632     public void setOnkeyup(final Object onkeyup) {
2633         setHandlerForJavaScript("keyup", onkeyup);
2634     }
2635 
2636     /**
2637      * Returns the {@code onmsgesturestart} event handler.
2638      * @return the {@code onmsgesturestart} event handler
2639      */
2640     @JsxGetter(IE)
2641     public Function getOnmsgesturestart() {
2642         return getEventHandler("msgesturestart");
2643     }
2644 
2645     /**
2646      * Sets the {@code onmsgesturestart} event handler.
2647      * @param onmsgesturestart the {@code onmsgesturestart} event handler
2648      */
2649     @JsxSetter(IE)
2650     public void setOnmsgesturestart(final Object onmsgesturestart) {
2651         setHandlerForJavaScript("msgesturestart", onmsgesturestart);
2652     }
2653 
2654     /**
2655      * Returns the {@code ondeviceproximity} event handler.
2656      * @return the {@code ondeviceproximity} event handler
2657      */
2658     @JsxGetter(FF)
2659     public Function getOndeviceproximity() {
2660         return getEventHandler("deviceproximity");
2661     }
2662 
2663     /**
2664      * Sets the {@code ondeviceproximity} event handler.
2665      * @param ondeviceproximity the {@code ondeviceproximity} event handler
2666      */
2667     @JsxSetter(FF)
2668     public void setOndeviceproximity(final Object ondeviceproximity) {
2669         setHandlerForJavaScript("deviceproximity", ondeviceproximity);
2670     }
2671 
2672     /**
2673      * Returns the {@code onreset} event handler.
2674      * @return the {@code onreset} event handler
2675      */
2676     @JsxGetter
2677     public Function getOnreset() {
2678         return getEventHandler("reset");
2679     }
2680 
2681     /**
2682      * Sets the {@code onreset} event handler.
2683      * @param onreset the {@code onreset} event handler
2684      */
2685     @JsxSetter
2686     public void setOnreset(final Object onreset) {
2687         setHandlerForJavaScript("reset", onreset);
2688     }
2689 
2690     /**
2691      * Returns the {@code onkeypress} event handler.
2692      * @return the {@code onkeypress} event handler
2693      */
2694     @JsxGetter
2695     public Function getOnkeypress() {
2696         return getEventHandler("keypress");
2697     }
2698 
2699     /**
2700      * Sets the {@code onkeypress} event handler.
2701      * @param onkeypress the {@code onkeypress} event handler
2702      */
2703     @JsxSetter
2704     public void setOnkeypress(final Object onkeypress) {
2705         setHandlerForJavaScript("keypress", onkeypress);
2706     }
2707 
2708     /**
2709      * Returns the {@code ondrag} event handler.
2710      * @return the {@code ondrag} event handler
2711      */
2712     @JsxGetter
2713     public Function getOndrag() {
2714         return getEventHandler("drag");
2715     }
2716 
2717     /**
2718      * Sets the {@code ondrag} event handler.
2719      * @param ondrag the {@code ondrag} event handler
2720      */
2721     @JsxSetter
2722     public void setOndrag(final Object ondrag) {
2723         setHandlerForJavaScript("drag", ondrag);
2724     }
2725 
2726     /**
2727      * Returns the {@code onfocusout} event handler.
2728      * @return the {@code onfocusout} event handler
2729      */
2730     @JsxGetter(IE)
2731     public Function getOnfocusout() {
2732         return getEventHandler("focusout");
2733     }
2734 
2735     /**
2736      * Sets the {@code onfocusout} event handler.
2737      * @param onfocusout the {@code onfocusout} event handler
2738      */
2739     @JsxSetter(IE)
2740     public void setOnfocusout(final Object onfocusout) {
2741         setHandlerForJavaScript("focusout", onfocusout);
2742     }
2743 
2744     /**
2745      * Returns the {@code onseeked} event handler.
2746      * @return the {@code onseeked} event handler
2747      */
2748     @JsxGetter
2749     public Function getOnseeked() {
2750         return getEventHandler("seeked");
2751     }
2752 
2753     /**
2754      * Sets the {@code onseeked} event handler.
2755      * @param onseeked the {@code onseeked} event handler
2756      */
2757     @JsxSetter
2758     public void setOnseeked(final Object onseeked) {
2759         setHandlerForJavaScript("seeked", onseeked);
2760     }
2761 
2762     /**
2763      * Returns the {@code onoffline} event handler.
2764      * @return the {@code onoffline} event handler
2765      */
2766     @JsxGetter
2767     public Function getOnoffline() {
2768         return getEventHandler("offline");
2769     }
2770 
2771     /**
2772      * Sets the {@code onoffline} event handler.
2773      * @param onoffline the {@code onoffline} event handler
2774      */
2775     @JsxSetter
2776     public void setOnoffline(final Object onoffline) {
2777         setHandlerForJavaScript("offline", onoffline);
2778     }
2779 
2780     /**
2781      * Returns the {@code ondeviceorientation} event handler.
2782      * @return the {@code ondeviceorientation} event handler
2783      */
2784     @JsxGetter({CHROME, FF})
2785     public Function getOndeviceorientation() {
2786         return getEventHandler("deviceorientation");
2787     }
2788 
2789     /**
2790      * Sets the {@code ondeviceorientation} event handler.
2791      * @param ondeviceorientation the {@code ondeviceorientation} event handler
2792      */
2793     @JsxSetter({CHROME, FF})
2794     public void setOndeviceorientation(final Object ondeviceorientation) {
2795         setHandlerForJavaScript("deviceorientation", ondeviceorientation);
2796     }
2797 
2798     /**
2799      * Returns the {@code ontoggle} event handler.
2800      * @return the {@code ontoggle} event handler
2801      */
2802     @JsxGetter({CHROME, FF52})
2803     public Function getOntoggle() {
2804         return getEventHandler("toggle");
2805     }
2806 
2807     /**
2808      * Sets the {@code ontoggle} event handler.
2809      * @param ontoggle the {@code ontoggle} event handler
2810      */
2811     @JsxSetter({CHROME, FF52})
2812     public void setOntoggle(final Object ontoggle) {
2813         setHandlerForJavaScript("toggle", ontoggle);
2814     }
2815 
2816     /**
2817      * Returns the {@code onplay} event handler.
2818      * @return the {@code onplay} event handler
2819      */
2820     @JsxGetter
2821     public Function getOnplay() {
2822         return getEventHandler("play");
2823     }
2824 
2825     /**
2826      * Sets the {@code onplay} event handler.
2827      * @param onplay the {@code onplay} event handler
2828      */
2829     @JsxSetter
2830     public void setOnplay(final Object onplay) {
2831         setHandlerForJavaScript("play", onplay);
2832     }
2833 
2834     /**
2835      * Returns the {@code oncontextmenu} event handler.
2836      * @return the {@code oncontextmenu} event handler
2837      */
2838     @JsxGetter
2839     public Function getOncontextmenu() {
2840         return getEventHandler("contextmenu");
2841     }
2842 
2843     /**
2844      * Sets the {@code oncontextmenu} event handler.
2845      * @param oncontextmenu the {@code oncontextmenu} event handler
2846      */
2847     @JsxSetter
2848     public void setOncontextmenu(final Object oncontextmenu) {
2849         setHandlerForJavaScript("contextmenu", oncontextmenu);
2850     }
2851 
2852     /**
2853      * Returns the {@code onmousemove} event handler.
2854      * @return the {@code onmousemove} event handler
2855      */
2856     @JsxGetter
2857     public Function getOnmousemove() {
2858         return getEventHandler("mousemove");
2859     }
2860 
2861     /**
2862      * Sets the {@code onmousemove} event handler.
2863      * @param onmousemove the {@code onmousemove} event handler
2864      */
2865     @JsxSetter
2866     public void setOnmousemove(final Object onmousemove) {
2867         setHandlerForJavaScript("mousemove", onmousemove);
2868     }
2869 
2870     /**
2871      * Returns the {@code onreadystatechange} event handler.
2872      * @return the {@code onreadystatechange} event handler
2873      */
2874     @JsxGetter(IE)
2875     public Function getOnreadystatechange() {
2876         return getEventHandler("readystatechange");
2877     }
2878 
2879     /**
2880      * Sets the {@code onreadystatechange} event handler.
2881      * @param onreadystatechange the {@code onreadystatechange} event handler
2882      */
2883     @JsxSetter(IE)
2884     public void setOnreadystatechange(final Object onreadystatechange) {
2885         setHandlerForJavaScript("readystatechange", onreadystatechange);
2886     }
2887 
2888     /**
2889      * Returns the {@code onmspointerover} event handler.
2890      * @return the {@code onmspointerover} event handler
2891      */
2892     @JsxGetter(IE)
2893     public Function getOnmspointerover() {
2894         return getEventHandler("mspointerover");
2895     }
2896 
2897     /**
2898      * Sets the {@code onmspointerover} event handler.
2899      * @param onmspointerover the {@code onmspointerover} event handler
2900      */
2901     @JsxSetter(IE)
2902     public void setOnmspointerover(final Object onmspointerover) {
2903         setHandlerForJavaScript("mspointerover", onmspointerover);
2904     }
2905 
2906     /**
2907      * Returns the {@code onpointermove} event handler.
2908      * @return the {@code onpointermove} event handler
2909      */
2910     @JsxGetter({CHROME, IE})
2911     public Function getOnpointermove() {
2912         return getEventHandler("pointermove");
2913     }
2914 
2915     /**
2916      * Sets the {@code onpointermove} event handler.
2917      * @param onpointermove the {@code onpointermove} event handler
2918      */
2919     @JsxSetter({CHROME, IE})
2920     public void setOnpointermove(final Object onpointermove) {
2921         setHandlerForJavaScript("pointermove", onpointermove);
2922     }
2923 
2924     /**
2925      * Returns the {@code onmspointermove} event handler.
2926      * @return the {@code onmspointermove} event handler
2927      */
2928     @JsxGetter(IE)
2929     public Function getOnmspointermove() {
2930         return getEventHandler("mspointermove");
2931     }
2932 
2933     /**
2934      * Sets the {@code onmspointermove} event handler.
2935      * @param onmspointermove the {@code onmspointermove} event handler
2936      */
2937     @JsxSetter(IE)
2938     public void setOnmspointermove(final Object onmspointermove) {
2939         setHandlerForJavaScript("mspointermove", onmspointermove);
2940     }
2941 
2942     /**
2943      * Returns the {@code onmouseover} event handler.
2944      * @return the {@code onmouseover} event handler
2945      */
2946     @JsxGetter
2947     public Function getOnmouseover() {
2948         return getEventHandler("mouseover");
2949     }
2950 
2951     /**
2952      * Sets the {@code onmouseover} event handler.
2953      * @param onmouseover the {@code onmouseover} event handler
2954      */
2955     @JsxSetter
2956     public void setOnmouseover(final Object onmouseover) {
2957         setHandlerForJavaScript("mouseover", onmouseover);
2958     }
2959 
2960     /**
2961      * Returns the {@code onuserproximity} event handler.
2962      * @return the {@code onuserproximity} event handler
2963      */
2964     @JsxGetter(FF)
2965     public Function getOnuserproximity() {
2966         return getEventHandler("userproximity");
2967     }
2968 
2969     /**
2970      * Sets the {@code onuserproximity} event handler.
2971      * @param onuserproximity the {@code onuserproximity} event handler
2972      */
2973     @JsxSetter(FF)
2974     public void setOnuserproximity(final Object onuserproximity) {
2975         setHandlerForJavaScript("userproximity", onuserproximity);
2976     }
2977 
2978     /**
2979      * Returns the {@code onlostpointercapture} event handler.
2980      * @return the {@code onlostpointercapture} event handler
2981      */
2982     @JsxGetter(CHROME)
2983     public Function getOnlostpointercapture() {
2984         return getEventHandler("lostpointercapture");
2985     }
2986 
2987     /**
2988      * Sets the {@code onlostpointercapture} event handler.
2989      * @param onlostpointercapture the {@code onlostpointercapture} event handler
2990      */
2991     @JsxSetter(CHROME)
2992     public void setOnlostpointercapture(final Object onlostpointercapture) {
2993         setHandlerForJavaScript("lostpointercapture", onlostpointercapture);
2994     }
2995 
2996     /**
2997      * Returns the {@code onpointerover} event handler.
2998      * @return the {@code onpointerover} event handler
2999      */
3000     @JsxGetter({CHROME, IE})
3001     public Function getOnpointerover() {
3002         return getEventHandler("pointerover");
3003     }
3004 
3005     /**
3006      * Sets the {@code onpointerover} event handler.
3007      * @param onpointerover the {@code onpointerover} event handler
3008      */
3009     @JsxSetter({CHROME, IE})
3010     public void setOnpointerover(final Object onpointerover) {
3011         setHandlerForJavaScript("pointerover", onpointerover);
3012     }
3013 
3014     /**
3015      * Returns the {@code onclose} event handler.
3016      * @return the {@code onclose} event handler
3017      */
3018     @JsxGetter(CHROME)
3019     public Function getOnclose() {
3020         return getEventHandler("close");
3021     }
3022 
3023     /**
3024      * Sets the {@code onclose} event handler.
3025      * @param onclose the {@code onclose} event handler
3026      */
3027     @JsxSetter(CHROME)
3028     public void setOnclose(final Object onclose) {
3029         setHandlerForJavaScript("close", onclose);
3030     }
3031 
3032     /**
3033      * Returns the {@code onanimationend} event handler.
3034      * @return the {@code onanimationend} event handler
3035      */
3036     @JsxGetter({CHROME, FF52})
3037     public Function getOnanimationend() {
3038         return getEventHandler("animationend");
3039     }
3040 
3041     /**
3042      * Sets the {@code onanimationend} event handler.
3043      * @param onanimationend the {@code onanimationend} event handler
3044      */
3045     @JsxSetter({CHROME, FF52})
3046     public void setOnanimationend(final Object onanimationend) {
3047         setHandlerForJavaScript("animationend", onanimationend);
3048     }
3049 
3050     /**
3051      * Returns the {@code ondragenter} event handler.
3052      * @return the {@code ondragenter} event handler
3053      */
3054     @JsxGetter
3055     public Function getOndragenter() {
3056         return getEventHandler("dragenter");
3057     }
3058 
3059     /**
3060      * Sets the {@code ondragenter} event handler.
3061      * @param ondragenter the {@code ondragenter} event handler
3062      */
3063     @JsxSetter
3064     public void setOndragenter(final Object ondragenter) {
3065         setHandlerForJavaScript("dragenter", ondragenter);
3066     }
3067 
3068     /**
3069      * Returns the {@code onafterprint} event handler.
3070      * @return the {@code onafterprint} event handler
3071      */
3072     @JsxGetter({FF, IE})
3073     public Function getOnafterprint() {
3074         return getEventHandler("afterprint");
3075     }
3076 
3077     /**
3078      * Sets the {@code onafterprint} event handler.
3079      * @param onafterprint the {@code onafterprint} event handler
3080      */
3081     @JsxSetter({FF, IE})
3082     public void setOnafterprint(final Object onafterprint) {
3083         setHandlerForJavaScript("afterprint", onafterprint);
3084     }
3085 
3086     /**
3087      * Returns the {@code onmozfullscreenerror} event handler.
3088      * @return the {@code onmozfullscreenerror} event handler
3089      */
3090     @JsxGetter(FF)
3091     public Function getOnmozfullscreenerror() {
3092         return getEventHandler("mozfullscreenerror");
3093     }
3094 
3095     /**
3096      * Sets the {@code onmozfullscreenerror} event handler.
3097      * @param onmozfullscreenerror the {@code onmozfullscreenerror} event handler
3098      */
3099     @JsxSetter(FF)
3100     public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
3101         setHandlerForJavaScript("mozfullscreenerror", onmozfullscreenerror);
3102     }
3103 
3104     /**
3105      * Returns the {@code onmouseleave} event handler.
3106      * @return the {@code onmouseleave} event handler
3107      */
3108     @JsxGetter
3109     public Function getOnmouseleave() {
3110         return getEventHandler("mouseleave");
3111     }
3112 
3113     /**
3114      * Sets the {@code onmouseleave} event handler.
3115      * @param onmouseleave the {@code onmouseleave} event handler
3116      */
3117     @JsxSetter
3118     public void setOnmouseleave(final Object onmouseleave) {
3119         setHandlerForJavaScript("mouseleave", onmouseleave);
3120     }
3121 
3122     /**
3123      * Returns the {@code onmousewheel} event handler.
3124      * @return the {@code onmousewheel} event handler
3125      */
3126     @JsxGetter({CHROME, IE})
3127     public Function getOnmousewheel() {
3128         return getEventHandler("mousewheel");
3129     }
3130 
3131     /**
3132      * Sets the {@code onmousewheel} event handler.
3133      * @param onmousewheel the {@code onmousewheel} event handler
3134      */
3135     @JsxSetter({CHROME, IE})
3136     public void setOnmousewheel(final Object onmousewheel) {
3137         setHandlerForJavaScript("mousewheel", onmousewheel);
3138     }
3139 
3140     /**
3141      * Returns the {@code onseeking} event handler.
3142      * @return the {@code onseeking} event handler
3143      */
3144     @JsxGetter
3145     public Function getOnseeking() {
3146         return getEventHandler("seeking");
3147     }
3148 
3149     /**
3150      * Sets the {@code onseeking} event handler.
3151      * @param onseeking the {@code onseeking} event handler
3152      */
3153     @JsxSetter
3154     public void setOnseeking(final Object onseeking) {
3155         setHandlerForJavaScript("seeking", onseeking);
3156     }
3157 
3158     /**
3159      * Returns the {@code oncuechange} event handler.
3160      * @return the {@code oncuechange} event handler
3161      */
3162     @JsxGetter(CHROME)
3163     public Function getOncuechange() {
3164         return getEventHandler("cuechange");
3165     }
3166 
3167     /**
3168      * Sets the {@code oncuechange} event handler.
3169      * @param oncuechange the {@code oncuechange} event handler
3170      */
3171     @JsxSetter(CHROME)
3172     public void setOncuechange(final Object oncuechange) {
3173         setHandlerForJavaScript("cuechange", oncuechange);
3174     }
3175 
3176     /**
3177      * Returns the {@code onpageshow} event handler.
3178      * @return the {@code onpageshow} event handler
3179      */
3180     @JsxGetter
3181     public Function getOnpageshow() {
3182         return getEventHandler("pageshow");
3183     }
3184 
3185     /**
3186      * Sets the {@code onpageshow} event handler.
3187      * @param onpageshow the {@code onpageshow} event handler
3188      */
3189     @JsxSetter
3190     public void setOnpageshow(final Object onpageshow) {
3191         setHandlerForJavaScript("pageshow", onpageshow);
3192     }
3193 
3194     /**
3195      * Returns the {@code onmspointerenter} event handler.
3196      * @return the {@code onmspointerenter} event handler
3197      */
3198     @JsxGetter(IE)
3199     public Function getOnmspointerenter() {
3200         return getEventHandler("mspointerenter");
3201     }
3202 
3203     /**
3204      * Sets the {@code onmspointerenter} event handler.
3205      * @param onmspointerenter the {@code onmspointerenter} event handler
3206      */
3207     @JsxSetter(IE)
3208     public void setOnmspointerenter(final Object onmspointerenter) {
3209         setHandlerForJavaScript("mspointerenter", onmspointerenter);
3210     }
3211 
3212     /**
3213      * Returns the {@code onmozfullscreenchange} event handler.
3214      * @return the {@code onmozfullscreenchange} event handler
3215      */
3216     @JsxGetter(FF)
3217     public Function getOnmozfullscreenchange() {
3218         return getEventHandler("mozfullscreenchange");
3219     }
3220 
3221     /**
3222      * Sets the {@code onmozfullscreenchange} event handler.
3223      * @param onmozfullscreenchange the {@code onmozfullscreenchange} event handler
3224      */
3225     @JsxSetter(FF)
3226     public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
3227         setHandlerForJavaScript("mozfullscreenchange", onmozfullscreenchange);
3228     }
3229 
3230     /**
3231      * Returns the {@code ondurationchange} event handler.
3232      * @return the {@code ondurationchange} event handler
3233      */
3234     @JsxGetter
3235     public Function getOndurationchange() {
3236         return getEventHandler("durationchange");
3237     }
3238 
3239     /**
3240      * Sets the {@code ondurationchange} event handler.
3241      * @param ondurationchange the {@code ondurationchange} event handler
3242      */
3243     @JsxSetter
3244     public void setOndurationchange(final Object ondurationchange) {
3245         setHandlerForJavaScript("durationchange", ondurationchange);
3246     }
3247 
3248     /**
3249      * Returns the {@code onplaying} event handler.
3250      * @return the {@code onplaying} event handler
3251      */
3252     @JsxGetter
3253     public Function getOnplaying() {
3254         return getEventHandler("playing");
3255     }
3256 
3257     /**
3258      * Sets the {@code onplaying} event handler.
3259      * @param onplaying the {@code onplaying} event handler
3260      */
3261     @JsxSetter
3262     public void setOnplaying(final Object onplaying) {
3263         setHandlerForJavaScript("playing", onplaying);
3264     }
3265 
3266     /**
3267      * Returns the {@code onended} event handler.
3268      * @return the {@code onended} event handler
3269      */
3270     @JsxGetter
3271     public Function getOnended() {
3272         return getEventHandler("ended");
3273     }
3274 
3275     /**
3276      * Sets the {@code onended} event handler.
3277      * @param onended the {@code onended} event handler
3278      */
3279     @JsxSetter
3280     public void setOnended(final Object onended) {
3281         setHandlerForJavaScript("ended", onended);
3282     }
3283 
3284     /**
3285      * Returns the {@code onloadeddata} event handler.
3286      * @return the {@code onloadeddata} event handler
3287      */
3288     @JsxGetter
3289     public Function getOnloadeddata() {
3290         return getEventHandler("loadeddata");
3291     }
3292 
3293     /**
3294      * Sets the {@code onloadeddata} event handler.
3295      * @param onloadeddata the {@code onloadeddata} event handler
3296      */
3297     @JsxSetter
3298     public void setOnloadeddata(final Object onloadeddata) {
3299         setHandlerForJavaScript("loadeddata", onloadeddata);
3300     }
3301 
3302     /**
3303      * Returns the {@code onunhandledrejection} event handler.
3304      * @return the {@code onunhandledrejection} event handler
3305      */
3306     @JsxGetter(CHROME)
3307     public Function getOnunhandledrejection() {
3308         return getEventHandler("unhandledrejection");
3309     }
3310 
3311     /**
3312      * Sets the {@code onunhandledrejection} event handler.
3313      * @param onunhandledrejection the {@code onunhandledrejection} event handler
3314      */
3315     @JsxSetter(CHROME)
3316     public void setOnunhandledrejection(final Object onunhandledrejection) {
3317         setHandlerForJavaScript("unhandledrejection", onunhandledrejection);
3318     }
3319 
3320     /**
3321      * Returns the {@code onmouseout} event handler.
3322      * @return the {@code onmouseout} event handler
3323      */
3324     @JsxGetter
3325     public Function getOnmouseout() {
3326         return getEventHandler("mouseout");
3327     }
3328 
3329     /**
3330      * Sets the {@code onmouseout} event handler.
3331      * @param onmouseout the {@code onmouseout} event handler
3332      */
3333     @JsxSetter
3334     public void setOnmouseout(final Object onmouseout) {
3335         setHandlerForJavaScript("mouseout", onmouseout);
3336     }
3337 
3338     /**
3339      * Returns the {@code onsuspend} event handler.
3340      * @return the {@code onsuspend} event handler
3341      */
3342     @JsxGetter
3343     public Function getOnsuspend() {
3344         return getEventHandler("suspend");
3345     }
3346 
3347     /**
3348      * Sets the {@code onsuspend} event handler.
3349      * @param onsuspend the {@code onsuspend} event handler
3350      */
3351     @JsxSetter
3352     public void setOnsuspend(final Object onsuspend) {
3353         setHandlerForJavaScript("suspend", onsuspend);
3354     }
3355 
3356     /**
3357      * Returns the {@code onwaiting} event handler.
3358      * @return the {@code onwaiting} event handler
3359      */
3360     @JsxGetter
3361     public Function getOnwaiting() {
3362         return getEventHandler("waiting");
3363     }
3364 
3365     /**
3366      * Sets the {@code onwaiting} event handler.
3367      * @param onwaiting the {@code onwaiting} event handler
3368      */
3369     @JsxSetter
3370     public void setOnwaiting(final Object onwaiting) {
3371         setHandlerForJavaScript("waiting", onwaiting);
3372     }
3373 
3374     /**
3375      * Returns the {@code oncanplay} event handler.
3376      * @return the {@code oncanplay} event handler
3377      */
3378     @JsxGetter
3379     public Function getOncanplay() {
3380         return getEventHandler("canplay");
3381     }
3382 
3383     /**
3384      * Sets the {@code oncanplay} event handler.
3385      * @param oncanplay the {@code oncanplay} event handler
3386      */
3387     @JsxSetter
3388     public void setOncanplay(final Object oncanplay) {
3389         setHandlerForJavaScript("canplay", oncanplay);
3390     }
3391 
3392     /**
3393      * Returns the {@code onmousedown} event handler.
3394      * @return the {@code onmousedown} event handler
3395      */
3396     @JsxGetter
3397     public Function getOnmousedown() {
3398         return getEventHandler("mousedown");
3399     }
3400 
3401     /**
3402      * Sets the {@code onmousedown} event handler.
3403      * @param onmousedown the {@code onmousedown} event handler
3404      */
3405     @JsxSetter
3406     public void setOnmousedown(final Object onmousedown) {
3407         setHandlerForJavaScript("mousedown", onmousedown);
3408     }
3409 
3410     /**
3411      * Returns the {@code onlanguagechange} event handler.
3412      * @return the {@code onlanguagechange} event handler
3413      */
3414     @JsxGetter({CHROME, FF})
3415     public Function getOnlanguagechange() {
3416         return getEventHandler("languagechange");
3417     }
3418 
3419     /**
3420      * Sets the {@code onlanguagechange} event handler.
3421      * @param onlanguagechange the {@code onlanguagechange} event handler
3422      */
3423     @JsxSetter({CHROME, FF})
3424     public void setOnlanguagechange(final Object onlanguagechange) {
3425         setHandlerForJavaScript("languagechange", onlanguagechange);
3426     }
3427 
3428     /**
3429      * Returns the {@code onemptied} event handler.
3430      * @return the {@code onemptied} event handler
3431      */
3432     @JsxGetter
3433     public Function getOnemptied() {
3434         return getEventHandler("emptied");
3435     }
3436 
3437     /**
3438      * Sets the {@code onemptied} event handler.
3439      * @param onemptied the {@code onemptied} event handler
3440      */
3441     @JsxSetter
3442     public void setOnemptied(final Object onemptied) {
3443         setHandlerForJavaScript("emptied", onemptied);
3444     }
3445 
3446     /**
3447      * Returns the {@code onrejectionhandled} event handler.
3448      * @return the {@code onrejectionhandled} event handler
3449      */
3450     @JsxGetter(CHROME)
3451     public Function getOnrejectionhandled() {
3452         return getEventHandler("rejectionhandled");
3453     }
3454 
3455     /**
3456      * Sets the {@code onrejectionhandled} event handler.
3457      * @param onrejectionhandled the {@code onrejectionhandled} event handler
3458      */
3459     @JsxSetter(CHROME)
3460     public void setOnrejectionhandled(final Object onrejectionhandled) {
3461         setHandlerForJavaScript("rejectionhandled", onrejectionhandled);
3462     }
3463 
3464     /**
3465      * Returns the {@code onpointercancel} event handler.
3466      * @return the {@code onpointercancel} event handler
3467      */
3468     @JsxGetter({CHROME, IE})
3469     public Function getOnpointercancel() {
3470         return getEventHandler("pointercancel");
3471     }
3472 
3473     /**
3474      * Sets the {@code onpointercancel} event handler.
3475      * @param onpointercancel the {@code onpointercancel} event handler
3476      */
3477     @JsxSetter({CHROME, IE})
3478     public void setOnpointercancel(final Object onpointercancel) {
3479         setHandlerForJavaScript("pointercancel", onpointercancel);
3480     }
3481 
3482     /**
3483      * Returns the {@code onmsgestureend} event handler.
3484      * @return the {@code onmsgestureend} event handler
3485      */
3486     @JsxGetter(IE)
3487     public Function getOnmsgestureend() {
3488         return getEventHandler("msgestureend");
3489     }
3490 
3491     /**
3492      * Sets the {@code onmsgestureend} event handler.
3493      * @param onmsgestureend the {@code onmsgestureend} event handler
3494      */
3495     @JsxSetter(IE)
3496     public void setOnmsgestureend(final Object onmsgestureend) {
3497         setHandlerForJavaScript("msgestureend", onmsgestureend);
3498     }
3499 
3500     /**
3501      * Returns the {@code onresize} event handler.
3502      * @return the {@code onresize} event handler
3503      */
3504     @JsxGetter
3505     public Function getOnresize() {
3506         return getEventHandler("resize");
3507     }
3508 
3509     /**
3510      * Sets the {@code onresize} event handler.
3511      * @param onresize the {@code onresize} event handler
3512      */
3513     @JsxSetter
3514     public void setOnresize(final Object onresize) {
3515         setHandlerForJavaScript("resize", onresize);
3516     }
3517 
3518     /**
3519      * Returns the {@code onpause} event handler.
3520      * @return the {@code onpause} event handler
3521      */
3522     @JsxGetter
3523     public Function getOnpause() {
3524         return getEventHandler("pause");
3525     }
3526 
3527     /**
3528      * Sets the {@code onpause} event handler.
3529      * @param onpause the {@code onpause} event handler
3530      */
3531     @JsxSetter
3532     public void setOnpause(final Object onpause) {
3533         setHandlerForJavaScript("pause", onpause);
3534     }
3535 
3536     /**
3537      * Returns the {@code onloadstart} event handler.
3538      * @return the {@code onloadstart} event handler
3539      */
3540     @JsxGetter
3541     public Function getOnloadstart() {
3542         return getEventHandler("loadstart");
3543     }
3544 
3545     /**
3546      * Sets the {@code onloadstart} event handler.
3547      * @param onloadstart the {@code onloadstart} event handler
3548      */
3549     @JsxSetter
3550     public void setOnloadstart(final Object onloadstart) {
3551         setHandlerForJavaScript("loadstart", onloadstart);
3552     }
3553 
3554     /**
3555      * Returns the {@code onprogress} event handler.
3556      * @return the {@code onprogress} event handler
3557      */
3558     @JsxGetter
3559     public Function getOnprogress() {
3560         return getEventHandler("progress");
3561     }
3562 
3563     /**
3564      * Sets the {@code onprogress} event handler.
3565      * @param onprogress the {@code onprogress} event handler
3566      */
3567     @JsxSetter
3568     public void setOnprogress(final Object onprogress) {
3569         setHandlerForJavaScript("progress", onprogress);
3570     }
3571 
3572     /**
3573      * Returns the {@code onpointerup} event handler.
3574      * @return the {@code onpointerup} event handler
3575      */
3576     @JsxGetter({CHROME, IE})
3577     public Function getOnpointerup() {
3578         return getEventHandler("pointerup");
3579     }
3580 
3581     /**
3582      * Sets the {@code onpointerup} event handler.
3583      * @param onpointerup the {@code onpointerup} event handler
3584      */
3585     @JsxSetter({CHROME, IE})
3586     public void setOnpointerup(final Object onpointerup) {
3587         setHandlerForJavaScript("pointerup", onpointerup);
3588     }
3589 
3590     /**
3591      * Returns the {@code onwheel} event handler.
3592      * @return the {@code onwheel} event handler
3593      */
3594     @JsxGetter({CHROME, FF})
3595     public Function getOnwheel() {
3596         return getEventHandler("wheel");
3597     }
3598 
3599     /**
3600      * Sets the {@code onwheel} event handler.
3601      * @param onwheel the {@code onwheel} event handler
3602      */
3603     @JsxSetter({CHROME, FF})
3604     public void setOnwheel(final Object onwheel) {
3605         setHandlerForJavaScript("wheel", onwheel);
3606     }
3607 
3608     /**
3609      * Returns the {@code onmspointerdown} event handler.
3610      * @return the {@code onmspointerdown} event handler
3611      */
3612     @JsxGetter(IE)
3613     public Function getOnmspointerdown() {
3614         return getEventHandler("mspointerdown");
3615     }
3616 
3617     /**
3618      * Sets the {@code onmspointerdown} event handler.
3619      * @param onmspointerdown the {@code onmspointerdown} event handler
3620      */
3621     @JsxSetter(IE)
3622     public void setOnmspointerdown(final Object onmspointerdown) {
3623         setHandlerForJavaScript("mspointerdown", onmspointerdown);
3624     }
3625 
3626     /**
3627      * Returns the {@code onpointerleave} event handler.
3628      * @return the {@code onpointerleave} event handler
3629      */
3630     @JsxGetter({CHROME, IE})
3631     public Function getOnpointerleave() {
3632         return getEventHandler("pointerleave");
3633     }
3634 
3635     /**
3636      * Sets the {@code onpointerleave} event handler.
3637      * @param onpointerleave the {@code onpointerleave} event handler
3638      */
3639     @JsxSetter({CHROME, IE})
3640     public void setOnpointerleave(final Object onpointerleave) {
3641         setHandlerForJavaScript("pointerleave", onpointerleave);
3642     }
3643 
3644     /**
3645      * Returns the {@code onbeforeprint} event handler.
3646      * @return the {@code onbeforeprint} event handler
3647      */
3648     @JsxGetter({FF, IE})
3649     public Function getOnbeforeprint() {
3650         return getEventHandler("beforeprint");
3651     }
3652 
3653     /**
3654      * Sets the {@code onbeforeprint} event handler.
3655      * @param onbeforeprint the {@code onbeforeprint} event handler
3656      */
3657     @JsxSetter({FF, IE})
3658     public void setOnbeforeprint(final Object onbeforeprint) {
3659         setHandlerForJavaScript("beforeprint", onbeforeprint);
3660     }
3661 
3662     /**
3663      * Returns the {@code onstorage} event handler.
3664      * @return the {@code onstorage} event handler
3665      */
3666     @JsxGetter
3667     public Function getOnstorage() {
3668         return getEventHandler("storage");
3669     }
3670 
3671     /**
3672      * Sets the {@code onstorage} event handler.
3673      * @param onstorage the {@code onstorage} event handler
3674      */
3675     @JsxSetter
3676     public void setOnstorage(final Object onstorage) {
3677         setHandlerForJavaScript("storage", onstorage);
3678     }
3679 
3680     /**
3681      * Returns the {@code ondevicelight} event handler.
3682      * @return the {@code ondevicelight} event handler
3683      */
3684     @JsxGetter(FF)
3685     public Function getOndevicelight() {
3686         return getEventHandler("devicelight");
3687     }
3688 
3689     /**
3690      * Sets the {@code ondevicelight} event handler.
3691      * @param ondevicelight the {@code ondevicelight} event handler
3692      */
3693     @JsxSetter(FF)
3694     public void setOndevicelight(final Object ondevicelight) {
3695         setHandlerForJavaScript("devicelight", ondevicelight);
3696     }
3697 
3698     /**
3699      * Returns the {@code onanimationstart} event handler.
3700      * @return the {@code onanimationstart} event handler
3701      */
3702     @JsxGetter({CHROME, FF52})
3703     public Function getOnanimationstart() {
3704         return getEventHandler("animationstart");
3705     }
3706 
3707     /**
3708      * Sets the {@code onanimationstart} event handler.
3709      * @param onanimationstart the {@code onanimationstart} event handler
3710      */
3711     @JsxSetter({CHROME, FF52})
3712     public void setOnanimationstart(final Object onanimationstart) {
3713         setHandlerForJavaScript("animationstart", onanimationstart);
3714     }
3715 
3716     /**
3717      * Returns the {@code onmspointercancel} event handler.
3718      * @return the {@code onmspointercancel} event handler
3719      */
3720     @JsxGetter(IE)
3721     public Function getOnmspointercancel() {
3722         return getEventHandler("mspointercancel");
3723     }
3724 
3725     /**
3726      * Sets the {@code onmspointercancel} event handler.
3727      * @param onmspointercancel the {@code onmspointercancel} event handler
3728      */
3729     @JsxSetter(IE)
3730     public void setOnmspointercancel(final Object onmspointercancel) {
3731         setHandlerForJavaScript("mspointercancel", onmspointercancel);
3732     }
3733 
3734     /**
3735      * Returns the {@code ontimeupdate} event handler.
3736      * @return the {@code ontimeupdate} event handler
3737      */
3738     @JsxGetter
3739     public Function getOntimeupdate() {
3740         return getEventHandler("timeupdate");
3741     }
3742 
3743     /**
3744      * Sets the {@code ontimeupdate} event handler.
3745      * @param ontimeupdate the {@code ontimeupdate} event handler
3746      */
3747     @JsxSetter
3748     public void setOntimeupdate(final Object ontimeupdate) {
3749         setHandlerForJavaScript("timeupdate", ontimeupdate);
3750     }
3751 
3752     /**
3753      * Returns the {@code onpagehide} event handler.
3754      * @return the {@code onpagehide} event handler
3755      */
3756     @JsxGetter
3757     public Function getOnpagehide() {
3758         return getEventHandler("pagehide");
3759     }
3760 
3761     /**
3762      * Sets the {@code onpagehide} event handler.
3763      * @param onpagehide the {@code onpagehide} event handler
3764      */
3765     @JsxSetter
3766     public void setOnpagehide(final Object onpagehide) {
3767         setHandlerForJavaScript("pagehide", onpagehide);
3768     }
3769 
3770     /**
3771      * Returns the {@code onwebkitanimationiteration} event handler.
3772      * @return the {@code onwebkitanimationiteration} event handler
3773      */
3774     @JsxGetter({CHROME, FF52})
3775     public Function getOnwebkitanimationiteration() {
3776         return getEventHandler("webkitanimationiteration");
3777     }
3778 
3779     /**
3780      * Sets the {@code onwebkitanimationiteration} event handler.
3781      * @param onwebkitanimationiteration the {@code onwebkitanimationiteration} event handler
3782      */
3783     @JsxSetter({CHROME, FF52})
3784     public void setOnwebkitanimationiteration(final Object onwebkitanimationiteration) {
3785         setHandlerForJavaScript("webkitanimationiteration", onwebkitanimationiteration);
3786     }
3787 
3788     /**
3789      * Returns the {@code onmspointerup} event handler.
3790      * @return the {@code onmspointerup} event handler
3791      */
3792     @JsxGetter(IE)
3793     public Function getOnmspointerup() {
3794         return getEventHandler("mspointerup");
3795     }
3796 
3797     /**
3798      * Sets the {@code onmspointerup} event handler.
3799      * @param onmspointerup the {@code onmspointerup} event handler
3800      */
3801     @JsxSetter(IE)
3802     public void setOnmspointerup(final Object onmspointerup) {
3803         setHandlerForJavaScript("mspointerup", onmspointerup);
3804     }
3805 
3806     /**
3807      * Returns the {@code onabort} event handler.
3808      * @return the {@code onabort} event handler
3809      */
3810     @JsxGetter
3811     public Function getOnabort() {
3812         return getEventHandler("abort");
3813     }
3814 
3815     /**
3816      * Sets the {@code onabort} event handler.
3817      * @param onabort the {@code onabort} event handler
3818      */
3819     @JsxSetter
3820     public void setOnabort(final Object onabort) {
3821         setHandlerForJavaScript("abort", onabort);
3822     }
3823 
3824     /**
3825      * Returns the {@code onloadedmetadata} event handler.
3826      * @return the {@code onloadedmetadata} event handler
3827      */
3828     @JsxGetter
3829     public Function getOnloadedmetadata() {
3830         return getEventHandler("loadedmetadata");
3831     }
3832 
3833     /**
3834      * Sets the {@code onloadedmetadata} event handler.
3835      * @param onloadedmetadata the {@code onloadedmetadata} event handler
3836      */
3837     @JsxSetter
3838     public void setOnloadedmetadata(final Object onloadedmetadata) {
3839         setHandlerForJavaScript("loadedmetadata", onloadedmetadata);
3840     }
3841 
3842     /**
3843      * Returns the {@code onmsinertiastart} event handler.
3844      * @return the {@code onmsinertiastart} event handler
3845      */
3846     @JsxGetter(IE)
3847     public Function getOnmsinertiastart() {
3848         return getEventHandler("msinertiastart");
3849     }
3850 
3851     /**
3852      * Sets the {@code onmsinertiastart} event handler.
3853      * @param onmsinertiastart the {@code onmsinertiastart} event handler
3854      */
3855     @JsxSetter(IE)
3856     public void setOnmsinertiastart(final Object onmsinertiastart) {
3857         setHandlerForJavaScript("msinertiastart", onmsinertiastart);
3858     }
3859 
3860     /**
3861      * Returns the {@code onmouseup} event handler.
3862      * @return the {@code onmouseup} event handler
3863      */
3864     @JsxGetter
3865     public Function getOnmouseup() {
3866         return getEventHandler("mouseup");
3867     }
3868 
3869     /**
3870      * Sets the {@code onmouseup} event handler.
3871      * @param onmouseup the {@code onmouseup} event handler
3872      */
3873     @JsxSetter
3874     public void setOnmouseup(final Object onmouseup) {
3875         setHandlerForJavaScript("mouseup", onmouseup);
3876     }
3877 
3878     /**
3879      * Returns the {@code onmsgesturetap} event handler.
3880      * @return the {@code onmsgesturetap} event handler
3881      */
3882     @JsxGetter(IE)
3883     public Function getOnmsgesturetap() {
3884         return getEventHandler("msgesturetap");
3885     }
3886 
3887     /**
3888      * Sets the {@code onmsgesturetap} event handler.
3889      * @param onmsgesturetap the {@code onmsgesturetap} event handler
3890      */
3891     @JsxSetter(IE)
3892     public void setOnmsgesturetap(final Object onmsgesturetap) {
3893         setHandlerForJavaScript("msgesturetap", onmsgesturetap);
3894     }
3895 
3896     /**
3897      * Returns the {@code ondragover} event handler.
3898      * @return the {@code ondragover} event handler
3899      */
3900     @JsxGetter
3901     public Function getOndragover() {
3902         return getEventHandler("dragover");
3903     }
3904 
3905     /**
3906      * Sets the {@code ondragover} event handler.
3907      * @param ondragover the {@code ondragover} event handler
3908      */
3909     @JsxSetter
3910     public void setOndragover(final Object ondragover) {
3911         setHandlerForJavaScript("dragover", ondragover);
3912     }
3913 
3914     /**
3915      * Returns the {@code ononline} event handler.
3916      * @return the {@code ononline} event handler
3917      */
3918     @JsxGetter
3919     public Function getOnonline() {
3920         return getEventHandler("online");
3921     }
3922 
3923     /**
3924      * Sets the {@code ononline} event handler.
3925      * @param ononline the {@code ononline} event handler
3926      */
3927     @JsxSetter
3928     public void setOnonline(final Object ononline) {
3929         setHandlerForJavaScript("online", ononline);
3930     }
3931 
3932     /**
3933      * Returns the {@code onmsgesturedoubletap} event handler.
3934      * @return the {@code onmsgesturedoubletap} event handler
3935      */
3936     @JsxGetter(IE)
3937     public Function getOnmsgesturedoubletap() {
3938         return getEventHandler("msgesturedoubletap");
3939     }
3940 
3941     /**
3942      * Sets the {@code onmsgesturedoubletap} event handler.
3943      * @param onmsgesturedoubletap the {@code onmsgesturedoubletap} event handler
3944      */
3945     @JsxSetter(IE)
3946     public void setOnmsgesturedoubletap(final Object onmsgesturedoubletap) {
3947         setHandlerForJavaScript("msgesturedoubletap", onmsgesturedoubletap);
3948     }
3949 
3950     /**
3951      * Returns the {@code onsearch} event handler.
3952      * @return the {@code onsearch} event handler
3953      */
3954     @JsxGetter(CHROME)
3955     public Function getOnsearch() {
3956         return getEventHandler("search");
3957     }
3958 
3959     /**
3960      * Sets the {@code onsearch} event handler.
3961      * @param onsearch the {@code onsearch} event handler
3962      */
3963     @JsxSetter(CHROME)
3964     public void setOnsearch(final Object onsearch) {
3965         setHandlerForJavaScript("search", onsearch);
3966     }
3967 
3968     /**
3969      * Returns the {@code oninput} event handler.
3970      * @return the {@code oninput} event handler
3971      */
3972     @JsxGetter
3973     public Function getOninput() {
3974         return getEventHandler("input");
3975     }
3976 
3977     /**
3978      * Sets the {@code oninput} event handler.
3979      * @param oninput the {@code oninput} event handler
3980      */
3981     @JsxSetter
3982     public void setOninput(final Object oninput) {
3983         setHandlerForJavaScript("input", oninput);
3984     }
3985 
3986     /**
3987      * Returns the {@code onmozpointerlockerror} event handler.
3988      * @return the {@code onmozpointerlockerror} event handler
3989      */
3990     @JsxGetter(FF45)
3991     public Function getOnmozpointerlockerror() {
3992         return getEventHandler("mozpointerlockerror");
3993     }
3994 
3995     /**
3996      * Sets the {@code onmozpointerlockerror} event handler.
3997      * @param onmozpointerlockerror the {@code onmozpointerlockerror} event handler
3998      */
3999     @JsxSetter(FF45)
4000     public void setOnmozpointerlockerror(final Object onmozpointerlockerror) {
4001         setHandlerForJavaScript("mozpointerlockerror", onmozpointerlockerror);
4002     }
4003 
4004     /**
4005      * Returns the {@code onwebkittransitionend} event handler.
4006      * @return the {@code onwebkittransitionend} event handler
4007      */
4008     @JsxGetter({CHROME, FF52})
4009     public Function getOnwebkittransitionend() {
4010         return getEventHandler("webkittransitionend");
4011     }
4012 
4013     /**
4014      * Sets the {@code onwebkittransitionend} event handler.
4015      * @param onwebkittransitionend the {@code onwebkittransitionend} event handler
4016      */
4017     @JsxSetter({CHROME, FF52})
4018     public void setOnwebkittransitionend(final Object onwebkittransitionend) {
4019         setHandlerForJavaScript("webkittransitionend", onwebkittransitionend);
4020     }
4021 
4022     /**
4023      * Returns the {@code onmspointerout} event handler.
4024      * @return the {@code onmspointerout} event handler
4025      */
4026     @JsxGetter(IE)
4027     public Function getOnmspointerout() {
4028         return getEventHandler("mspointerout");
4029     }
4030 
4031     /**
4032      * Sets the {@code onmspointerout} event handler.
4033      * @param onmspointerout the {@code onmspointerout} event handler
4034      */
4035     @JsxSetter(IE)
4036     public void setOnmspointerout(final Object onmspointerout) {
4037         setHandlerForJavaScript("mspointerout", onmspointerout);
4038     }
4039 
4040     /**
4041      * Returns the {@code ondevicemotion} event handler.
4042      * @return the {@code ondevicemotion} event handler
4043      */
4044     @JsxGetter({CHROME, FF})
4045     public Function getOndevicemotion() {
4046         return getEventHandler("devicemotion");
4047     }
4048 
4049     /**
4050      * Sets the {@code ondevicemotion} event handler.
4051      * @param ondevicemotion the {@code ondevicemotion} event handler
4052      */
4053     @JsxSetter({CHROME, FF})
4054     public void setOndevicemotion(final Object ondevicemotion) {
4055         setHandlerForJavaScript("devicemotion", ondevicemotion);
4056     }
4057 
4058     /**
4059      * Returns the {@code onstalled} event handler.
4060      * @return the {@code onstalled} event handler
4061      */
4062     @JsxGetter
4063     public Function getOnstalled() {
4064         return getEventHandler("stalled");
4065     }
4066 
4067     /**
4068      * Sets the {@code onstalled} event handler.
4069      * @param onstalled the {@code onstalled} event handler
4070      */
4071     @JsxSetter
4072     public void setOnstalled(final Object onstalled) {
4073         setHandlerForJavaScript("stalled", onstalled);
4074     }
4075 
4076     /**
4077      * Returns the {@code onmouseenter} event handler.
4078      * @return the {@code onmouseenter} event handler
4079      */
4080     @JsxGetter
4081     public Function getOnmouseenter() {
4082         return getEventHandler("mouseenter");
4083     }
4084 
4085     /**
4086      * Sets the {@code onmouseenter} event handler.
4087      * @param onmouseenter the {@code onmouseenter} event handler
4088      */
4089     @JsxSetter
4090     public void setOnmouseenter(final Object onmouseenter) {
4091         setHandlerForJavaScript("mouseenter", onmouseenter);
4092     }
4093 
4094     /**
4095      * Returns the {@code ondragleave} event handler.
4096      * @return the {@code ondragleave} event handler
4097      */
4098     @JsxGetter
4099     public Function getOndragleave() {
4100         return getEventHandler("dragleave");
4101     }
4102 
4103     /**
4104      * Sets the {@code ondragleave} event handler.
4105      * @param ondragleave the {@code ondragleave} event handler
4106      */
4107     @JsxSetter
4108     public void setOndragleave(final Object ondragleave) {
4109         setHandlerForJavaScript("dragleave", ondragleave);
4110     }
4111 
4112     /**
4113      * Returns the {@code onpointerdown} event handler.
4114      * @return the {@code onpointerdown} event handler
4115      */
4116     @JsxGetter({CHROME, IE})
4117     public Function getOnpointerdown() {
4118         return getEventHandler("pointerdown");
4119     }
4120 
4121     /**
4122      * Sets the {@code onpointerdown} event handler.
4123      * @param onpointerdown the {@code onpointerdown} event handler
4124      */
4125     @JsxSetter({CHROME, IE})
4126     public void setOnpointerdown(final Object onpointerdown) {
4127         setHandlerForJavaScript("pointerdown", onpointerdown);
4128     }
4129 
4130     /**
4131      * Returns the {@code ondrop} event handler.
4132      * @return the {@code ondrop} event handler
4133      */
4134     @JsxGetter
4135     public Function getOndrop() {
4136         return getEventHandler("drop");
4137     }
4138 
4139     /**
4140      * Sets the {@code ondrop} event handler.
4141      * @param ondrop the {@code ondrop} event handler
4142      */
4143     @JsxSetter
4144     public void setOndrop(final Object ondrop) {
4145         setHandlerForJavaScript("drop", ondrop);
4146     }
4147 
4148     /**
4149      * Returns the {@code onunload} event handler.
4150      * @return the {@code onunload} event handler
4151      */
4152     @JsxGetter
4153     public Function getOnunload() {
4154         return getEventHandler("unload");
4155     }
4156 
4157     /**
4158      * Sets the {@code onunload} event handler.
4159      * @param onunload the {@code onunload} event handler
4160      */
4161     @JsxSetter
4162     public void setOnunload(final Object onunload) {
4163         setHandlerForJavaScript("unload", onunload);
4164     }
4165 
4166     /**
4167      * Returns the {@code onwebkitanimationend} event handler.
4168      * @return the {@code onwebkitanimationend} event handler
4169      */
4170     @JsxGetter({CHROME, FF52})
4171     public Function getOnwebkitanimationend() {
4172         return getEventHandler("webkitanimationend");
4173     }
4174 
4175     /**
4176      * Sets the {@code onwebkitanimationend} event handler.
4177      * @param onwebkitanimationend the {@code onwebkitanimationend} event handler
4178      */
4179     @JsxSetter({CHROME, FF52})
4180     public void setOnwebkitanimationend(final Object onwebkitanimationend) {
4181         setHandlerForJavaScript("webkitanimationend", onwebkitanimationend);
4182     }
4183 
4184     /**
4185      * Returns the {@code ondragstart} event handler.
4186      * @return the {@code ondragstart} event handler
4187      */
4188     @JsxGetter
4189     public Function getOndragstart() {
4190         return getEventHandler("dragstart");
4191     }
4192 
4193     /**
4194      * Sets the {@code ondragstart} event handler.
4195      * @param ondragstart the {@code ondragstart} event handler
4196      */
4197     @JsxSetter
4198     public void setOndragstart(final Object ondragstart) {
4199         setHandlerForJavaScript("dragstart", ondragstart);
4200     }
4201 
4202     /**
4203      * Returns the {@code ontransitionend} event handler.
4204      * @return the {@code ontransitionend} event handler
4205      */
4206     @JsxGetter({CHROME, FF52})
4207     public Function getOntransitionend() {
4208         return getEventHandler("transitionend");
4209     }
4210 
4211     /**
4212      * Sets the {@code ontransitionend} event handler.
4213      * @param ontransitionend the {@code ontransitionend} event handler
4214      */
4215     @JsxSetter({CHROME, FF52})
4216     public void setOntransitionend(final Object ontransitionend) {
4217         setHandlerForJavaScript("transitionend", ontransitionend);
4218     }
4219 
4220     /**
4221      * Returns the {@code onmsgesturehold} event handler.
4222      * @return the {@code onmsgesturehold} event handler
4223      */
4224     @JsxGetter(IE)
4225     public Function getOnmsgesturehold() {
4226         return getEventHandler("msgesturehold");
4227     }
4228 
4229     /**
4230      * Sets the {@code onmsgesturehold} event handler.
4231      * @param onmsgesturehold the {@code onmsgesturehold} event handler
4232      */
4233     @JsxSetter(IE)
4234     public void setOnmsgesturehold(final Object onmsgesturehold) {
4235         setHandlerForJavaScript("msgesturehold", onmsgesturehold);
4236     }
4237 
4238     /**
4239      * Returns the {@code ondeviceorientationabsolute} event handler.
4240      * @return the {@code ondeviceorientationabsolute} event handler
4241      */
4242     @JsxGetter(CHROME)
4243     public Function getOndeviceorientationabsolute() {
4244         return getEventHandler("deviceorientationabsolute");
4245     }
4246 
4247     /**
4248      * Sets the {@code ondeviceorientationabsolute} event handler.
4249      * @param ondeviceorientationabsolute the {@code ondeviceorientationabsolute} event handler
4250      */
4251     @JsxSetter(CHROME)
4252     public void setOndeviceorientationabsolute(final Object ondeviceorientationabsolute) {
4253         setHandlerForJavaScript("deviceorientationabsolute", ondeviceorientationabsolute);
4254     }
4255 
4256     /**
4257      * Returns the {@code onshow} event handler.
4258      * @return the {@code onshow} event handler
4259      */
4260     @JsxGetter({CHROME, FF})
4261     public Function getOnshow() {
4262         return getEventHandler("show");
4263     }
4264 
4265     /**
4266      * Sets the {@code onshow} event handler.
4267      * @param onshow the {@code onshow} event handler
4268      */
4269     @JsxSetter({CHROME, FF})
4270     public void setOnshow(final Object onshow) {
4271         setHandlerForJavaScript("show", onshow);
4272     }
4273 
4274     /**
4275      * Returns the {@code onvolumechange} event handler.
4276      * @return the {@code onvolumechange} event handler
4277      */
4278     @JsxGetter
4279     public Function getOnvolumechange() {
4280         return getEventHandler("volumechange");
4281     }
4282 
4283     /**
4284      * Sets the {@code onvolumechange} event handler.
4285      * @param onvolumechange the {@code onvolumechange} event handler
4286      */
4287     @JsxSetter
4288     public void setOnvolumechange(final Object onvolumechange) {
4289         setHandlerForJavaScript("volumechange", onvolumechange);
4290     }
4291 
4292     /**
4293      * Returns the {@code onmsgesturechange} event handler.
4294      * @return the {@code onmsgesturechange} event handler
4295      */
4296     @JsxGetter(IE)
4297     public Function getOnmsgesturechange() {
4298         return getEventHandler("msgesturechange");
4299     }
4300 
4301     /**
4302      * Sets the {@code onmsgesturechange} event handler.
4303      * @param onmsgesturechange the {@code onmsgesturechange} event handler
4304      */
4305     @JsxSetter(IE)
4306     public void setOnmsgesturechange(final Object onmsgesturechange) {
4307         setHandlerForJavaScript("msgesturechange", onmsgesturechange);
4308     }
4309 
4310     /**
4311      * Returns the {@code ongotpointercapture} event handler.
4312      * @return the {@code ongotpointercapture} event handler
4313      */
4314     @JsxGetter(CHROME)
4315     public Function getOngotpointercapture() {
4316         return getEventHandler("gotpointercapture");
4317     }
4318 
4319     /**
4320      * Sets the {@code ongotpointercapture} event handler.
4321      * @param ongotpointercapture the {@code ongotpointercapture} event handler
4322      */
4323     @JsxSetter(CHROME)
4324     public void setOngotpointercapture(final Object ongotpointercapture) {
4325         setHandlerForJavaScript("gotpointercapture", ongotpointercapture);
4326     }
4327 
4328     /**
4329      * Returns the {@code onpopstate} event handler.
4330      * @return the {@code onpopstate} event handler
4331      */
4332     @JsxGetter
4333     public Function getOnpopstate() {
4334         return getEventHandler("popstate");
4335     }
4336 
4337     /**
4338      * Sets the {@code onpopstate} event handler.
4339      * @param onpopstate the {@code onpopstate} event handler
4340      */
4341     @JsxSetter
4342     public void setOnpopstate(final Object onpopstate) {
4343         setHandlerForJavaScript("popstate", onpopstate);
4344     }
4345 
4346     /**
4347      * Returns the {@code onabsolutedeviceorientation} event handler.
4348      * @return the {@code onabsolutedeviceorientation} event handler
4349      */
4350     @JsxGetter(FF52)
4351     public Function getOnabsolutedeviceorientation() {
4352         return getEventHandler("absolutedeviceorientation");
4353     }
4354 
4355     /**
4356      * Sets the {@code onabsolutedeviceorientation} event handler.
4357      * @param absolutedeviceorientation the {@code onabsolutedeviceorientation} event handler
4358      */
4359     @JsxSetter(FF52)
4360     public void setOnabsolutedeviceorientation(final Object absolutedeviceorientation) {
4361         setEventHandler("absolutedeviceorientation", absolutedeviceorientation);
4362     }
4363 
4364     /**
4365      * Returns the {@code ondragexit} event handler.
4366      * @return the {@code ondragexit} event handler
4367      */
4368     @JsxGetter(FF52)
4369     public Function getOndragexit() {
4370         return getEventHandler("dragexit");
4371     }
4372 
4373     /**
4374      * Sets the {@code ondragexit} event handler.
4375      * @param dragexit the {@code ondragexit} event handler
4376      */
4377     @JsxSetter(FF52)
4378     public void setOndragexit(final Object dragexit) {
4379         setEventHandler("dragexit", dragexit);
4380     }
4381 
4382     /**
4383      * Returns the {@code onloadend} event handler.
4384      * @return the {@code onloadend} event handler
4385      */
4386     @JsxGetter(FF52)
4387     public Function getOnloadend() {
4388         return getEventHandler("loadend");
4389     }
4390 
4391     /**
4392      * Sets the {@code onloadend} event handler.
4393      * @param loadend the {@code onloadend} event handler
4394      */
4395     @JsxSetter(FF52)
4396     public void setOnloadend(final Object loadend) {
4397         setEventHandler("loadend", loadend);
4398     }
4399 
4400     /**
4401      * Returns the {@code onselectstart} event handler.
4402      * @return the {@code onselectstart} event handler
4403      */
4404     @JsxGetter(FF52)
4405     public Function getOnselectstart() {
4406         return getEventHandler("selectstart");
4407     }
4408 
4409     /**
4410      * Sets the {@code onselectstart} event handler.
4411      * @param selectstart the {@code onselectstart} event handler
4412      */
4413     @JsxSetter(FF52)
4414     public void setOnselectstart(final Object selectstart) {
4415         setEventHandler("selectstart", selectstart);
4416     }
4417 
4418 }
4419 
4420 class HTMLCollectionFrames extends HTMLCollection {
4421     private static final Log LOG = LogFactory.getLog(HTMLCollectionFrames.class);
4422 
4423     HTMLCollectionFrames(final HtmlPage page) {
4424         super(page, false);
4425     }
4426 
4427     @Override
4428     protected boolean isMatching(final DomNode node) {
4429         return node instanceof BaseFrameElement;
4430     }
4431 
4432     @Override
4433     protected Scriptable getScriptableForElement(final Object obj) {
4434         final WebWindow window;
4435         if (obj instanceof BaseFrameElement) {
4436             window = ((BaseFrameElement) obj).getEnclosedWindow();
4437         }
4438         else {
4439             window = ((FrameWindow) obj).getFrameElement().getEnclosedWindow();
4440         }
4441 
4442         return window.getScriptableObject();
4443     }
4444 
4445     @Override
4446     protected Object getWithPreemption(final String name) {
4447         final List<DomNode> elements = getElements();
4448 
4449         for (final Object next : elements) {
4450             final BaseFrameElement frameElt = (BaseFrameElement) next;
4451             final WebWindow window = frameElt.getEnclosedWindow();
4452             if (name.equals(window.getName())) {
4453                 if (LOG.isDebugEnabled()) {
4454                     LOG.debug("Property \"" + name + "\" evaluated (by name) to " + window);
4455                 }
4456                 return getScriptableForElement(window);
4457             }
4458             if (getBrowserVersion().hasFeature(JS_WINDOW_FRAMES_ACCESSIBLE_BY_ID) && frameElt.getId().equals(name)) {
4459                 if (LOG.isDebugEnabled()) {
4460                     LOG.debug("Property \"" + name + "\" evaluated (by id) to " + window);
4461                 }
4462                 return getScriptableForElement(window);
4463             }
4464         }
4465 
4466         return NOT_FOUND;
4467     }
4468 
4469     @Override
4470     protected void addElementIds(final List<String> idList, final List<DomNode> elements) {
4471         for (final DomNode next : elements) {
4472             final BaseFrameElement frameElt = (BaseFrameElement) next;
4473             final WebWindow window = frameElt.getEnclosedWindow();
4474             final String windowName = window.getName();
4475             if (windowName != null) {
4476                 idList.add(windowName);
4477             }
4478         }
4479     }
4480 
4481 }