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