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