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 final HtmlPage page = (HtmlPage) domNode.getPage();
1464 Object result = getFrameWindowByName(page, name);
1465
1466 if (result == NOT_FOUND) {
1467 result = getElementsByName(page, name);
1468
1469 if (result == NOT_FOUND) {
1470
1471 try {
1472 final HtmlElement htmlElement = page.getHtmlElementById(name);
1473 result = getScriptableFor(htmlElement);
1474 }
1475 catch (final ElementNotFoundException e) {
1476 result = NOT_FOUND;
1477 }
1478 }
1479 }
1480
1481 if (result instanceof Window) {
1482 final WebWindow webWindow = ((Window) result).getWebWindow();
1483 result = getProxy(webWindow);
1484 }
1485
1486 return result;
1487 }
1488
1489
1490
1491
1492 @Override
1493 public Object get(final int index, final Scriptable start) {
1494 if (index < 0 || getWebWindow() == null) {
1495 return JavaScriptEngine.UNDEFINED;
1496 }
1497
1498 final HTMLCollection frames = getFrames();
1499 if (frames == null || index >= frames.getLength()) {
1500 return JavaScriptEngine.UNDEFINED;
1501 }
1502 return frames.item(Integer.valueOf(index));
1503 }
1504
1505 private static Object getFrameWindowByName(final HtmlPage page, final String name) {
1506 try {
1507 return page.getFrameByName(name).getScriptableObject();
1508 }
1509 catch (final ElementNotFoundException e) {
1510 return NOT_FOUND;
1511 }
1512 }
1513
1514 private Object getElementsByName(final HtmlPage page, final String name) {
1515
1516
1517
1518
1519
1520
1521 final List<DomElement> elements = page.getElementsByName(name);
1522
1523 final Filter filter = new Filter(false);
1524
1525 elements.removeIf(domElement -> !filter.matches(domElement));
1526
1527 if (elements.isEmpty()) {
1528 return NOT_FOUND;
1529 }
1530
1531 if (elements.size() == 1) {
1532 return getScriptableFor(elements.get(0));
1533 }
1534
1535
1536 final String expElementName = "null".equals(name) ? "" : name;
1537
1538 final HTMLCollection coll = new HTMLCollection(page, true);
1539 coll.setElementsSupplier(
1540 (Supplier<List<DomNode>> & Serializable)
1541 () -> {
1542 final List<DomElement> expElements = page.getElementsByName(expElementName);
1543 final List<DomNode> result = new ArrayList<>(expElements.size());
1544
1545 for (final DomElement domElement : expElements) {
1546 if (filter.matches(domElement)) {
1547 result.add(domElement);
1548 }
1549 }
1550 return result;
1551 });
1552
1553 coll.setEffectOnCacheFunction(
1554 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1555 event -> {
1556 if ("name".equals(event.getName())) {
1557 return EffectOnCache.RESET;
1558 }
1559 return EffectOnCache.NONE;
1560 });
1561
1562 return coll;
1563 }
1564
1565
1566
1567
1568
1569
1570 public static WindowProxy getProxy(final WebWindow w) {
1571 return ((Window) w.getScriptableObject()).windowProxy_;
1572 }
1573
1574
1575
1576
1577
1578 @JsxGetter
1579 public String getStatus() {
1580 return status_;
1581 }
1582
1583
1584
1585
1586
1587 @JsxSetter
1588 public void setStatus(final String message) {
1589 status_ = message;
1590
1591 final StatusHandler statusHandler = webWindow_.getWebClient().getStatusHandler();
1592 if (statusHandler != null) {
1593 statusHandler.statusMessageChanged(webWindow_.getEnclosedPage(), message);
1594 }
1595 }
1596
1597
1598
1599
1600
1601
1602 @JsxGetter
1603 public int getInnerWidth() {
1604 return getWebWindow().getInnerWidth();
1605 }
1606
1607
1608
1609
1610
1611 @JsxSetter
1612 public void setInnerWidth(final int width) {
1613 getWebWindow().setInnerWidth(width);
1614 }
1615
1616
1617
1618
1619
1620
1621 @JsxGetter
1622 public int getOuterWidth() {
1623 return getWebWindow().getOuterWidth();
1624 }
1625
1626
1627
1628
1629
1630 @JsxSetter
1631 public void setOuterWidth(final int width) {
1632 getWebWindow().setOuterWidth(width);
1633 }
1634
1635
1636
1637
1638
1639
1640 @JsxGetter
1641 public int getInnerHeight() {
1642 return getWebWindow().getInnerHeight();
1643 }
1644
1645
1646
1647
1648
1649 @JsxSetter
1650 public void setInnerHeight(final int height) {
1651 getWebWindow().setInnerHeight(height);
1652 }
1653
1654
1655
1656
1657
1658
1659 @JsxGetter
1660 public int getOuterHeight() {
1661 return getWebWindow().getOuterHeight();
1662 }
1663
1664
1665
1666
1667
1668 @JsxSetter
1669 public void setOuterHeight(final int height) {
1670 getWebWindow().setOuterHeight(height);
1671 }
1672
1673
1674
1675
1676
1677
1678
1679
1680 @JsxFunction
1681 public void print() {
1682 final PrintHandler handler = getWebWindow().getWebClient().getPrintHandler();
1683 if (handler == null) {
1684 LOG.info("No PrintHandler installed - window.print() ignored");
1685 return;
1686 }
1687
1688 final SgmlPage sgmlPage = getDocument().getPage();
1689 if (!(sgmlPage instanceof HtmlPage)) {
1690 LOG.debug("Page is not an HtmlPage - window.print() ignored");
1691 return;
1692 }
1693
1694 Event event = new Event(this, Event.TYPE_BEFOREPRINT);
1695 fireEvent(event);
1696
1697 final HtmlPage page = (HtmlPage) sgmlPage;
1698 page.setPrinting(true);
1699 try {
1700 handler.handlePrint(page);
1701 }
1702 finally {
1703 page.setPrinting(false);
1704 }
1705 event = new Event(this, Event.TYPE_AFTERPRINT);
1706 fireEvent(event);
1707 }
1708
1709
1710
1711
1712
1713
1714 @JsxFunction
1715 public void captureEvents(final String type) {
1716
1717 }
1718
1719
1720
1721
1722
1723
1724 @JsxFunction
1725 public void releaseEvents(final String type) {
1726
1727 }
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739 @JsxFunction
1740 public ComputedCSSStyleDeclaration getComputedStyle(final Object element, final String pseudoElement) {
1741 if (!(element instanceof Element)) {
1742 throw JavaScriptEngine.typeError("parameter 1 is not of type 'Element'");
1743 }
1744 final Element e = (Element) element;
1745
1746 final ComputedCssStyleDeclaration style = getWebWindow().getComputedStyle(e.getDomNodeOrDie(), pseudoElement);
1747 return new ComputedCSSStyleDeclaration(e, style);
1748 }
1749
1750
1751
1752
1753
1754 @JsxFunction
1755 public Selection getSelection() {
1756 final WebWindow webWindow = getWebWindow();
1757
1758 if (webWindow instanceof FrameWindow) {
1759 final FrameWindow frameWindow = (FrameWindow) webWindow;
1760 if (getBrowserVersion().hasFeature(JS_WINDOW_SELECTION_NULL_IF_INVISIBLE)
1761 && !frameWindow.getFrameElement().isDisplayed()) {
1762 return null;
1763 }
1764 }
1765 return getSelectionImpl();
1766 }
1767
1768
1769
1770
1771
1772 public Selection getSelectionImpl() {
1773 if (selection_ == null) {
1774 selection_ = new Selection();
1775 selection_.setParentScope(this);
1776 selection_.setPrototype(getPrototype(selection_.getClass()));
1777 }
1778 return selection_;
1779 }
1780
1781
1782
1783
1784
1785
1786
1787 @JsxGetter({FF, FF_ESR})
1788 public Object getControllers() {
1789 return controllers_;
1790 }
1791
1792
1793
1794
1795
1796 @JsxSetter({FF, FF_ESR})
1797 public void setControllers(final Object value) {
1798 controllers_ = value;
1799 }
1800
1801
1802
1803
1804
1805 @JsxGetter(FF)
1806 public int getMozInnerScreenX() {
1807 return 12;
1808 }
1809
1810
1811
1812
1813
1814 @JsxGetter(value = FF_ESR, propertyName = "mozInnerScreenX")
1815 public int getMozInnerScreenXffesr_js() {
1816 return 10;
1817 }
1818
1819
1820
1821
1822
1823 @JsxGetter({FF, FF_ESR})
1824 public int getMozInnerScreenY() {
1825 return 89;
1826 }
1827
1828 private static final class Filter {
1829 private final boolean includeFormFields_;
1830
1831 Filter(final boolean includeFormFields) {
1832 includeFormFields_ = includeFormFields;
1833 }
1834
1835 boolean matches(final Object object) {
1836 if (object instanceof HtmlEmbed
1837 || object instanceof HtmlForm
1838 || object instanceof HtmlImage
1839 || object instanceof HtmlObject) {
1840 return true;
1841 }
1842
1843 return includeFormFields_
1844 && (object instanceof HtmlAnchor
1845 || object instanceof HtmlButton
1846 || object instanceof HtmlInput
1847 || object instanceof HtmlMap
1848 || object instanceof HtmlSelect
1849 || object instanceof HtmlTextArea);
1850 }
1851 }
1852
1853
1854
1855
1856
1857
1858 @JsxFunction
1859 public void stop() {
1860
1861 }
1862
1863
1864
1865
1866
1867 @JsxGetter
1868 public int getPageXOffset() {
1869 return 0;
1870 }
1871
1872
1873
1874
1875
1876 @JsxGetter
1877 public int getPageYOffset() {
1878 return 0;
1879 }
1880
1881
1882
1883
1884
1885 @JsxGetter
1886 public int getScrollX() {
1887 return 0;
1888 }
1889
1890
1891
1892
1893
1894 @JsxGetter
1895 public int getScrollY() {
1896 return 0;
1897 }
1898
1899
1900
1901
1902 @JsxGetter({FF, FF_ESR})
1903 public Netscape getNetscape() {
1904 return new Netscape(this);
1905 }
1906
1907
1908
1909
1910
1911 @Override
1912 public boolean isConst(final String name) {
1913 if ("undefined".equals(name) || "Infinity".equals(name) || "NaN".equals(name)) {
1914 return false;
1915 }
1916
1917 return super.isConst(name);
1918 }
1919
1920
1921
1922
1923 @Override
1924 public boolean dispatchEvent(final Event event) {
1925 event.setTarget(this);
1926 final ScriptResult result = fireEvent(event);
1927 return !event.isAborted(result);
1928 }
1929
1930
1931
1932
1933
1934 @JsxGetter
1935 public Function getOnchange() {
1936 return getEventHandler(Event.TYPE_CHANGE);
1937 }
1938
1939
1940
1941
1942
1943 @JsxSetter
1944 public void setOnchange(final Object onchange) {
1945 setHandlerForJavaScript(Event.TYPE_CHANGE, onchange);
1946 }
1947
1948
1949
1950
1951
1952 @JsxGetter
1953 public Function getOnsubmit() {
1954 return getEventHandler(Event.TYPE_SUBMIT);
1955 }
1956
1957
1958
1959
1960
1961 @JsxSetter
1962 public void setOnsubmit(final Object onsubmit) {
1963 setHandlerForJavaScript(Event.TYPE_SUBMIT, onsubmit);
1964 }
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975 @JsxFunction
1976 public static void postMessage(final Context context, final Scriptable scope,
1977 final Scriptable thisObj, final Object[] args, final Function funObj) {
1978
1979
1980 if (args.length < 1) {
1981 throw JavaScriptEngine.typeError("message not provided");
1982 }
1983 final Object message = args[0];
1984
1985 String targetOrigin = "*";
1986 if (args.length > 1) {
1987 targetOrigin = JavaScriptEngine.toString(args[1]);
1988 }
1989
1990 Object transfer = JavaScriptEngine.UNDEFINED;
1991 if (args.length > 2) {
1992 transfer = args[2];
1993 }
1994
1995 final Window sender = (Window) scope;
1996 final Window receiver = (Window) thisObj;
1997 final URL receiverURL = receiver.getWebWindow().getEnclosedPage().getUrl();
1998
1999 final WebWindow webWindow = sender.getWebWindow();
2000 final Page page = webWindow.getEnclosedPage();
2001 final URL senderURL = page.getUrl();
2002
2003 if (!org.htmlunit.util.StringUtils.equalsChar('*', targetOrigin)) {
2004 final URL targetURL;
2005 if (org.htmlunit.util.StringUtils.equalsChar('/', targetOrigin)) {
2006 targetURL = senderURL;
2007 }
2008 else {
2009 try {
2010 targetURL = new URL(targetOrigin);
2011 }
2012 catch (final Exception e) {
2013 throw JavaScriptEngine.asJavaScriptException(
2014 (HtmlUnitScriptable) getTopLevelScope(thisObj),
2015 "Failed to execute 'postMessage' on 'Window': Invalid target origin '"
2016 + targetOrigin + "' was specified (reason: " + e.getMessage() + ".",
2017 DOMException.SYNTAX_ERR);
2018 }
2019 }
2020
2021 if (getPort(targetURL) != getPort(receiverURL)) {
2022 return;
2023 }
2024 if (!targetURL.getHost().equals(receiverURL.getHost())) {
2025 return;
2026 }
2027 if (!targetURL.getProtocol().equals(receiverURL.getProtocol())) {
2028 return;
2029 }
2030 }
2031
2032 String origin = "";
2033 try {
2034 final URL originUrl = UrlUtils.getUrlWithoutPathRefQuery(senderURL);
2035 origin = UrlUtils.removeRedundantPort(originUrl).toExternalForm();
2036 }
2037 catch (final MalformedURLException e) {
2038 throw JavaScriptEngine.throwAsScriptRuntimeEx(e);
2039 }
2040
2041 final MessageEvent event = new MessageEvent();
2042 event.initMessageEvent(Event.TYPE_MESSAGE, false, false, message, origin, "", sender, transfer);
2043 event.setParentScope(scope);
2044 event.setPrototype(receiver.getPrototype(event.getClass()));
2045
2046 final AbstractJavaScriptEngine<?> jsEngine = webWindow.getWebClient().getJavaScriptEngine();
2047 final PostponedAction action = new PostponedAction(page, "Window.postMessage") {
2048 @Override
2049 public void execute() {
2050 final HtmlUnitContextFactory cf = jsEngine.getContextFactory();
2051 cf.call(cx -> receiver.dispatchEvent(event));
2052 }
2053 };
2054 jsEngine.addPostponedAction(action);
2055 }
2056
2057
2058
2059
2060
2061
2062 public static int getPort(final URL url) {
2063 int port = url.getPort();
2064 if (port == -1) {
2065 if ("http".equals(url.getProtocol())) {
2066 port = 80;
2067 }
2068 else {
2069 port = 443;
2070 }
2071 }
2072 return port;
2073 }
2074
2075
2076
2077
2078
2079
2080
2081 @JsxGetter
2082 public Scriptable getPerformance() {
2083 if (performance_ == null) {
2084 final Performance performance = new Performance();
2085 performance.setParentScope(this);
2086 performance.setPrototype(getPrototype(performance.getClass()));
2087 performance_ = performance;
2088 }
2089 return performance_;
2090 }
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100 @JsxSetter
2101 public void setPerformance(final Scriptable performance) {
2102 performance_ = performance;
2103 }
2104
2105
2106
2107
2108
2109 @JsxGetter
2110 public int getDevicePixelRatio() {
2111 return 1;
2112 }
2113
2114
2115
2116
2117
2118 @JsxGetter({CHROME, EDGE})
2119 public StyleMedia getStyleMedia() {
2120 final StyleMedia styleMedia = new StyleMedia();
2121 styleMedia.setParentScope(this);
2122 styleMedia.setPrototype(getPrototype(styleMedia.getClass()));
2123 return styleMedia;
2124 }
2125
2126
2127
2128
2129
2130
2131
2132 @JsxFunction
2133 public MediaQueryList matchMedia(final String mediaQueryString) {
2134 final MediaQueryList mediaQueryList = new MediaQueryList(mediaQueryString);
2135 mediaQueryList.setParentScope(this);
2136 mediaQueryList.setPrototype(getPrototype(mediaQueryList.getClass()));
2137 return mediaQueryList;
2138 }
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151 @JsxFunction
2152 public boolean find(final String search, final boolean caseSensitive,
2153 final boolean backwards, final boolean wrapAround,
2154 final boolean wholeWord, final boolean searchInFrames, final boolean showDialog) {
2155 return false;
2156 }
2157
2158
2159
2160
2161
2162 @JsxGetter({CHROME, EDGE})
2163 public SpeechSynthesis getSpeechSynthesis() {
2164 final SpeechSynthesis speechSynthesis = new SpeechSynthesis();
2165 speechSynthesis.setParentScope(this);
2166 speechSynthesis.setPrototype(getPrototype(speechSynthesis.getClass()));
2167 return speechSynthesis;
2168 }
2169
2170
2171
2172
2173
2174 @JsxGetter({CHROME, EDGE})
2175 public boolean getOffscreenBuffering() {
2176 return true;
2177 }
2178
2179
2180
2181
2182
2183 @JsxGetter
2184 public Crypto getCrypto() {
2185 if (crypto_ == null) {
2186 crypto_ = new Crypto(this);
2187 }
2188 return crypto_;
2189 }
2190
2191
2192
2193
2194 @Override
2195 public void close() {
2196
2197 }
2198
2199
2200
2201
2202
2203 @Override
2204 public void setParentScope(final Scriptable parent) {
2205
2206 }
2207
2208
2209
2210
2211
2212 @JsxGetter
2213 public Function getOnfocus() {
2214 return getEventHandler(Event.TYPE_FOCUS);
2215 }
2216
2217
2218
2219
2220
2221 @JsxSetter
2222 public void setOnfocus(final Object onfocus) {
2223 setHandlerForJavaScript(Event.TYPE_FOCUS, onfocus);
2224 }
2225
2226
2227
2228
2229
2230 @JsxGetter
2231 public Function getOndragend() {
2232 return getEventHandler(Event.TYPE_DRAGEND);
2233 }
2234
2235
2236
2237
2238
2239 @JsxSetter
2240 public void setOndragend(final Object ondragend) {
2241 setHandlerForJavaScript(Event.TYPE_DRAGEND, ondragend);
2242 }
2243
2244
2245
2246
2247
2248 @JsxGetter
2249 public Function getOninvalid() {
2250 return getEventHandler(Event.TYPE_INVALID);
2251 }
2252
2253
2254
2255
2256
2257 @JsxSetter
2258 public void setOninvalid(final Object oninvalid) {
2259 setHandlerForJavaScript(Event.TYPE_INVALID, oninvalid);
2260 }
2261
2262
2263
2264
2265
2266 @JsxGetter({CHROME, EDGE})
2267 public Function getOnpointerout() {
2268 return getEventHandler(Event.TYPE_POINTEROUT);
2269 }
2270
2271
2272
2273
2274
2275 @JsxSetter({CHROME, EDGE})
2276 public void setOnpointerout(final Object onpointerout) {
2277 setHandlerForJavaScript(Event.TYPE_POINTEROUT, onpointerout);
2278 }
2279
2280
2281
2282
2283
2284 @JsxGetter
2285 public Function getOnratechange() {
2286 return getEventHandler(Event.TYPE_RATECHANGE);
2287 }
2288
2289
2290
2291
2292
2293 @JsxSetter
2294 public void setOnratechange(final Object onratechange) {
2295 setHandlerForJavaScript(Event.TYPE_RATECHANGE, onratechange);
2296 }
2297
2298
2299
2300
2301
2302 @JsxGetter
2303 public Function getOnanimationiteration() {
2304 return getEventHandler(Event.TYPE_ANIMATIONITERATION);
2305 }
2306
2307
2308
2309
2310
2311 @JsxSetter
2312 public void setOnanimationiteration(final Object onanimationiteration) {
2313 setHandlerForJavaScript(Event.TYPE_ANIMATIONITERATION, onanimationiteration);
2314 }
2315
2316
2317
2318
2319
2320 @JsxGetter
2321 public Function getOncanplaythrough() {
2322 return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2323 }
2324
2325
2326
2327
2328
2329 @JsxSetter
2330 public void setOncanplaythrough(final Object oncanplaythrough) {
2331 setHandlerForJavaScript(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2332 }
2333
2334
2335
2336
2337
2338 @JsxGetter({CHROME, EDGE})
2339 public Function getOncancel() {
2340 return getEventHandler(Event.TYPE_CANCEL);
2341 }
2342
2343
2344
2345
2346
2347 @JsxSetter({CHROME, EDGE})
2348 public void setOncancel(final Object oncancel) {
2349 setHandlerForJavaScript(Event.TYPE_CANCEL, oncancel);
2350 }
2351
2352
2353
2354
2355
2356 @JsxGetter({CHROME, EDGE})
2357 public Function getOnpointerenter() {
2358 return getEventHandler(Event.TYPE_POINTERENTER);
2359 }
2360
2361
2362
2363
2364
2365 @JsxSetter({CHROME, EDGE})
2366 public void setOnpointerenter(final Object onpointerenter) {
2367 setHandlerForJavaScript(Event.TYPE_POINTERENTER, onpointerenter);
2368 }
2369
2370
2371
2372
2373
2374 @JsxGetter
2375 public Function getOnselect() {
2376 return getEventHandler(Event.TYPE_SELECT);
2377 }
2378
2379
2380
2381
2382
2383 @JsxSetter
2384 public void setOnselect(final Object onselect) {
2385 setHandlerForJavaScript(Event.TYPE_SELECT, onselect);
2386 }
2387
2388
2389
2390
2391
2392 @JsxGetter({CHROME, EDGE})
2393 public Function getOnauxclick() {
2394 return getEventHandler(Event.TYPE_AUXCLICK);
2395 }
2396
2397
2398
2399
2400
2401 @JsxSetter({CHROME, EDGE})
2402 public void setOnauxclick(final Object onauxclick) {
2403 setHandlerForJavaScript(Event.TYPE_AUXCLICK, onauxclick);
2404 }
2405
2406
2407
2408
2409
2410 @JsxGetter
2411 public Function getOnscroll() {
2412 return getEventHandler(Event.TYPE_SCROLL);
2413 }
2414
2415
2416
2417
2418
2419 @JsxSetter
2420 public void setOnscroll(final Object onscroll) {
2421 setHandlerForJavaScript(Event.TYPE_SCROLL, onscroll);
2422 }
2423
2424
2425
2426
2427
2428 @JsxGetter
2429 public Function getOnkeydown() {
2430 return getEventHandler(Event.TYPE_KEY_DOWN);
2431 }
2432
2433
2434
2435
2436
2437 @JsxSetter
2438 public void setOnkeydown(final Object onkeydown) {
2439 setHandlerForJavaScript(Event.TYPE_KEY_DOWN, onkeydown);
2440 }
2441
2442
2443
2444
2445
2446 @JsxGetter({CHROME, EDGE})
2447 public Function getOnwebkitanimationstart() {
2448 return getEventHandler(Event.TYPE_WEBANIMATIONSTART);
2449 }
2450
2451
2452
2453
2454
2455 @JsxSetter({CHROME, EDGE})
2456 public void setOnwebkitanimationstart(final Object onwebkitanimationstart) {
2457 setHandlerForJavaScript(Event.TYPE_WEBANIMATIONSTART, onwebkitanimationstart);
2458 }
2459
2460
2461
2462
2463
2464 @JsxGetter
2465 public Function getOnkeyup() {
2466 return getEventHandler(Event.TYPE_KEY_UP);
2467 }
2468
2469
2470
2471
2472
2473 @JsxSetter
2474 public void setOnkeyup(final Object onkeyup) {
2475 setHandlerForJavaScript(Event.TYPE_KEY_UP, onkeyup);
2476 }
2477
2478
2479
2480
2481
2482 @JsxGetter
2483 public Function getOnreset() {
2484 return getEventHandler(Event.TYPE_RESET);
2485 }
2486
2487
2488
2489
2490
2491 @JsxSetter
2492 public void setOnreset(final Object onreset) {
2493 setHandlerForJavaScript(Event.TYPE_RESET, onreset);
2494 }
2495
2496
2497
2498
2499
2500 @JsxGetter
2501 public Function getOnkeypress() {
2502 return getEventHandler(Event.TYPE_KEY_PRESS);
2503 }
2504
2505
2506
2507
2508
2509 @JsxSetter
2510 public void setOnkeypress(final Object onkeypress) {
2511 setHandlerForJavaScript(Event.TYPE_KEY_PRESS, onkeypress);
2512 }
2513
2514
2515
2516
2517
2518 @JsxGetter
2519 public Function getOndrag() {
2520 return getEventHandler(Event.TYPE_DRAG);
2521 }
2522
2523
2524
2525
2526
2527 @JsxSetter
2528 public void setOndrag(final Object ondrag) {
2529 setHandlerForJavaScript(Event.TYPE_DRAG, ondrag);
2530 }
2531
2532
2533
2534
2535
2536 @JsxGetter
2537 public Function getOnseeked() {
2538 return getEventHandler(Event.TYPE_SEEKED);
2539 }
2540
2541
2542
2543
2544
2545 @JsxSetter
2546 public void setOnseeked(final Object onseeked) {
2547 setHandlerForJavaScript(Event.TYPE_SEEKED, onseeked);
2548 }
2549
2550
2551
2552
2553
2554 @JsxGetter
2555 public Function getOnoffline() {
2556 return getEventHandler(Event.TYPE_OFFLINE);
2557 }
2558
2559
2560
2561
2562
2563 @JsxSetter
2564 public void setOnoffline(final Object onoffline) {
2565 setHandlerForJavaScript(Event.TYPE_OFFLINE, onoffline);
2566 }
2567
2568
2569
2570
2571
2572 @JsxGetter
2573 public Function getOndeviceorientation() {
2574 return getEventHandler(Event.TYPE_DEVICEORIENTATION);
2575 }
2576
2577
2578
2579
2580
2581 @JsxSetter
2582 public void setOndeviceorientation(final Object ondeviceorientation) {
2583 setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATION, ondeviceorientation);
2584 }
2585
2586
2587
2588
2589
2590 @JsxGetter({CHROME, EDGE})
2591 public Function getOntoggle() {
2592 return getEventHandler(Event.TYPE_TOGGLE);
2593 }
2594
2595
2596
2597
2598
2599 @JsxSetter({CHROME, EDGE})
2600 public void setOntoggle(final Object ontoggle) {
2601 setHandlerForJavaScript(Event.TYPE_TOGGLE, ontoggle);
2602 }
2603
2604
2605
2606
2607
2608 @JsxGetter
2609 public Function getOnplay() {
2610 return getEventHandler(Event.TYPE_PLAY);
2611 }
2612
2613
2614
2615
2616
2617 @JsxSetter
2618 public void setOnplay(final Object onplay) {
2619 setHandlerForJavaScript(Event.TYPE_PLAY, onplay);
2620 }
2621
2622
2623
2624
2625
2626 @JsxGetter
2627 public Function getOncontextmenu() {
2628 return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
2629 }
2630
2631
2632
2633
2634
2635 @JsxSetter
2636 public void setOncontextmenu(final Object oncontextmenu) {
2637 setHandlerForJavaScript(MouseEvent.TYPE_CONTEXT_MENU, oncontextmenu);
2638 }
2639
2640
2641
2642
2643
2644 @JsxGetter
2645 public Function getOnmousemove() {
2646 return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
2647 }
2648
2649
2650
2651
2652
2653 @JsxSetter
2654 public void setOnmousemove(final Object onmousemove) {
2655 setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_MOVE, onmousemove);
2656 }
2657
2658
2659
2660
2661
2662 @JsxGetter({CHROME, EDGE})
2663 public Function getOnpointermove() {
2664 return getEventHandler(Event.TYPE_POINTERMOVE);
2665 }
2666
2667
2668
2669
2670
2671 @JsxSetter({CHROME, EDGE})
2672 public void setOnpointermove(final Object onpointermove) {
2673 setHandlerForJavaScript(Event.TYPE_POINTERMOVE, onpointermove);
2674 }
2675
2676
2677
2678
2679
2680 @JsxGetter
2681 public Function getOnmouseover() {
2682 return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
2683 }
2684
2685
2686
2687
2688
2689 @JsxSetter
2690 public void setOnmouseover(final Object onmouseover) {
2691 setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OVER, onmouseover);
2692 }
2693
2694
2695
2696
2697
2698 @JsxGetter({CHROME, EDGE})
2699 public Function getOnlostpointercapture() {
2700 return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2701 }
2702
2703
2704
2705
2706
2707 @JsxSetter({CHROME, EDGE})
2708 public void setOnlostpointercapture(final Object onlostpointercapture) {
2709 setHandlerForJavaScript(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2710 }
2711
2712
2713
2714
2715
2716 @JsxGetter({CHROME, EDGE})
2717 public Function getOnpointerover() {
2718 return getEventHandler(Event.TYPE_POINTEROVER);
2719 }
2720
2721
2722
2723
2724
2725 @JsxSetter({CHROME, EDGE})
2726 public void setOnpointerover(final Object onpointerover) {
2727 setHandlerForJavaScript(Event.TYPE_POINTEROVER, onpointerover);
2728 }
2729
2730
2731
2732
2733
2734 @JsxGetter({CHROME, EDGE})
2735 public Function getOnclose() {
2736 return getEventHandler(Event.TYPE_CLOSE);
2737 }
2738
2739
2740
2741
2742
2743 @JsxSetter({CHROME, EDGE})
2744 public void setOnclose(final Object onclose) {
2745 setHandlerForJavaScript(Event.TYPE_CLOSE, onclose);
2746 }
2747
2748
2749
2750
2751
2752 @JsxGetter
2753 public Function getOnanimationend() {
2754 return getEventHandler(Event.TYPE_ANIMATIONEND);
2755 }
2756
2757
2758
2759
2760
2761 @JsxSetter
2762 public void setOnanimationend(final Object onanimationend) {
2763 setHandlerForJavaScript(Event.TYPE_ANIMATIONEND, onanimationend);
2764 }
2765
2766
2767
2768
2769
2770 @JsxGetter
2771 public Function getOndragenter() {
2772 return getEventHandler(Event.TYPE_DRAGENTER);
2773 }
2774
2775
2776
2777
2778
2779 @JsxSetter
2780 public void setOndragenter(final Object ondragenter) {
2781 setHandlerForJavaScript(Event.TYPE_DRAGENTER, ondragenter);
2782 }
2783
2784
2785
2786
2787
2788 @JsxGetter({FF, FF_ESR})
2789 public Function getOnafterprint() {
2790 return getEventHandler(Event.TYPE_AFTERPRINT);
2791 }
2792
2793
2794
2795
2796
2797 @JsxSetter({FF, FF_ESR})
2798 public void setOnafterprint(final Object onafterprint) {
2799 setHandlerForJavaScript(Event.TYPE_AFTERPRINT, onafterprint);
2800 }
2801
2802
2803
2804
2805
2806 @JsxGetter({FF, FF_ESR})
2807 public Function getOnmozfullscreenerror() {
2808 return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
2809 }
2810
2811
2812
2813
2814
2815 @JsxSetter({FF, FF_ESR})
2816 public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
2817 setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
2818 }
2819
2820
2821
2822
2823
2824 @JsxGetter
2825 public Function getOnmouseleave() {
2826 return getEventHandler(Event.TYPE_MOUSELEAVE);
2827 }
2828
2829
2830
2831
2832
2833 @JsxSetter
2834 public void setOnmouseleave(final Object onmouseleave) {
2835 setHandlerForJavaScript(Event.TYPE_MOUSELEAVE, onmouseleave);
2836 }
2837
2838
2839
2840
2841
2842 @JsxGetter({CHROME, EDGE})
2843 public Function getOnmousewheel() {
2844 return getEventHandler(Event.TYPE_MOUSEWHEEL);
2845 }
2846
2847
2848
2849
2850
2851 @JsxSetter({CHROME, EDGE})
2852 public void setOnmousewheel(final Object onmousewheel) {
2853 setHandlerForJavaScript(Event.TYPE_MOUSEWHEEL, onmousewheel);
2854 }
2855
2856
2857
2858
2859
2860 @JsxGetter
2861 public Function getOnseeking() {
2862 return getEventHandler(Event.TYPE_SEEKING);
2863 }
2864
2865
2866
2867
2868
2869 @JsxSetter
2870 public void setOnseeking(final Object onseeking) {
2871 setHandlerForJavaScript(Event.TYPE_SEEKING, onseeking);
2872 }
2873
2874
2875
2876
2877
2878 @JsxGetter({CHROME, EDGE})
2879 public Function getOncuechange() {
2880 return getEventHandler(Event.TYPE_CUECHANGE);
2881 }
2882
2883
2884
2885
2886
2887 @JsxSetter({CHROME, EDGE})
2888 public void setOncuechange(final Object oncuechange) {
2889 setHandlerForJavaScript(Event.TYPE_CUECHANGE, oncuechange);
2890 }
2891
2892
2893
2894
2895
2896 @JsxGetter
2897 public Function getOnpageshow() {
2898 return getEventHandler(Event.TYPE_PAGESHOW);
2899 }
2900
2901
2902
2903
2904
2905 @JsxSetter
2906 public void setOnpageshow(final Object onpageshow) {
2907 setHandlerForJavaScript(Event.TYPE_PAGESHOW, onpageshow);
2908 }
2909
2910
2911
2912
2913
2914 @JsxGetter({FF, FF_ESR})
2915 public Function getOnmozfullscreenchange() {
2916 return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
2917 }
2918
2919
2920
2921
2922
2923 @JsxSetter({FF, FF_ESR})
2924 public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
2925 setHandlerForJavaScript(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
2926 }
2927
2928
2929
2930
2931
2932 @JsxGetter
2933 public Function getOndurationchange() {
2934 return getEventHandler(Event.TYPE_DURATIONCHANGE);
2935 }
2936
2937
2938
2939
2940
2941 @JsxSetter
2942 public void setOndurationchange(final Object ondurationchange) {
2943 setHandlerForJavaScript(Event.TYPE_DURATIONCHANGE, ondurationchange);
2944 }
2945
2946
2947
2948
2949
2950 @JsxGetter
2951 public Function getOnplaying() {
2952 return getEventHandler(Event.TYPE_PLAYING);
2953 }
2954
2955
2956
2957
2958
2959 @JsxSetter
2960 public void setOnplaying(final Object onplaying) {
2961 setHandlerForJavaScript(Event.TYPE_PLAYING, onplaying);
2962 }
2963
2964
2965
2966
2967
2968 @JsxGetter
2969 public Function getOnended() {
2970 return getEventHandler(Event.TYPE_ENDED);
2971 }
2972
2973
2974
2975
2976
2977 @JsxSetter
2978 public void setOnended(final Object onended) {
2979 setHandlerForJavaScript(Event.TYPE_ENDED, onended);
2980 }
2981
2982
2983
2984
2985
2986 @JsxGetter
2987 public Function getOnloadeddata() {
2988 return getEventHandler(Event.TYPE_LOADEDDATA);
2989 }
2990
2991
2992
2993
2994
2995 @JsxSetter
2996 public void setOnloadeddata(final Object onloadeddata) {
2997 setHandlerForJavaScript(Event.TYPE_LOADEDDATA, onloadeddata);
2998 }
2999
3000
3001
3002
3003
3004 @JsxGetter({CHROME, EDGE})
3005 public Function getOnunhandledrejection() {
3006 return getEventHandler(Event.TYPE_UNHANDLEDREJECTION);
3007 }
3008
3009
3010
3011
3012
3013 @JsxSetter({CHROME, EDGE})
3014 public void setOnunhandledrejection(final Object onunhandledrejection) {
3015 setHandlerForJavaScript(Event.TYPE_UNHANDLEDREJECTION, onunhandledrejection);
3016 }
3017
3018
3019
3020
3021
3022 @JsxGetter
3023 public Function getOnmouseout() {
3024 return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
3025 }
3026
3027
3028
3029
3030
3031 @JsxSetter
3032 public void setOnmouseout(final Object onmouseout) {
3033 setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_OUT, onmouseout);
3034 }
3035
3036
3037
3038
3039
3040 @JsxGetter
3041 public Function getOnsuspend() {
3042 return getEventHandler(Event.TYPE_SUSPEND);
3043 }
3044
3045
3046
3047
3048
3049 @JsxSetter
3050 public void setOnsuspend(final Object onsuspend) {
3051 setHandlerForJavaScript(Event.TYPE_SUSPEND, onsuspend);
3052 }
3053
3054
3055
3056
3057
3058 @JsxGetter
3059 public Function getOnwaiting() {
3060 return getEventHandler(Event.TYPE_WAITING);
3061 }
3062
3063
3064
3065
3066
3067 @JsxSetter
3068 public void setOnwaiting(final Object onwaiting) {
3069 setHandlerForJavaScript(Event.TYPE_WAITING, onwaiting);
3070 }
3071
3072
3073
3074
3075
3076 @JsxGetter
3077 public Function getOncanplay() {
3078 return getEventHandler(Event.TYPE_CANPLAY);
3079 }
3080
3081
3082
3083
3084
3085 @JsxSetter
3086 public void setOncanplay(final Object oncanplay) {
3087 setHandlerForJavaScript(Event.TYPE_CANPLAY, oncanplay);
3088 }
3089
3090
3091
3092
3093
3094 @JsxGetter
3095 public Function getOnmousedown() {
3096 return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
3097 }
3098
3099
3100
3101
3102
3103 @JsxSetter
3104 public void setOnmousedown(final Object onmousedown) {
3105 setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_DOWN, onmousedown);
3106 }
3107
3108
3109
3110
3111
3112 @JsxGetter
3113 public Function getOnlanguagechange() {
3114 return getEventHandler(Event.TYPE_LANGUAGECHANGE);
3115 }
3116
3117
3118
3119
3120
3121 @JsxSetter
3122 public void setOnlanguagechange(final Object onlanguagechange) {
3123 setHandlerForJavaScript(Event.TYPE_LANGUAGECHANGE, onlanguagechange);
3124 }
3125
3126
3127
3128
3129
3130 @JsxGetter
3131 public Function getOnemptied() {
3132 return getEventHandler(Event.TYPE_EMPTIED);
3133 }
3134
3135
3136
3137
3138
3139 @JsxSetter
3140 public void setOnemptied(final Object onemptied) {
3141 setHandlerForJavaScript(Event.TYPE_EMPTIED, onemptied);
3142 }
3143
3144
3145
3146
3147
3148 @JsxGetter({CHROME, EDGE})
3149 public Function getOnrejectionhandled() {
3150 return getEventHandler(Event.TYPE_REJECTIONHANDLED);
3151 }
3152
3153
3154
3155
3156
3157 @JsxSetter({CHROME, EDGE})
3158 public void setOnrejectionhandled(final Object onrejectionhandled) {
3159 setHandlerForJavaScript(Event.TYPE_REJECTIONHANDLED, onrejectionhandled);
3160 }
3161
3162
3163
3164
3165
3166 @JsxGetter({CHROME, EDGE})
3167 public Function getOnpointercancel() {
3168 return getEventHandler(Event.TYPE_POINTERCANCEL);
3169 }
3170
3171
3172
3173
3174
3175 @JsxSetter({CHROME, EDGE})
3176 public void setOnpointercancel(final Object onpointercancel) {
3177 setHandlerForJavaScript(Event.TYPE_POINTERCANCEL, onpointercancel);
3178 }
3179
3180
3181
3182
3183
3184 @JsxGetter
3185 public Function getOnresize() {
3186 return getEventHandler(Event.TYPE_RESIZE);
3187 }
3188
3189
3190
3191
3192
3193 @JsxSetter
3194 public void setOnresize(final Object onresize) {
3195 setHandlerForJavaScript(Event.TYPE_RESIZE, onresize);
3196 }
3197
3198
3199
3200
3201
3202 @JsxGetter
3203 public Function getOnpause() {
3204 return getEventHandler(Event.TYPE_PAUSE);
3205 }
3206
3207
3208
3209
3210
3211 @JsxSetter
3212 public void setOnpause(final Object onpause) {
3213 setHandlerForJavaScript(Event.TYPE_PAUSE, onpause);
3214 }
3215
3216
3217
3218
3219
3220 @JsxGetter
3221 public Function getOnloadstart() {
3222 return getEventHandler(Event.TYPE_LOAD_START);
3223 }
3224
3225
3226
3227
3228
3229 @JsxSetter
3230 public void setOnloadstart(final Object onloadstart) {
3231 setHandlerForJavaScript(Event.TYPE_LOAD_START, onloadstart);
3232 }
3233
3234
3235
3236
3237
3238 @JsxGetter
3239 public Function getOnprogress() {
3240 return getEventHandler(Event.TYPE_PROGRESS);
3241 }
3242
3243
3244
3245
3246
3247 @JsxSetter
3248 public void setOnprogress(final Object onprogress) {
3249 setHandlerForJavaScript(Event.TYPE_PROGRESS, onprogress);
3250 }
3251
3252
3253
3254
3255
3256 @JsxGetter({CHROME, EDGE})
3257 public Function getOnpointerup() {
3258 return getEventHandler(Event.TYPE_POINTERUP);
3259 }
3260
3261
3262
3263
3264
3265 @JsxSetter({CHROME, EDGE})
3266 public void setOnpointerup(final Object onpointerup) {
3267 setHandlerForJavaScript(Event.TYPE_POINTERUP, onpointerup);
3268 }
3269
3270
3271
3272
3273
3274 @JsxGetter
3275 public Function getOnwheel() {
3276 return getEventHandler(Event.TYPE_WHEEL);
3277 }
3278
3279
3280
3281
3282
3283 @JsxSetter
3284 public void setOnwheel(final Object onwheel) {
3285 setHandlerForJavaScript(Event.TYPE_WHEEL, onwheel);
3286 }
3287
3288
3289
3290
3291
3292 @JsxGetter({CHROME, EDGE})
3293 public Function getOnpointerleave() {
3294 return getEventHandler(Event.TYPE_POINTERLEAVE);
3295 }
3296
3297
3298
3299
3300
3301 @JsxSetter({CHROME, EDGE})
3302 public void setOnpointerleave(final Object onpointerleave) {
3303 setHandlerForJavaScript(Event.TYPE_POINTERLEAVE, onpointerleave);
3304 }
3305
3306
3307
3308
3309
3310 @JsxGetter({FF, FF_ESR})
3311 public Function getOnbeforeprint() {
3312 return getEventHandler(Event.TYPE_BEFOREPRINT);
3313 }
3314
3315
3316
3317
3318
3319 @JsxSetter({FF, FF_ESR})
3320 public void setOnbeforeprint(final Object onbeforeprint) {
3321 setHandlerForJavaScript(Event.TYPE_BEFOREPRINT, onbeforeprint);
3322 }
3323
3324
3325
3326
3327
3328 @JsxGetter
3329 public Function getOnstorage() {
3330 return getEventHandler(Event.TYPE_STORAGE);
3331 }
3332
3333
3334
3335
3336
3337 @JsxSetter
3338 public void setOnstorage(final Object onstorage) {
3339 setHandlerForJavaScript(Event.TYPE_STORAGE, onstorage);
3340 }
3341
3342
3343
3344
3345
3346 @JsxGetter
3347 public Function getOnanimationstart() {
3348 return getEventHandler(Event.TYPE_ANIMATIONSTART);
3349 }
3350
3351
3352
3353
3354
3355 @JsxSetter
3356 public void setOnanimationstart(final Object onanimationstart) {
3357 setHandlerForJavaScript(Event.TYPE_ANIMATIONSTART, onanimationstart);
3358 }
3359
3360
3361
3362
3363
3364 @JsxGetter
3365 public Function getOntimeupdate() {
3366 return getEventHandler(Event.TYPE_TIMEUPDATE);
3367 }
3368
3369
3370
3371
3372
3373 @JsxSetter
3374 public void setOntimeupdate(final Object ontimeupdate) {
3375 setHandlerForJavaScript(Event.TYPE_TIMEUPDATE, ontimeupdate);
3376 }
3377
3378
3379
3380
3381
3382 @JsxGetter
3383 public Function getOnpagehide() {
3384 return getEventHandler(Event.TYPE_PAGEHIDE);
3385 }
3386
3387
3388
3389
3390
3391 @JsxSetter
3392 public void setOnpagehide(final Object onpagehide) {
3393 setHandlerForJavaScript(Event.TYPE_PAGEHIDE, onpagehide);
3394 }
3395
3396
3397
3398
3399
3400 @JsxGetter({CHROME, EDGE})
3401 public Function getOnwebkitanimationiteration() {
3402 return getEventHandler(Event.TYPE_WEBKITANIMATIONITERATION);
3403 }
3404
3405
3406
3407
3408
3409 @JsxSetter({CHROME, EDGE})
3410 public void setOnwebkitanimationiteration(final Object onwebkitanimationiteration) {
3411 setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONITERATION, onwebkitanimationiteration);
3412 }
3413
3414
3415
3416
3417
3418 @JsxGetter
3419 public Function getOnabort() {
3420 return getEventHandler(Event.TYPE_ABORT);
3421 }
3422
3423
3424
3425
3426
3427 @JsxSetter
3428 public void setOnabort(final Object onabort) {
3429 setHandlerForJavaScript(Event.TYPE_ABORT, onabort);
3430 }
3431
3432
3433
3434
3435
3436 @JsxGetter
3437 public Function getOnloadedmetadata() {
3438 return getEventHandler(Event.TYPE_LOADEDMETADATA);
3439 }
3440
3441
3442
3443
3444
3445 @JsxSetter
3446 public void setOnloadedmetadata(final Object onloadedmetadata) {
3447 setHandlerForJavaScript(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
3448 }
3449
3450
3451
3452
3453
3454 @JsxGetter
3455 public Function getOnmouseup() {
3456 return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
3457 }
3458
3459
3460
3461
3462
3463 @JsxSetter
3464 public void setOnmouseup(final Object onmouseup) {
3465 setHandlerForJavaScript(MouseEvent.TYPE_MOUSE_UP, onmouseup);
3466 }
3467
3468
3469
3470
3471
3472 @JsxGetter
3473 public Function getOndragover() {
3474 return getEventHandler(Event.TYPE_DRAGOVER);
3475 }
3476
3477
3478
3479
3480
3481 @JsxSetter
3482 public void setOndragover(final Object ondragover) {
3483 setHandlerForJavaScript(Event.TYPE_DRAGOVER, ondragover);
3484 }
3485
3486
3487
3488
3489
3490 @JsxGetter
3491 public Function getOnonline() {
3492 return getEventHandler(Event.TYPE_ONLINE);
3493 }
3494
3495
3496
3497
3498
3499 @JsxSetter
3500 public void setOnonline(final Object ononline) {
3501 setHandlerForJavaScript(Event.TYPE_ONLINE, ononline);
3502 }
3503
3504
3505
3506
3507
3508 @JsxGetter({CHROME, EDGE})
3509 public Function getOnsearch() {
3510 return getEventHandler(Event.TYPE_SEARCH);
3511 }
3512
3513
3514
3515
3516
3517 @JsxSetter({CHROME, EDGE})
3518 public void setOnsearch(final Object onsearch) {
3519 setHandlerForJavaScript(Event.TYPE_SEARCH, onsearch);
3520 }
3521
3522
3523
3524
3525
3526 @JsxGetter
3527 public Function getOninput() {
3528 return getEventHandler(Event.TYPE_INPUT);
3529 }
3530
3531
3532
3533
3534
3535 @JsxSetter
3536 public void setOninput(final Object oninput) {
3537 setHandlerForJavaScript(Event.TYPE_INPUT, oninput);
3538 }
3539
3540
3541
3542
3543
3544 @JsxGetter({CHROME, EDGE})
3545 public Function getOnwebkittransitionend() {
3546 return getEventHandler(Event.TYPE_WEBKITTRANSITIONEND);
3547 }
3548
3549
3550
3551
3552
3553 @JsxSetter({CHROME, EDGE})
3554 public void setOnwebkittransitionend(final Object onwebkittransitionend) {
3555 setHandlerForJavaScript(Event.TYPE_WEBKITTRANSITIONEND, onwebkittransitionend);
3556 }
3557
3558
3559
3560
3561
3562 @JsxGetter
3563 public Function getOndevicemotion() {
3564 return getEventHandler(Event.TYPE_DEVICEMOTION);
3565 }
3566
3567
3568
3569
3570
3571 @JsxSetter
3572 public void setOndevicemotion(final Object ondevicemotion) {
3573 setHandlerForJavaScript(Event.TYPE_DEVICEMOTION, ondevicemotion);
3574 }
3575
3576
3577
3578
3579
3580 @JsxGetter
3581 public Function getOnstalled() {
3582 return getEventHandler(Event.TYPE_STALLED);
3583 }
3584
3585
3586
3587
3588
3589 @JsxSetter
3590 public void setOnstalled(final Object onstalled) {
3591 setHandlerForJavaScript(Event.TYPE_STALLED, onstalled);
3592 }
3593
3594
3595
3596
3597
3598 @JsxGetter
3599 public Function getOnmouseenter() {
3600 return getEventHandler(Event.TYPE_MOUDEENTER);
3601 }
3602
3603
3604
3605
3606
3607 @JsxSetter
3608 public void setOnmouseenter(final Object onmouseenter) {
3609 setHandlerForJavaScript(Event.TYPE_MOUDEENTER, onmouseenter);
3610 }
3611
3612
3613
3614
3615
3616 @JsxGetter
3617 public Function getOndragleave() {
3618 return getEventHandler(Event.TYPE_DRAGLEAVE);
3619 }
3620
3621
3622
3623
3624
3625 @JsxSetter
3626 public void setOndragleave(final Object ondragleave) {
3627 setHandlerForJavaScript(Event.TYPE_DRAGLEAVE, ondragleave);
3628 }
3629
3630
3631
3632
3633
3634 @JsxGetter({CHROME, EDGE})
3635 public Function getOnpointerdown() {
3636 return getEventHandler(Event.TYPE_POINTERDOWN);
3637 }
3638
3639
3640
3641
3642
3643 @JsxSetter({CHROME, EDGE})
3644 public void setOnpointerdown(final Object onpointerdown) {
3645 setHandlerForJavaScript(Event.TYPE_POINTERDOWN, onpointerdown);
3646 }
3647
3648
3649
3650
3651
3652 @JsxGetter
3653 public Function getOndrop() {
3654 return getEventHandler(Event.TYPE_DROP);
3655 }
3656
3657
3658
3659
3660
3661 @JsxSetter
3662 public void setOndrop(final Object ondrop) {
3663 setHandlerForJavaScript(Event.TYPE_DROP, ondrop);
3664 }
3665
3666
3667
3668
3669
3670 @JsxGetter
3671 public Function getOnunload() {
3672 return getEventHandler(Event.TYPE_UNLOAD);
3673 }
3674
3675
3676
3677
3678
3679 @JsxSetter
3680 public void setOnunload(final Object onunload) {
3681 setHandlerForJavaScript(Event.TYPE_UNLOAD, onunload);
3682 }
3683
3684
3685
3686
3687
3688 @JsxGetter({CHROME, EDGE})
3689 public Function getOnwebkitanimationend() {
3690 return getEventHandler(Event.TYPE_WEBKITANIMATIONEND);
3691 }
3692
3693
3694
3695
3696
3697 @JsxSetter({CHROME, EDGE})
3698 public void setOnwebkitanimationend(final Object onwebkitanimationend) {
3699 setHandlerForJavaScript(Event.TYPE_WEBKITANIMATIONEND, onwebkitanimationend);
3700 }
3701
3702
3703
3704
3705
3706 @JsxGetter
3707 public Function getOndragstart() {
3708 return getEventHandler(Event.TYPE_DRAGSTART);
3709 }
3710
3711
3712
3713
3714
3715 @JsxSetter
3716 public void setOndragstart(final Object ondragstart) {
3717 setHandlerForJavaScript(Event.TYPE_DRAGSTART, ondragstart);
3718 }
3719
3720
3721
3722
3723
3724 @JsxGetter({CHROME, EDGE})
3725 public Function getOntransitionend() {
3726 return getEventHandler(Event.TYPE_TRANSITIONEND);
3727 }
3728
3729
3730
3731
3732
3733 @JsxSetter({CHROME, EDGE})
3734 public void setOntransitionend(final Object ontransitionend) {
3735 setHandlerForJavaScript(Event.TYPE_TRANSITIONEND, ontransitionend);
3736 }
3737
3738
3739
3740
3741
3742 @JsxGetter({CHROME, EDGE})
3743 public Function getOndeviceorientationabsolute() {
3744 return getEventHandler(Event.TYPE_DEVICEORIENTATIONABSOLUTE);
3745 }
3746
3747
3748
3749
3750
3751 @JsxSetter({CHROME, EDGE})
3752 public void setOndeviceorientationabsolute(final Object ondeviceorientationabsolute) {
3753 setHandlerForJavaScript(Event.TYPE_DEVICEORIENTATIONABSOLUTE, ondeviceorientationabsolute);
3754 }
3755
3756
3757
3758
3759
3760 @JsxGetter
3761 public Function getOnvolumechange() {
3762 return getEventHandler(Event.TYPE_VOLUMECHANGE);
3763 }
3764
3765
3766
3767
3768
3769 @JsxSetter
3770 public void setOnvolumechange(final Object onvolumechange) {
3771 setHandlerForJavaScript(Event.TYPE_VOLUMECHANGE, onvolumechange);
3772 }
3773
3774
3775
3776
3777
3778 @JsxGetter({CHROME, EDGE})
3779 public Function getOngotpointercapture() {
3780 return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
3781 }
3782
3783
3784
3785
3786
3787 @JsxSetter({CHROME, EDGE})
3788 public void setOngotpointercapture(final Object ongotpointercapture) {
3789 setHandlerForJavaScript(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
3790 }
3791
3792
3793
3794
3795
3796 @JsxGetter
3797 public Function getOnpopstate() {
3798 return getEventHandler(Event.TYPE_POPSTATE);
3799 }
3800
3801
3802
3803
3804
3805 @JsxSetter
3806 public void setOnpopstate(final Object onpopstate) {
3807 setHandlerForJavaScript(Event.TYPE_POPSTATE, onpopstate);
3808 }
3809
3810
3811
3812
3813
3814 @Override
3815 public BrowserVersion getBrowserVersion() {
3816 return getWebWindow().getWebClient().getBrowserVersion();
3817 }
3818
3819 @Override
3820 public void put(final String name, final Scriptable start, final Object value) {
3821
3822
3823 if ("event".equals(name)) {
3824 final Slot slot = querySlot(Context.getCurrentContext(), "event");
3825 if (slot instanceof AccessorSlot) {
3826 delete("event");
3827 }
3828 }
3829 super.put(name, start, value);
3830 }
3831
3832
3833
3834
3835 @JsxGetter
3836 public boolean getIsSecureContext() {
3837 final Page page = getWebWindow().getEnclosedPage();
3838 if (page != null) {
3839 final String protocol = page.getUrl().getProtocol();
3840 if ("https".equals(protocol)
3841 || "wss".equals(protocol)
3842 || "file".equals(protocol)) {
3843 return true;
3844 }
3845
3846 final String host = page.getUrl().getHost();
3847 if ("localhost".equals(host)
3848 || "localhost.".equals(host)
3849 || host.endsWith(".localhost")
3850 || host.endsWith(".localhost.")) {
3851 return true;
3852 }
3853 }
3854
3855 return false;
3856 }
3857 }
3858
3859 class HTMLCollectionFrames extends HTMLCollection {
3860 private static final Log LOG = LogFactory.getLog(HTMLCollectionFrames.class);
3861
3862 HTMLCollectionFrames(final HtmlPage page) {
3863 super(page, false);
3864 this.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof BaseFrameElement);
3865 }
3866
3867 @Override
3868 protected Scriptable getScriptableForElement(final Object obj) {
3869 final WebWindow window;
3870 if (obj instanceof BaseFrameElement) {
3871 window = ((BaseFrameElement) obj).getEnclosedWindow();
3872 }
3873 else {
3874 window = ((FrameWindow) obj).getFrameElement().getEnclosedWindow();
3875 }
3876
3877 return window.getScriptableObject();
3878 }
3879
3880 @Override
3881 protected Object getWithPreemption(final String name) {
3882 final List<DomNode> elements = getElements();
3883
3884 for (final Object next : elements) {
3885 final BaseFrameElement frameElt = (BaseFrameElement) next;
3886 final WebWindow window = frameElt.getEnclosedWindow();
3887 if (name.equals(window.getName())) {
3888 if (LOG.isDebugEnabled()) {
3889 LOG.debug("Property \"" + name + "\" evaluated (by name) to " + window);
3890 }
3891 return getScriptableForElement(window);
3892 }
3893 }
3894
3895 return NOT_FOUND;
3896 }
3897 }