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