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