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