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