1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.dom;
16
17 import static org.htmlunit.BrowserVersionFeatures.EVENT_TYPE_MUTATIONEVENT;
18 import static org.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_EVALUATE_RECREATES_RESULT;
19 import static org.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_SELECTION_RANGE_COUNT;
20 import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
21 import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
22 import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
23 import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
24
25 import java.io.IOException;
26 import java.io.Serializable;
27 import java.lang.reflect.InvocationTargetException;
28 import java.net.URL;
29 import java.time.ZoneId;
30 import java.time.format.DateTimeFormatter;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.Locale;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.UUID;
38 import java.util.function.Predicate;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.htmlunit.HttpHeader;
43 import org.htmlunit.Page;
44 import org.htmlunit.SgmlPage;
45 import org.htmlunit.StringWebResponse;
46 import org.htmlunit.WebResponse;
47 import org.htmlunit.WebWindow;
48 import org.htmlunit.corejs.javascript.Callable;
49 import org.htmlunit.corejs.javascript.Context;
50 import org.htmlunit.corejs.javascript.Function;
51 import org.htmlunit.corejs.javascript.NativeFunction;
52 import org.htmlunit.corejs.javascript.Scriptable;
53 import org.htmlunit.corejs.javascript.ScriptableObject;
54 import org.htmlunit.corejs.javascript.VarScope;
55 import org.htmlunit.cssparser.parser.CSSException;
56 import org.htmlunit.html.DomComment;
57 import org.htmlunit.html.DomDocumentFragment;
58 import org.htmlunit.html.DomElement;
59 import org.htmlunit.html.DomNode;
60 import org.htmlunit.html.DomText;
61 import org.htmlunit.html.FrameWindow;
62 import org.htmlunit.html.Html;
63 import org.htmlunit.html.HtmlAnchor;
64 import org.htmlunit.html.HtmlArea;
65 import org.htmlunit.html.HtmlAttributeChangeEvent;
66 import org.htmlunit.html.HtmlElement;
67 import org.htmlunit.html.HtmlEmbed;
68 import org.htmlunit.html.HtmlForm;
69 import org.htmlunit.html.HtmlFrameSet;
70 import org.htmlunit.html.HtmlImage;
71 import org.htmlunit.html.HtmlPage;
72 import org.htmlunit.html.HtmlRb;
73 import org.htmlunit.html.HtmlRp;
74 import org.htmlunit.html.HtmlRt;
75 import org.htmlunit.html.HtmlRtc;
76 import org.htmlunit.html.HtmlScript;
77 import org.htmlunit.html.HtmlSvg;
78 import org.htmlunit.html.HtmlUnknownElement;
79 import org.htmlunit.html.UnknownElementFactory;
80 import org.htmlunit.html.impl.SimpleRange;
81 import org.htmlunit.http.Cookie;
82 import org.htmlunit.http.HttpUtils;
83 import org.htmlunit.httpclient.HtmlUnitBrowserCompatCookieSpec;
84 import org.htmlunit.javascript.HtmlUnitScriptable;
85 import org.htmlunit.javascript.JavaScriptEngine;
86 import org.htmlunit.javascript.configuration.JsxClass;
87 import org.htmlunit.javascript.configuration.JsxConstructor;
88 import org.htmlunit.javascript.configuration.JsxFunction;
89 import org.htmlunit.javascript.configuration.JsxGetter;
90 import org.htmlunit.javascript.configuration.JsxSetter;
91 import org.htmlunit.javascript.configuration.JsxStaticFunction;
92 import org.htmlunit.javascript.host.Element;
93 import org.htmlunit.javascript.host.FontFaceSet;
94 import org.htmlunit.javascript.host.Location;
95 import org.htmlunit.javascript.host.NativeFunctionPrefixResolver;
96 import org.htmlunit.javascript.host.Window;
97 import org.htmlunit.javascript.host.animations.AnimationEvent;
98 import org.htmlunit.javascript.host.css.StyleSheetList;
99 import org.htmlunit.javascript.host.dom.AbstractList.EffectOnCache;
100 import org.htmlunit.javascript.host.event.BeforeUnloadEvent;
101 import org.htmlunit.javascript.host.event.CompositionEvent;
102 import org.htmlunit.javascript.host.event.CustomEvent;
103 import org.htmlunit.javascript.host.event.DeviceMotionEvent;
104 import org.htmlunit.javascript.host.event.DeviceOrientationEvent;
105 import org.htmlunit.javascript.host.event.DragEvent;
106 import org.htmlunit.javascript.host.event.Event;
107 import org.htmlunit.javascript.host.event.FocusEvent;
108 import org.htmlunit.javascript.host.event.HashChangeEvent;
109 import org.htmlunit.javascript.host.event.KeyboardEvent;
110 import org.htmlunit.javascript.host.event.MessageEvent;
111 import org.htmlunit.javascript.host.event.MouseEvent;
112 import org.htmlunit.javascript.host.event.MutationEvent;
113 import org.htmlunit.javascript.host.event.PointerEvent;
114 import org.htmlunit.javascript.host.event.PopStateEvent;
115 import org.htmlunit.javascript.host.event.ProgressEvent;
116 import org.htmlunit.javascript.host.event.TextEvent;
117 import org.htmlunit.javascript.host.event.UIEvent;
118 import org.htmlunit.javascript.host.event.WheelEvent;
119 import org.htmlunit.javascript.host.file.Blob;
120 import org.htmlunit.javascript.host.html.HTMLAllCollection;
121 import org.htmlunit.javascript.host.html.HTMLBodyElement;
122 import org.htmlunit.javascript.host.html.HTMLCollection;
123 import org.htmlunit.javascript.host.html.HTMLElement;
124 import org.htmlunit.javascript.host.html.HTMLFrameSetElement;
125 import org.htmlunit.util.StringUtils;
126 import org.htmlunit.util.UrlUtils;
127 import org.htmlunit.xpath.xml.utils.PrefixResolver;
128 import org.w3c.dom.CDATASection;
129 import org.w3c.dom.DOMException;
130 import org.w3c.dom.DocumentType;
131 import org.w3c.dom.ProcessingInstruction;
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 @JsxClass
158 public class Document extends Node {
159
160 private static final Log LOG = LogFactory.getLog(Document.class);
161
162
163
164
165
166 private static final Set<String> EXECUTE_CMDS_FF = new HashSet<>();
167 private static final Set<String> EXECUTE_CMDS_CHROME = new HashSet<>();
168
169 private static final DateTimeFormatter LAST_MODIFIED_DATE_FORMATTER
170 = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
171
172
173 private static final Map<String, Class<? extends Event>> SUPPORTED_DOM2_EVENT_TYPE_MAP;
174
175 private static final Map<String, Class<? extends Event>> SUPPORTED_DOM3_EVENT_TYPE_MAP;
176
177 private static final Map<String, Class<? extends Event>> SUPPORTED_VENDOR_EVENT_TYPE_MAP;
178
179
180
181
182
183
184
185
186
187 static {
188 SUPPORTED_DOM2_EVENT_TYPE_MAP = Map.of(
189 "HTMLEvents", Event.class,
190 "MouseEvents", MouseEvent.class,
191 "MutationEvents", MutationEvent.class,
192 "UIEvents", UIEvent.class);
193
194 SUPPORTED_DOM3_EVENT_TYPE_MAP = Map.ofEntries(
195 Map.entry("Event", Event.class),
196 Map.entry("KeyboardEvent", KeyboardEvent.class),
197 Map.entry("MouseEvent", MouseEvent.class),
198 Map.entry("MessageEvent", MessageEvent.class),
199 Map.entry("MutationEvent", MutationEvent.class),
200 Map.entry("UIEvent", UIEvent.class),
201 Map.entry("CustomEvent", CustomEvent.class),
202 Map.entry("CompositionEvent", CompositionEvent.class),
203 Map.entry("DragEvent", DragEvent.class),
204 Map.entry("TextEvent", TextEvent.class),
205 Map.entry("DeviceMotionEvent", DeviceMotionEvent.class),
206 Map.entry("DeviceOrientationEvent", DeviceOrientationEvent.class));
207
208 SUPPORTED_VENDOR_EVENT_TYPE_MAP = Map.ofEntries(
209 Map.entry("BeforeUnloadEvent", BeforeUnloadEvent.class),
210 Map.entry("Events", Event.class),
211 Map.entry("HashChangeEvent", HashChangeEvent.class),
212 Map.entry("KeyEvents", KeyboardEvent.class),
213 Map.entry("PointerEvent", PointerEvent.class),
214 Map.entry("PopStateEvent", PopStateEvent.class),
215 Map.entry("ProgressEvent", ProgressEvent.class),
216 Map.entry("FocusEvent", FocusEvent.class),
217 Map.entry("WheelEvent", WheelEvent.class),
218 Map.entry("AnimationEvent", AnimationEvent.class));
219 }
220
221 private Window window_;
222 private DOMImplementation implementation_;
223 private String designMode_;
224 private String compatMode_;
225 private int documentMode_ = -1;
226 private String domain_;
227 private String lastModified_;
228 private ScriptableObject currentScript_;
229 private transient FontFaceSet fonts_;
230 private transient StyleSheetList styleSheetList_;
231
232 private final Map<String, Blob> blobUrl2Blobs_ = new HashMap<>();
233
234 static {
235
236 String[] cmds = {
237 "BackColor", "BackgroundImageCache" ,
238 "Bold",
239 "CreateLink", "Delete",
240 "FontName", "FontSize", "ForeColor", "FormatBlock",
241 "Indent", "InsertHorizontalRule", "InsertImage",
242 "InsertOrderedList", "InsertParagraph", "InsertUnorderedList",
243 "Italic", "JustifyCenter", "JustifyFull", "JustifyLeft", "JustifyNone",
244 "JustifyRight",
245 "Outdent",
246 "Print",
247 "Redo", "RemoveFormat",
248 "SelectAll", "StrikeThrough", "Subscript", "Superscript",
249 "Underline", "Undo", "Unlink", "Unselect"
250 };
251 for (final String cmd : cmds) {
252 if (!"Bold".equals(cmd)) {
253 EXECUTE_CMDS_CHROME.add(cmd.toLowerCase(Locale.ROOT));
254 }
255 }
256
257 cmds = new String[] {
258 "backColor", "bold", "contentReadOnly", "copy", "createLink", "cut", "decreaseFontSize", "delete",
259 "fontName", "fontSize", "foreColor", "formatBlock", "heading", "hiliteColor", "increaseFontSize",
260 "indent", "insertHorizontalRule", "insertHTML", "insertImage", "insertOrderedList", "insertUnorderedList",
261 "insertParagraph", "italic",
262 "justifyCenter", "JustifyFull", "justifyLeft", "justifyRight", "outdent", "paste", "redo",
263 "removeFormat", "selectAll", "strikeThrough", "subscript", "superscript", "underline", "undo", "unlink",
264 "useCSS", "styleWithCSS"
265 };
266 for (final String cmd : cmds) {
267 EXECUTE_CMDS_FF.add(cmd.toLowerCase(Locale.ROOT));
268 if (!"bold".equals(cmd)) {
269 EXECUTE_CMDS_CHROME.add(cmd.toLowerCase(Locale.ROOT));
270 }
271 }
272 }
273
274
275
276
277 @Override
278 @JsxConstructor
279 public void jsConstructor() {
280 throw JavaScriptEngine.typeErrorIllegalConstructor();
281 }
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296 @JsxStaticFunction
297 public static Document parseHTMLUnsafe(final Context cx, final VarScope scope,
298 final Scriptable thisObj, final Object[] args, final Function funObj) {
299 if (args.length < 1) {
300 throw JavaScriptEngine
301 .typeError("Document.parseHTMLUnsafe: At least 1 argument required, but only 0 passed");
302 }
303
304 final Window win = getWindow(thisObj);
305 if (JavaScriptEngine.isUndefined(args[0])) {
306 return win.getDocument();
307 }
308
309 final String html = JavaScriptEngine.toString(args[0]);
310
311 try {
312 final WebWindow webWindow = win.getWebWindow();
313 final WebResponse webResponse = new StringWebResponse(html, webWindow.getEnclosedPage().getUrl());
314 return DOMParser.parseHtmlDocument(win.getDocument(), webResponse, webWindow);
315 }
316 catch (final IOException e) {
317 throw JavaScriptEngine.syntaxError("Parsing failed" + e.getMessage());
318 }
319 }
320
321
322
323
324
325 public void setWindow(final Window window) {
326 window_ = window;
327 }
328
329
330
331
332
333 @JsxGetter
334 public Location getLocation() {
335 if (window_ == null) {
336 return null;
337 }
338 return window_.getLocation();
339 }
340
341
342
343
344
345
346
347
348
349 @JsxSetter
350 public void setLocation(final String location) throws IOException {
351 window_.setLocation(location);
352 }
353
354
355
356
357
358 @JsxGetter
359 public String getReferrer() {
360 String referrer = "";
361 final WebResponse webResponse = getPage().getWebResponse();
362 if (webResponse != null) {
363 referrer = webResponse.getWebRequest().getAdditionalHeaders().get(HttpHeader.REFERER);
364 if (referrer == null) {
365 referrer = "";
366 }
367 }
368 return referrer;
369 }
370
371
372
373
374
375 @JsxGetter
376 public Element getDocumentElement() {
377 final Object documentElement = getPage().getDocumentElement();
378 if (documentElement == null) {
379
380 return null;
381 }
382 return (Element) getScriptableFor(documentElement);
383 }
384
385
386
387
388
389 @JsxGetter
390 public Element getRootElement() {
391 return null;
392 }
393
394
395
396
397
398 @JsxGetter
399 public HtmlUnitScriptable getDoctype() {
400 final Object documentType = getPage().getDoctype();
401 if (documentType == null) {
402 return null;
403 }
404 return getScriptableFor(documentType);
405 }
406
407
408
409
410
411 @JsxGetter
412 public String getDesignMode() {
413 if (designMode_ == null) {
414 designMode_ = "off";
415 }
416 return designMode_;
417 }
418
419
420
421
422
423 @JsxSetter
424 public void setDesignMode(final String mode) {
425 if ("on".equalsIgnoreCase(mode)) {
426 designMode_ = "on";
427 final SgmlPage page = getPage();
428 if (page != null && page.isHtmlPage()
429 && getBrowserVersion().hasFeature(JS_DOCUMENT_SELECTION_RANGE_COUNT)) {
430 final HtmlPage htmlPage = (HtmlPage) page;
431 final DomNode child = htmlPage.getBody().getFirstChild();
432 final DomNode rangeNode = child == null ? htmlPage.getBody() : child;
433 htmlPage.setSelectionRange(new SimpleRange(rangeNode, 0));
434 }
435 }
436 else if ("off".equalsIgnoreCase(mode)) {
437 designMode_ = "off";
438 }
439 }
440
441
442
443
444
445 public SgmlPage getPage() {
446 return (SgmlPage) getDomNodeOrDie();
447 }
448
449
450
451
452
453 @JsxGetter
454 public Object getDefaultView() {
455 return getWindow();
456 }
457
458
459
460
461
462 @JsxFunction
463 public HtmlUnitScriptable createDocumentFragment() {
464 final DomDocumentFragment fragment = getDomNodeOrDie().getPage().createDocumentFragment();
465 final DocumentFragment node = new DocumentFragment();
466 node.setParentScope(getParentScope());
467 node.setPrototype(getPrototype(node.getClass()));
468 node.setDomNode(fragment);
469 return getScriptableFor(fragment);
470 }
471
472
473
474
475
476
477
478 @JsxFunction
479 public Attr createAttribute(final String attributeName) {
480 return getPage().createAttribute(attributeName).getScriptableObject();
481 }
482
483
484
485
486
487
488
489
490
491
492 @JsxFunction
493 public HtmlUnitScriptable importNode(final Node importedNode, final boolean deep) {
494 DomNode domNode = importedNode.getDomNodeOrDie();
495 domNode = domNode.cloneNode(deep);
496 domNode.processImportNode(this);
497 for (final DomNode childNode : domNode.getDescendants()) {
498 childNode.processImportNode(this);
499 }
500 return domNode.getScriptableObject();
501 }
502
503
504
505
506
507
508
509
510
511
512 @JsxFunction
513 public HtmlUnitScriptable adoptNode(final Node externalNode) {
514 externalNode.remove();
515 return importNode(externalNode, true);
516 }
517
518
519
520
521
522 @JsxGetter
523 public DOMImplementation getImplementation() {
524 if (implementation_ == null) {
525 implementation_ = new DOMImplementation();
526 implementation_.setParentScope(getParentScope());
527 implementation_.setPrototype(getPrototype(implementation_.getClass()));
528 }
529 return implementation_;
530 }
531
532
533
534
535
536
537
538
539 @JsxFunction
540 public NativeXPathNSResolver createNSResolver(final Node nodeResolver) {
541 final NativeXPathNSResolver resolver = new NativeXPathNSResolver();
542 resolver.setElement(nodeResolver);
543 resolver.setParentScope(getParentScope());
544 resolver.setPrototype(getPrototype(resolver.getClass()));
545 return resolver;
546 }
547
548
549
550
551
552
553
554 @JsxFunction
555 public HtmlUnitScriptable createTextNode(final String newData) {
556 final DomNode domNode = new DomText(getDomNodeOrDie().getPage(), newData);
557 return makeScriptableFor(domNode);
558 }
559
560
561
562
563
564
565 @JsxFunction
566 public HtmlUnitScriptable createComment(final String comment) {
567 final DomNode domNode = new DomComment(getDomNodeOrDie().getPage(), comment);
568 return getScriptableFor(domNode);
569 }
570
571
572
573
574
575
576
577
578
579
580
581 @JsxFunction
582 public XPathResult evaluate(final String expression, final Node contextNode,
583 final Object resolver, final int type, final Object result) {
584 XPathResult xPathResult = null;
585 if (result instanceof XPathResult pathResult) {
586 xPathResult = pathResult;
587
588 if (getBrowserVersion().hasFeature(JS_DOCUMENT_EVALUATE_RECREATES_RESULT)) {
589 xPathResult = new XPathResult();
590 xPathResult.setParentScope(getParentScope());
591 xPathResult.setPrototype(getPrototype(xPathResult.getClass()));
592 }
593 }
594 else if (result == null
595 || JavaScriptEngine.isUndefined(result)
596 || result instanceof ScriptableObject) {
597 xPathResult = new XPathResult();
598 xPathResult.setParentScope(getParentScope());
599 xPathResult.setPrototype(getPrototype(xPathResult.getClass()));
600 }
601 else {
602 throw JavaScriptEngine.typeError("Argument 5 of Document.evaluate has to be an XPathResult or null.");
603 }
604
605 try {
606 PrefixResolver prefixResolver = null;
607 if (resolver instanceof NativeFunction function) {
608 prefixResolver = new NativeFunctionPrefixResolver(
609 function, contextNode.getParentScope());
610 }
611 else if (resolver instanceof PrefixResolver prefixResolver1) {
612 prefixResolver = prefixResolver1;
613 }
614 xPathResult.init(contextNode.getDomNodeOrDie().getByXPath(expression, prefixResolver), type);
615 return xPathResult;
616 }
617 catch (final Exception e) {
618 throw JavaScriptEngine.asJavaScriptException(
619 getWindow(),
620 "Failed to execute 'evaluate': " + e.getMessage(),
621 org.htmlunit.javascript.host.dom.DOMException.SYNTAX_ERR);
622 }
623 }
624
625
626
627
628
629
630
631 @JsxFunction
632 public HtmlUnitScriptable createElement(final Object tagName) {
633 if (tagName == null || JavaScriptEngine.isUndefined(tagName)) {
634 final org.w3c.dom.Node element = getPage().createElement("unknown");
635 ((HtmlUnknownElement) element).markAsCreatedByJavascript();
636 return getScriptableFor(element);
637 }
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658 final String tagNameString = JavaScriptEngine.toString(tagName);
659 if (tagNameString.length() > 0) {
660 final int firstChar = tagNameString.charAt(0);
661 if (firstChar < 128
662 && !Character.isLetter(firstChar)
663 && firstChar != ':' && firstChar != '_') {
664 if (LOG.isInfoEnabled()) {
665 LOG.info("createElement: Provided string '" + tagNameString + "' contains an invalid character");
666 }
667 throw JavaScriptEngine.asJavaScriptException(
668 getWindow(),
669 "createElement: Provided string '" + tagNameString + "' contains an invalid character",
670 org.htmlunit.javascript.host.dom.DOMException.INVALID_CHARACTER_ERR);
671 }
672
673 final int length = tagNameString.length();
674 for (int i = 1; i < length; i++) {
675 final int c = tagNameString.charAt(i);
676 if (c < 128) {
677 if (c == 0
678 || c == 9
679 || c == 10
680 || c == 12
681 || c == 13
682 || c == ' '
683 || c == '/'
684 || c == '>') {
685 if (LOG.isInfoEnabled()) {
686 LOG.info("createElement: Provided string '"
687 + tagNameString + "' contains an invalid character");
688 }
689 throw JavaScriptEngine.asJavaScriptException(
690 getWindow(),
691 "createElement: Provided string '" + tagNameString
692 + "' contains an invalid character",
693 org.htmlunit.javascript.host.dom.DOMException.INVALID_CHARACTER_ERR);
694 }
695 }
696 }
697 }
698
699 org.w3c.dom.Node element = getPage().createElement(tagNameString);
700
701 if (element instanceof HtmlImage image) {
702 image.markAsCreatedByJavascript();
703 }
704 else if (element instanceof HtmlRb rb) {
705 rb.markAsCreatedByJavascript();
706 }
707 else if (element instanceof HtmlRp rp) {
708 rp.markAsCreatedByJavascript();
709 }
710 else if (element instanceof HtmlRt rt) {
711 rt.markAsCreatedByJavascript();
712 }
713 else if (element instanceof HtmlRtc rtc) {
714 rtc.markAsCreatedByJavascript();
715 }
716 else if (element instanceof HtmlUnknownElement unknownElement) {
717 unknownElement.markAsCreatedByJavascript();
718 }
719 else if (element instanceof HtmlSvg) {
720 element = UnknownElementFactory.INSTANCE.createElementNS(getPage(), "", "svg", null);
721 ((HtmlUnknownElement) element).markAsCreatedByJavascript();
722 }
723 final HtmlUnitScriptable jsElement = getScriptableFor(element);
724
725 if (jsElement == NOT_FOUND) {
726 if (LOG.isDebugEnabled()) {
727 LOG.debug("createElement(" + tagName
728 + ") cannot return a result as there isn't a JavaScript object for the element "
729 + element.getClass().getName());
730 }
731 }
732 return jsElement;
733 }
734
735
736
737
738
739
740
741
742 @JsxFunction
743 public HtmlUnitScriptable createElementNS(final String namespaceURI, final String qualifiedName) {
744 if ("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul".equals(namespaceURI)) {
745 throw JavaScriptEngine.typeError("XUL not available");
746 }
747
748 final org.w3c.dom.Element element;
749 if (Html.XHTML_NAMESPACE.equals(namespaceURI)
750 || Html.SVG_NAMESPACE.equals(namespaceURI)) {
751 element = getPage().createElementNS(namespaceURI, qualifiedName);
752 }
753 else {
754 element = new DomElement(namespaceURI, qualifiedName, getPage(), null);
755 }
756 return getScriptableFor(element);
757 }
758
759
760
761
762
763
764 @JsxFunction
765 public HTMLCollection getElementsByTagName(final String tagName) {
766 final HTMLCollection collection = new HTMLCollection(getDomNodeOrDie(), false);
767
768 if (StringUtils.equalsChar('*', tagName)) {
769 collection.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> true);
770 }
771 else {
772 collection.setIsMatchingPredicate(
773 (Predicate<DomNode> & Serializable)
774 node -> tagName.equalsIgnoreCase(node.getNodeName()));
775 }
776
777 return collection;
778 }
779
780
781
782
783
784
785
786
787 @JsxFunction
788 public HTMLCollection getElementsByTagNameNS(final Object namespaceURI, final String localName) {
789 final HTMLCollection elements = new HTMLCollection(getDomNodeOrDie(), false);
790 elements.setIsMatchingPredicate(
791 (Predicate<DomNode> & Serializable)
792 node -> localName.equals(node.getLocalName()));
793 return elements;
794 }
795
796
797
798
799
800
801 @JsxGetter
802 public Object getActiveElement() {
803 return null;
804 }
805
806
807
808
809
810 @JsxGetter
811 public String getCharacterSet() {
812 if (!(getPage() instanceof HtmlPage)) {
813
814 return "";
815 }
816 return getPage().getCharset().name();
817 }
818
819
820
821
822
823 @JsxGetter
824 public String getCharset() {
825 if (!(getPage() instanceof HtmlPage)) {
826
827 return "";
828 }
829 return getPage().getCharset().name();
830 }
831
832
833
834
835
836
837
838
839 @JsxGetter
840 public HTMLCollection getAnchors() {
841 final HTMLCollection anchors = new HTMLCollection(getDomNodeOrDie(), true);
842
843 anchors.setIsMatchingPredicate(
844 (Predicate<DomNode> & Serializable)
845 node -> {
846 if (!(node instanceof HtmlAnchor anchor)) {
847 return false;
848 }
849 return anchor.hasAttribute(DomElement.NAME_ATTRIBUTE);
850 });
851
852 anchors.setEffectOnCacheFunction(
853 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
854 event -> {
855 if (DomElement.NAME_ATTRIBUTE.equals(event.getName())
856 || DomElement.ID_ATTRIBUTE.equals(event.getName())) {
857 return EffectOnCache.RESET;
858 }
859 return EffectOnCache.NONE;
860 });
861
862 return anchors;
863 }
864
865
866
867
868
869
870
871
872
873 @JsxGetter
874 public HTMLCollection getApplets() {
875 return new HTMLCollection(getDomNodeOrDie(), false);
876 }
877
878
879
880
881
882 @JsxGetter
883 public HTMLElement getBody() {
884 final Page page = getPage();
885 if (page instanceof HtmlPage htmlPage) {
886 final HtmlElement body = htmlPage.getBody();
887 if (body != null) {
888 return body.getScriptableObject();
889 }
890
891
892 final DomElement doc = htmlPage.getDocumentElement();
893 if (doc != null) {
894 for (final DomNode node : doc.getChildren()) {
895 if (node instanceof HtmlFrameSet) {
896 return node.getScriptableObject();
897 }
898 }
899 }
900 }
901 return null;
902 }
903
904
905
906
907
908 @JsxSetter
909 public void setBody(final HTMLElement htmlElement) {
910 if (htmlElement instanceof HTMLBodyElement || htmlElement instanceof HTMLFrameSetElement) {
911 final Page page = getPage();
912 if (page instanceof HtmlPage htmlPage) {
913 final HtmlElement body = htmlPage.getBody();
914 if (body != null) {
915 body.replace(htmlElement.getDomNodeOrDie());
916 }
917 }
918 return;
919 }
920 throw JavaScriptEngine.asJavaScriptException(
921 getWindow(),
922 "Failed to set the 'body' property on 'Document': "
923 + "The new body element is of type '" + htmlElement.getTagName() + "'. "
924 + "It must be either a 'BODY' or 'FRAMESET' element.",
925 org.htmlunit.javascript.host.dom.DOMException.HIERARCHY_REQUEST_ERR);
926 }
927
928
929
930
931
932
933
934
935
936 @JsxFunction({CHROME, EDGE})
937 public void close() throws IOException {
938
939 }
940
941
942
943
944
945 @JsxGetter
946 public String getCompatMode() {
947
948 getDocumentMode();
949 return compatMode_;
950 }
951
952
953
954
955
956 public int getDocumentMode() {
957 if (documentMode_ != -1) {
958 return documentMode_;
959 }
960
961 compatMode_ = "CSS1Compat";
962
963 if (isQuirksDocType()) {
964 compatMode_ = "BackCompat";
965 }
966
967 final float version = getBrowserVersion().getBrowserVersionNumeric();
968 documentMode_ = (int) Math.floor(version);
969 return documentMode_;
970 }
971
972 private boolean isQuirksDocType() {
973 final DocumentType docType = getPage().getDoctype();
974 if (docType != null) {
975 final String systemId = docType.getSystemId();
976 if (systemId != null) {
977 if ("http://www.w3.org/TR/html4/strict.dtd".equals(systemId)) {
978 return false;
979 }
980
981 if ("http://www.w3.org/TR/html4/loose.dtd".equals(systemId)) {
982 final String publicId = docType.getPublicId();
983 if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicId)) {
984 return false;
985 }
986 }
987
988 if ("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd".equals(systemId)
989 || "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd".equals(systemId)) {
990 return false;
991 }
992 }
993 else if (docType.getPublicId() == null) {
994 return docType.getName() == null;
995 }
996 }
997 return true;
998 }
999
1000
1001
1002
1003
1004
1005
1006 public void forceDocumentMode(final int documentMode) {
1007 documentMode_ = documentMode;
1008 compatMode_ = documentMode == 5 ? "BackCompat" : "CSS1Compat";
1009 }
1010
1011
1012
1013
1014
1015
1016 @JsxFunction
1017 public Node querySelector(final String selectors) {
1018 try {
1019 final DomNode node = getDomNodeOrDie().querySelector(selectors);
1020 if (node != null) {
1021 return node.getScriptableObject();
1022 }
1023 return null;
1024 }
1025 catch (final CSSException e) {
1026 throw JavaScriptEngine.asJavaScriptException(
1027 getWindow(),
1028 "An invalid or illegal selector was specified (selector: '"
1029 + selectors + "' error: " + e.getMessage() + ").",
1030 org.htmlunit.javascript.host.dom.DOMException.SYNTAX_ERR);
1031 }
1032 }
1033
1034
1035
1036
1037
1038
1039
1040
1041 @JsxFunction
1042 public NodeList querySelectorAll(final String selectors) {
1043 try {
1044 return NodeList.staticNodeList(getParentScope(), getDomNodeOrDie().querySelectorAll(selectors));
1045 }
1046 catch (final CSSException e) {
1047 throw JavaScriptEngine.asJavaScriptException(
1048 getWindow(),
1049 "An invalid or illegal selector was specified (selector: '"
1050 + selectors + "' error: " + e.getMessage() + ").",
1051 org.htmlunit.javascript.host.dom.DOMException.SYNTAX_ERR);
1052 }
1053 }
1054
1055
1056
1057
1058
1059
1060
1061 @JsxFunction
1062 public boolean queryCommandSupported(final String cmd) {
1063 return hasCommand(cmd, true);
1064 }
1065
1066 private boolean hasCommand(final String cmd, final boolean includeBold) {
1067 if (null == cmd) {
1068 return false;
1069 }
1070
1071 final String cmdLC = cmd.toLowerCase(Locale.ROOT);
1072 if (getBrowserVersion().isChrome() || getBrowserVersion().isEdge()) {
1073 return EXECUTE_CMDS_CHROME.contains(cmdLC) || (includeBold && "bold".equalsIgnoreCase(cmd));
1074 }
1075 return EXECUTE_CMDS_FF.contains(cmdLC);
1076 }
1077
1078
1079
1080
1081
1082
1083
1084 @JsxFunction
1085 public boolean queryCommandEnabled(final String cmd) {
1086 return hasCommand(cmd, true);
1087 }
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097 @JsxFunction
1098 public boolean execCommand(final String cmd, final boolean userInterface, final Object value) {
1099 if (!hasCommand(cmd, false)) {
1100 return false;
1101 }
1102 if (LOG.isWarnEnabled()) {
1103 LOG.warn("Nothing done for execCommand(" + cmd + ", ...) (feature not implemented)");
1104 }
1105 return true;
1106 }
1107
1108
1109
1110
1111
1112 @JsxGetter(propertyName = "URL")
1113 public String getURL_js() {
1114 return getPage().getUrl().toExternalForm();
1115 }
1116
1117
1118
1119
1120
1121 @JsxGetter
1122 public String getDocumentURI() {
1123 return getURL_js();
1124 }
1125
1126
1127
1128
1129
1130 @JsxGetter
1131 public String getCookie() {
1132 final SgmlPage sgmlPage = getPage();
1133
1134 final StringBuilder builder = new StringBuilder();
1135 final Set<Cookie> cookies = sgmlPage.getWebClient().getCookies(sgmlPage.getUrl());
1136 for (final Cookie cookie : cookies) {
1137 if (cookie.isHttpOnly()) {
1138 continue;
1139 }
1140 if (builder.length() != 0) {
1141 builder.append("; ");
1142 }
1143 if (!HtmlUnitBrowserCompatCookieSpec.EMPTY_COOKIE_NAME.equals(cookie.getName())) {
1144 builder.append(cookie.getName()).append('=');
1145 }
1146 builder.append(cookie.getValue());
1147 }
1148
1149 return builder.toString();
1150 }
1151
1152
1153
1154
1155
1156
1157 @JsxSetter
1158 public void setCookie(final String newCookie) {
1159 if (StringUtils.isBlank(newCookie)) {
1160 return;
1161 }
1162
1163 final SgmlPage sgmlPage = getPage();
1164 sgmlPage.getWebClient().addCookie(newCookie, sgmlPage.getUrl(), this);
1165 }
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 @JsxFunction
1179 public Event createEvent(final String eventType) throws DOMException {
1180 Class<? extends Event> clazz = SUPPORTED_DOM2_EVENT_TYPE_MAP.get(eventType);
1181 if (clazz == null) {
1182 clazz = SUPPORTED_DOM3_EVENT_TYPE_MAP.get(eventType);
1183 }
1184
1185 if (MutationEvent.class == clazz
1186 && !getBrowserVersion().hasFeature(EVENT_TYPE_MUTATIONEVENT)) {
1187 clazz = null;
1188 }
1189 else if (clazz == null
1190 && ("Events".equals(eventType)
1191 || "HashChangeEvent".equals(eventType)
1192 || "BeforeUnloadEvent".equals(eventType)
1193 || "FocusEvent".equals(eventType))) {
1194 clazz = SUPPORTED_VENDOR_EVENT_TYPE_MAP.get(eventType);
1195 }
1196
1197 if (clazz == null) {
1198 throw JavaScriptEngine.asJavaScriptException(
1199 this,
1200 "Event Type '" + eventType + "' is not supported.",
1201 org.htmlunit.javascript.host.dom.DOMException.NOT_SUPPORTED_ERR);
1202 }
1203
1204 try {
1205 final Event event = clazz.getDeclaredConstructor().newInstance();
1206 event.setParentScope(getParentScope());
1207 event.setPrototype(getPrototype(clazz));
1208 event.eventCreated();
1209 return event;
1210 }
1211 catch (final InstantiationException | IllegalAccessException
1212 | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
1213 throw JavaScriptEngine.reportRuntimeError("Failed to instantiate event: class ='" + clazz.getName()
1214 + "' for event type of '" + eventType + "': " + e.getMessage());
1215 }
1216 }
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227 @JsxFunction
1228 public NodeIterator createNodeIterator(final Node root, final int whatToShow, final Scriptable filter) {
1229 final org.w3c.dom.traversal.NodeFilter filterWrapper = createFilterWrapper(filter, false);
1230 final NodeIterator iterator = new NodeIterator(root, whatToShow, filterWrapper);
1231 iterator.setParentScope(getParentScope());
1232 iterator.setPrototype(getPrototype(iterator.getClass()));
1233 return iterator;
1234 }
1235
1236 private static org.w3c.dom.traversal.NodeFilter createFilterWrapper(final Scriptable filter,
1237 final boolean filterFunctionOnly) {
1238 org.w3c.dom.traversal.NodeFilter filterWrapper = null;
1239 if (filter != null) {
1240 filterWrapper = n -> {
1241 final Object[] args = {((DomNode) n).getScriptableObject()};
1242 final Object response;
1243 if (filter instanceof Callable callable) {
1244 response = callable.call(Context.getCurrentContext(), filter.getParentScope(), filter, args);
1245 }
1246 else {
1247 if (filterFunctionOnly) {
1248 throw JavaScriptEngine.reportRuntimeError("only a function is allowed as filter");
1249 }
1250 response = ScriptableObject.callMethod(filter, "acceptNode", args);
1251 }
1252 return (short) JavaScriptEngine.toNumber(response);
1253 };
1254 }
1255 return filterWrapper;
1256 }
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279 @JsxFunction
1280 public TreeWalker createTreeWalker(final Node root, final double whatToShow, final Scriptable filter,
1281 final boolean expandEntityReferences) throws DOMException {
1282
1283
1284
1285 final int whatToShowI = (int) Double.valueOf(whatToShow).longValue();
1286
1287 final org.w3c.dom.traversal.NodeFilter filterWrapper = createFilterWrapper(filter, false);
1288 final TreeWalker t = new TreeWalker(root, whatToShowI, filterWrapper, false);
1289 t.setParentScope(getParentScope());
1290 t.setPrototype(staticGetPrototype(getWindow(this), TreeWalker.class));
1291 return t;
1292 }
1293
1294 @SuppressWarnings("unchecked")
1295 private static Scriptable staticGetPrototype(final Window window,
1296 final Class<? extends HtmlUnitScriptable> javaScriptClass) {
1297 final Scriptable prototype = window.getPrototype(javaScriptClass);
1298 if (prototype == null && javaScriptClass != HtmlUnitScriptable.class) {
1299 return staticGetPrototype(window, (Class<? extends HtmlUnitScriptable>) javaScriptClass.getSuperclass());
1300 }
1301 return prototype;
1302 }
1303
1304
1305
1306
1307
1308
1309 @JsxFunction
1310 public Range createRange() {
1311 final Range range = new Range(this);
1312 range.setParentScope(getParentScope());
1313 range.setPrototype(getPrototype(Range.class));
1314 return range;
1315 }
1316
1317
1318
1319
1320
1321
1322
1323
1324 @JsxGetter
1325 public String getDomain() {
1326 if (domain_ == null && getPage().getWebResponse() != null) {
1327 URL url = getPage().getUrl();
1328 if (url == UrlUtils.URL_ABOUT_BLANK) {
1329 final WebWindow w = getWindow().getWebWindow();
1330 if (w instanceof FrameWindow window) {
1331 url = window.getEnclosingPage().getUrl();
1332 }
1333 else {
1334 return null;
1335 }
1336 }
1337 domain_ = url.getHost().toLowerCase(Locale.ROOT);
1338 }
1339
1340 return domain_;
1341 }
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371 @JsxSetter
1372 public void setDomain(String newDomain) {
1373 newDomain = newDomain.toLowerCase(Locale.ROOT);
1374
1375 final String currentDomain = getDomain();
1376 if (currentDomain.equalsIgnoreCase(newDomain)) {
1377 return;
1378 }
1379
1380 if (newDomain.indexOf('.') == -1) {
1381 throw JavaScriptEngine.reportRuntimeError("Illegal domain value, cannot set domain from: \""
1382 + currentDomain + "\" to: \"" + newDomain + "\" (new domain has to contain a dot).");
1383 }
1384
1385 if (currentDomain.indexOf('.') > -1
1386 && !currentDomain.toLowerCase(Locale.ROOT).endsWith("." + newDomain.toLowerCase(Locale.ROOT))) {
1387 throw JavaScriptEngine.reportRuntimeError("Illegal domain value, cannot set domain from: \""
1388 + currentDomain + "\" to: \"" + newDomain + "\"");
1389 }
1390
1391 domain_ = newDomain;
1392 }
1393
1394
1395
1396
1397
1398 @JsxSetter
1399 public void setOnclick(final Object handler) {
1400 setEventHandler(MouseEvent.TYPE_CLICK, handler);
1401 }
1402
1403
1404
1405
1406
1407 @JsxGetter
1408 public Function getOnclick() {
1409 return getEventHandler(MouseEvent.TYPE_CLICK);
1410 }
1411
1412
1413
1414
1415
1416 @JsxSetter
1417 public void setOndblclick(final Object handler) {
1418 setEventHandler(MouseEvent.TYPE_DBL_CLICK, handler);
1419 }
1420
1421
1422
1423
1424
1425 @JsxGetter
1426 public Function getOndblclick() {
1427 return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
1428 }
1429
1430
1431
1432
1433
1434 @JsxSetter
1435 public void setOnblur(final Object handler) {
1436 setEventHandler(Event.TYPE_BLUR, handler);
1437 }
1438
1439
1440
1441
1442
1443 @JsxGetter
1444 public Function getOnblur() {
1445 return getEventHandler(Event.TYPE_BLUR);
1446 }
1447
1448
1449
1450
1451
1452 @JsxSetter
1453 public void setOnfocus(final Object handler) {
1454 setEventHandler(Event.TYPE_FOCUS, handler);
1455 }
1456
1457
1458
1459
1460
1461 @JsxGetter
1462 public Function getOnfocus() {
1463 return getEventHandler(Event.TYPE_FOCUS);
1464 }
1465
1466
1467
1468
1469
1470 @JsxSetter
1471 public void setOnkeydown(final Object handler) {
1472 setEventHandler(Event.TYPE_KEY_DOWN, handler);
1473 }
1474
1475
1476
1477
1478
1479 @JsxGetter
1480 public Function getOnkeydown() {
1481 return getEventHandler(Event.TYPE_KEY_DOWN);
1482 }
1483
1484
1485
1486
1487
1488 @JsxSetter
1489 public void setOnkeypress(final Object handler) {
1490 setEventHandler(Event.TYPE_KEY_PRESS, handler);
1491 }
1492
1493
1494
1495
1496
1497 @JsxGetter
1498 public Function getOnkeypress() {
1499 return getEventHandler(Event.TYPE_KEY_PRESS);
1500 }
1501
1502
1503
1504
1505
1506 @JsxSetter
1507 public void setOnkeyup(final Object handler) {
1508 setEventHandler(Event.TYPE_KEY_UP, handler);
1509 }
1510
1511
1512
1513
1514
1515 @JsxGetter
1516 public Function getOnkeyup() {
1517 return getEventHandler(Event.TYPE_KEY_UP);
1518 }
1519
1520
1521
1522
1523
1524 @JsxSetter
1525 public void setOnmousedown(final Object handler) {
1526 setEventHandler(MouseEvent.TYPE_MOUSE_DOWN, handler);
1527 }
1528
1529
1530
1531
1532
1533 @JsxGetter
1534 public Function getOnmousedown() {
1535 return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
1536 }
1537
1538
1539
1540
1541
1542 @JsxSetter
1543 public void setOnmousemove(final Object handler) {
1544 setEventHandler(MouseEvent.TYPE_MOUSE_MOVE, handler);
1545 }
1546
1547
1548
1549
1550
1551 @JsxGetter
1552 public Function getOnmousemove() {
1553 return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
1554 }
1555
1556
1557
1558
1559
1560 @JsxSetter
1561 public void setOnmouseout(final Object handler) {
1562 setEventHandler(MouseEvent.TYPE_MOUSE_OUT, handler);
1563 }
1564
1565
1566
1567
1568
1569 @JsxGetter
1570 public Function getOnmouseout() {
1571 return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
1572 }
1573
1574
1575
1576
1577
1578 @JsxSetter
1579 public void setOnmouseover(final Object handler) {
1580 setEventHandler(MouseEvent.TYPE_MOUSE_OVER, handler);
1581 }
1582
1583
1584
1585
1586
1587 @JsxGetter
1588 public Function getOnmouseover() {
1589 return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
1590 }
1591
1592
1593
1594
1595
1596 @JsxSetter
1597 public void setOnmouseup(final Object handler) {
1598 setEventHandler(MouseEvent.TYPE_MOUSE_UP, handler);
1599 }
1600
1601
1602
1603
1604
1605 @JsxGetter
1606 public Function getOnmouseup() {
1607 return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
1608 }
1609
1610
1611
1612
1613
1614 @JsxSetter
1615 public void setOncontextmenu(final Object handler) {
1616 setEventHandler(MouseEvent.TYPE_CONTEXT_MENU, handler);
1617 }
1618
1619
1620
1621
1622
1623 @JsxGetter
1624 public Function getOncontextmenu() {
1625 return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
1626 }
1627
1628
1629
1630
1631
1632 @JsxSetter
1633 public void setOnresize(final Object handler) {
1634 setEventHandler(Event.TYPE_RESIZE, handler);
1635 }
1636
1637
1638
1639
1640
1641 @JsxGetter
1642 public Function getOnresize() {
1643 return getEventHandler(Event.TYPE_RESIZE);
1644 }
1645
1646
1647
1648
1649
1650 @JsxSetter
1651 public void setOnerror(final Object handler) {
1652 setEventHandler(Event.TYPE_ERROR, handler);
1653 }
1654
1655
1656
1657
1658
1659 @JsxGetter
1660 public Function getOnerror() {
1661 return getEventHandler(Event.TYPE_ERROR);
1662 }
1663
1664
1665
1666
1667
1668 @JsxGetter
1669 public Function getOninput() {
1670 return getEventHandler(Event.TYPE_INPUT);
1671 }
1672
1673
1674
1675
1676
1677 @JsxSetter
1678 public void setOninput(final Object oninput) {
1679 setEventHandler(Event.TYPE_INPUT, oninput);
1680 }
1681
1682
1683
1684
1685
1686 @JsxGetter
1687 public boolean isHidden() {
1688 return false;
1689 }
1690
1691
1692
1693
1694 @Override
1695 @JsxGetter
1696 public int getChildElementCount() {
1697 int counter = 0;
1698 if (getPage().getDocumentElement() != null) {
1699 counter++;
1700 }
1701 return counter;
1702 }
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712 @JsxFunction
1713 public HtmlUnitScriptable elementFromPoint(final int x, final int y) {
1714 return null;
1715 }
1716
1717
1718
1719
1720
1721 @JsxGetter
1722 public HTMLCollection getForms() {
1723 final HTMLCollection forms = new HTMLCollection(getDomNodeOrDie(), false);
1724
1725 forms.setIsMatchingPredicate(
1726 (Predicate<DomNode> & Serializable)
1727 node -> node instanceof HtmlForm && node.getPrefix() == null);
1728 return forms;
1729 }
1730
1731
1732
1733
1734
1735 @JsxGetter
1736 public HTMLCollection getEmbeds() {
1737 final HTMLCollection embeds = new HTMLCollection(getDomNodeOrDie(), false);
1738
1739 embeds.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlEmbed);
1740 return embeds;
1741 }
1742
1743
1744
1745
1746
1747 @JsxGetter
1748 public HTMLCollection getImages() {
1749 final HTMLCollection images = new HTMLCollection(getDomNodeOrDie(), false);
1750
1751 images.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlImage);
1752 return images;
1753 }
1754
1755
1756
1757
1758
1759 @JsxGetter
1760 public HTMLCollection getScripts() {
1761 final HTMLCollection scripts = new HTMLCollection(getDomNodeOrDie(), false);
1762
1763 scripts.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlScript);
1764 return scripts;
1765 }
1766
1767
1768
1769
1770
1771
1772
1773
1774 @JsxGetter
1775 public StyleSheetList getStyleSheets() {
1776 if (styleSheetList_ == null) {
1777 styleSheetList_ = new StyleSheetList(this);
1778 }
1779 return styleSheetList_;
1780 }
1781
1782
1783
1784
1785
1786 @JsxGetter
1787 public HTMLCollection getPlugins() {
1788 return getEmbeds();
1789 }
1790
1791
1792
1793
1794
1795
1796 @JsxGetter
1797 public HTMLCollection getLinks() {
1798 final HTMLCollection links = new HTMLCollection(getDomNodeOrDie(), true);
1799
1800 links.setEffectOnCacheFunction(
1801 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1802 event -> {
1803 final HtmlElement node = event.getHtmlElement();
1804 if ((node instanceof HtmlAnchor || node instanceof HtmlArea) && "href".equals(event.getName())) {
1805 return EffectOnCache.RESET;
1806 }
1807 return EffectOnCache.NONE;
1808 });
1809
1810 links.setIsMatchingPredicate(
1811 (Predicate<DomNode> & Serializable)
1812 node ->
1813 (node instanceof HtmlAnchor || node instanceof HtmlArea)
1814 && ((HtmlElement) node).hasAttribute("href"));
1815
1816 return links;
1817 }
1818
1819
1820
1821
1822
1823
1824
1825 @JsxFunction
1826 public HTMLCollection getElementsByClassName(final String className) {
1827 return null;
1828 }
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839 @JsxFunction
1840 public NodeList getElementsByName(final String elementName) {
1841 return null;
1842 }
1843
1844
1845
1846
1847
1848
1849 @JsxFunction
1850 public boolean hasFocus() {
1851 return false;
1852 }
1853
1854
1855
1856
1857
1858 @JsxGetter
1859 public String getTitle() {
1860 return "";
1861 }
1862
1863
1864
1865
1866
1867 @JsxSetter
1868 public void setTitle(final String title) {
1869
1870 }
1871
1872
1873
1874
1875 @Override
1876 @JsxGetter
1877 public HTMLCollection getChildren() {
1878 return super.getChildren();
1879 }
1880
1881
1882
1883
1884
1885 @JsxGetter
1886 public String getContentType() {
1887 return getPage().getContentType();
1888 }
1889
1890
1891
1892
1893
1894 @JsxFunction
1895 public Selection getSelection() {
1896 return null;
1897 }
1898
1899
1900
1901
1902
1903 @JsxGetter
1904 public Object getHead() {
1905 return null;
1906 }
1907
1908
1909
1910
1911
1912 @JsxGetter
1913 public String getInputEncoding() {
1914 return getPage().getCharset().name();
1915 }
1916
1917
1918
1919
1920
1921
1922 @JsxGetter
1923 public String getLastModified() {
1924 if (lastModified_ == null) {
1925 final WebResponse webResponse = getPage().getWebResponse();
1926 final Date lastModified;
1927 if (webResponse != null) {
1928 String stringDate = webResponse.getResponseHeaderValue("Last-Modified");
1929 if (stringDate == null) {
1930 stringDate = webResponse.getResponseHeaderValue("Date");
1931 }
1932 lastModified = parseDateOrNow(stringDate);
1933 }
1934 else {
1935 lastModified = new Date();
1936 }
1937
1938 final ZoneId zoneid = Context.getCurrentContext().getTimeZone().toZoneId();
1939 lastModified_ = LAST_MODIFIED_DATE_FORMATTER.format(lastModified.toInstant().atZone(zoneid));
1940 }
1941 return lastModified_;
1942 }
1943
1944 private static Date parseDateOrNow(final String stringDate) {
1945 final Date date = HttpUtils.parseDate(stringDate);
1946 if (date == null) {
1947 return new Date();
1948 }
1949 return date;
1950 }
1951
1952
1953
1954
1955 @JsxFunction({FF, FF_ESR})
1956 public void releaseCapture() {
1957
1958 }
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970 @JsxGetter
1971 public String getReadyState() {
1972 return getDomNodeOrDie().getReadyState();
1973 }
1974
1975
1976
1977
1978
1979
1980
1981 @JsxFunction
1982 public void captureEvents(final String type) {
1983
1984 }
1985
1986
1987
1988
1989
1990
1991
1992 @JsxFunction
1993 public void releaseEvents(final String type) {
1994
1995 }
1996
1997
1998
1999
2000
2001 @JsxGetter
2002 public String getAlinkColor() {
2003 final HTMLElement body = getBody();
2004 if (body instanceof HTMLBodyElement element) {
2005 return element.getALink();
2006 }
2007 return null;
2008 }
2009
2010
2011
2012
2013
2014 @JsxSetter
2015 public void setAlinkColor(final String color) {
2016 final HTMLElement body = getBody();
2017 if (body instanceof HTMLBodyElement element) {
2018 element.setALink(color);
2019 }
2020 }
2021
2022
2023
2024
2025
2026
2027 @JsxGetter
2028 public String getBgColor() {
2029 final HTMLElement body = getBody();
2030 if (body instanceof HTMLBodyElement element) {
2031 return element.getBgColor();
2032 }
2033 return null;
2034 }
2035
2036
2037
2038
2039
2040
2041 @JsxSetter
2042 public void setBgColor(final String color) {
2043 final HTMLElement body = getBody();
2044 if (body instanceof HTMLBodyElement element) {
2045 element.setBgColor(color);
2046 }
2047 }
2048
2049
2050
2051
2052
2053 @JsxGetter
2054 public String getFgColor() {
2055 final HTMLElement body = getBody();
2056 if (body instanceof HTMLBodyElement element) {
2057 return element.getText();
2058 }
2059 return null;
2060 }
2061
2062
2063
2064
2065
2066 @JsxSetter
2067 public void setFgColor(final String color) {
2068 final HTMLElement body = getBody();
2069 if (body instanceof HTMLBodyElement element) {
2070 element.setText(color);
2071 }
2072 }
2073
2074
2075
2076
2077
2078 @JsxGetter
2079 public String getLinkColor() {
2080 final HTMLElement body = getBody();
2081 if (body instanceof HTMLBodyElement element) {
2082 return element.getLink();
2083 }
2084 return null;
2085 }
2086
2087
2088
2089
2090
2091 @JsxSetter
2092 public void setLinkColor(final String color) {
2093 final HTMLElement body = getBody();
2094 if (body instanceof HTMLBodyElement element) {
2095 element.setLink(color);
2096 }
2097 }
2098
2099
2100
2101
2102
2103 @JsxGetter
2104 public String getVlinkColor() {
2105 final HTMLElement body = getBody();
2106 if (body instanceof HTMLBodyElement element) {
2107 return element.getVLink();
2108 }
2109 return null;
2110 }
2111
2112
2113
2114
2115
2116 @JsxSetter
2117 public void setVlinkColor(final String color) {
2118 final HTMLElement body = getBody();
2119 if (body instanceof HTMLBodyElement element) {
2120 element.setVLink(color);
2121 }
2122 }
2123
2124
2125
2126
2127 @Override
2128 @JsxGetter
2129 public Element getLastElementChild() {
2130 return super.getLastElementChild();
2131 }
2132
2133
2134
2135
2136 @Override
2137 @JsxGetter
2138 public Element getFirstElementChild() {
2139 return super.getFirstElementChild();
2140 }
2141
2142
2143
2144
2145
2146 @JsxGetter({CHROME, EDGE})
2147 public String getXmlEncoding() {
2148 return getPage().getXmlEncoding();
2149 }
2150
2151
2152
2153
2154
2155 @JsxGetter({CHROME, EDGE})
2156 public boolean isXmlStandalone() {
2157 return getPage().getXmlStandalone();
2158 }
2159
2160
2161
2162
2163
2164 @JsxGetter({CHROME, EDGE})
2165 public String getXmlVersion() {
2166 return getPage().getXmlVersion();
2167 }
2168
2169
2170
2171
2172
2173 @JsxGetter
2174 public Function getOnabort() {
2175 return getEventHandler(Event.TYPE_ABORT);
2176 }
2177
2178
2179
2180
2181
2182 @JsxSetter
2183 public void setOnabort(final Object onabort) {
2184 setEventHandler(Event.TYPE_ABORT, onabort);
2185 }
2186
2187
2188
2189
2190
2191 @JsxGetter({CHROME, EDGE})
2192 public Function getOnauxclick() {
2193 return getEventHandler(Event.TYPE_AUXCLICK);
2194 }
2195
2196
2197
2198
2199
2200 @JsxSetter({CHROME, EDGE})
2201 public void setOnauxclick(final Object onauxclick) {
2202 setEventHandler(Event.TYPE_AUXCLICK, onauxclick);
2203 }
2204
2205
2206
2207
2208
2209 @JsxGetter({CHROME, EDGE})
2210 public Function getOnbeforecopy() {
2211 return getEventHandler(Event.TYPE_BEFORECOPY);
2212 }
2213
2214
2215
2216
2217
2218 @JsxSetter({CHROME, EDGE})
2219 public void setOnbeforecopy(final Object onbeforecopy) {
2220 setEventHandler(Event.TYPE_BEFORECOPY, onbeforecopy);
2221 }
2222
2223
2224
2225
2226
2227 @JsxGetter({CHROME, EDGE})
2228 public Function getOnbeforecut() {
2229 return getEventHandler(Event.TYPE_BEFORECUT);
2230 }
2231
2232
2233
2234
2235
2236 @JsxSetter({CHROME, EDGE})
2237 public void setOnbeforecut(final Object onbeforecut) {
2238 setEventHandler(Event.TYPE_BEFORECUT, onbeforecut);
2239 }
2240
2241
2242
2243
2244
2245 @JsxGetter({CHROME, EDGE})
2246 public Function getOnbeforepaste() {
2247 return getEventHandler(Event.TYPE_BEFOREPASTE);
2248 }
2249
2250
2251
2252
2253
2254 @JsxSetter({CHROME, EDGE})
2255 public void setOnbeforepaste(final Object onbeforepaste) {
2256 setEventHandler(Event.TYPE_BEFOREPASTE, onbeforepaste);
2257 }
2258
2259
2260
2261
2262
2263 @JsxGetter({CHROME, EDGE})
2264 public Function getOncancel() {
2265 return getEventHandler(Event.TYPE_CANCEL);
2266 }
2267
2268
2269
2270
2271
2272 @JsxSetter({CHROME, EDGE})
2273 public void setOncancel(final Object oncancel) {
2274 setEventHandler(Event.TYPE_CANCEL, oncancel);
2275 }
2276
2277
2278
2279
2280
2281 @JsxGetter
2282 public Function getOncanplay() {
2283 return getEventHandler(Event.TYPE_CANPLAY);
2284 }
2285
2286
2287
2288
2289
2290 @JsxSetter
2291 public void setOncanplay(final Object oncanplay) {
2292 setEventHandler(Event.TYPE_CANPLAY, oncanplay);
2293 }
2294
2295
2296
2297
2298
2299 @JsxGetter
2300 public Function getOncanplaythrough() {
2301 return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2302 }
2303
2304
2305
2306
2307
2308 @JsxSetter
2309 public void setOncanplaythrough(final Object oncanplaythrough) {
2310 setEventHandler(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2311 }
2312
2313
2314
2315
2316
2317 @JsxGetter
2318 public Function getOnchange() {
2319 return getEventHandler(Event.TYPE_CHANGE);
2320 }
2321
2322
2323
2324
2325
2326 @JsxSetter
2327 public void setOnchange(final Object onchange) {
2328 setEventHandler(Event.TYPE_CHANGE, onchange);
2329 }
2330
2331
2332
2333
2334
2335 @JsxGetter({CHROME, EDGE})
2336 public Function getOnclose() {
2337 return getEventHandler(Event.TYPE_CLOSE);
2338 }
2339
2340
2341
2342
2343
2344 @JsxSetter({CHROME, EDGE})
2345 public void setOnclose(final Object onclose) {
2346 setEventHandler(Event.TYPE_CLOSE, onclose);
2347 }
2348
2349
2350
2351
2352
2353 @JsxGetter
2354 public Function getOncopy() {
2355 return getEventHandler(Event.TYPE_COPY);
2356 }
2357
2358
2359
2360
2361
2362 @JsxSetter
2363 public void setOncopy(final Object oncopy) {
2364 setEventHandler(Event.TYPE_COPY, oncopy);
2365 }
2366
2367
2368
2369
2370
2371 @JsxGetter({CHROME, EDGE})
2372 public Function getOncuechange() {
2373 return getEventHandler(Event.TYPE_CUECHANGE);
2374 }
2375
2376
2377
2378
2379
2380 @JsxSetter({CHROME, EDGE})
2381 public void setOncuechange(final Object oncuechange) {
2382 setEventHandler(Event.TYPE_CUECHANGE, oncuechange);
2383 }
2384
2385
2386
2387
2388
2389 @JsxGetter
2390 public Function getOncut() {
2391 return getEventHandler(Event.TYPE_CUT);
2392 }
2393
2394
2395
2396
2397
2398 @JsxSetter
2399 public void setOncut(final Object oncut) {
2400 setEventHandler(Event.TYPE_CUT, oncut);
2401 }
2402
2403
2404
2405
2406
2407 @JsxGetter
2408 public Function getOndrag() {
2409 return getEventHandler(Event.TYPE_DRAG);
2410 }
2411
2412
2413
2414
2415
2416 @JsxSetter
2417 public void setOndrag(final Object ondrag) {
2418 setEventHandler(Event.TYPE_DRAG, ondrag);
2419 }
2420
2421
2422
2423
2424
2425 @JsxGetter
2426 public Function getOndragend() {
2427 return getEventHandler(Event.TYPE_DRAGEND);
2428 }
2429
2430
2431
2432
2433
2434 @JsxSetter
2435 public void setOndragend(final Object ondragend) {
2436 setEventHandler(Event.TYPE_DRAGEND, ondragend);
2437 }
2438
2439
2440
2441
2442
2443 @JsxGetter
2444 public Function getOndragenter() {
2445 return getEventHandler(Event.TYPE_DRAGENTER);
2446 }
2447
2448
2449
2450
2451
2452 @JsxSetter
2453 public void setOndragenter(final Object ondragenter) {
2454 setEventHandler(Event.TYPE_DRAGENTER, ondragenter);
2455 }
2456
2457
2458
2459
2460
2461 @JsxGetter
2462 public Function getOndragleave() {
2463 return getEventHandler(Event.TYPE_DRAGLEAVE);
2464 }
2465
2466
2467
2468
2469
2470 @JsxSetter
2471 public void setOndragleave(final Object ondragleave) {
2472 setEventHandler(Event.TYPE_DRAGLEAVE, ondragleave);
2473 }
2474
2475
2476
2477
2478
2479 @JsxGetter
2480 public Function getOndragover() {
2481 return getEventHandler(Event.TYPE_DRAGOVER);
2482 }
2483
2484
2485
2486
2487
2488 @JsxSetter
2489 public void setOndragover(final Object ondragover) {
2490 setEventHandler(Event.TYPE_DRAGOVER, ondragover);
2491 }
2492
2493
2494
2495
2496
2497 @JsxGetter
2498 public Function getOndragstart() {
2499 return getEventHandler(Event.TYPE_DRAGSTART);
2500 }
2501
2502
2503
2504
2505
2506 @JsxSetter
2507 public void setOndragstart(final Object ondragstart) {
2508 setEventHandler(Event.TYPE_DRAGSTART, ondragstart);
2509 }
2510
2511
2512
2513
2514
2515 @JsxGetter
2516 public Function getOndrop() {
2517 return getEventHandler(Event.TYPE_DROP);
2518 }
2519
2520
2521
2522
2523
2524 @JsxSetter
2525 public void setOndrop(final Object ondrop) {
2526 setEventHandler(Event.TYPE_DROP, ondrop);
2527 }
2528
2529
2530
2531
2532
2533 @JsxGetter
2534 public Function getOndurationchange() {
2535 return getEventHandler(Event.TYPE_DURATIONCHANGE);
2536 }
2537
2538
2539
2540
2541
2542 @JsxSetter
2543 public void setOndurationchange(final Object ondurationchange) {
2544 setEventHandler(Event.TYPE_DURATIONCHANGE, ondurationchange);
2545 }
2546
2547
2548
2549
2550
2551 @JsxGetter
2552 public Function getOnemptied() {
2553 return getEventHandler(Event.TYPE_EMPTIED);
2554 }
2555
2556
2557
2558
2559
2560 @JsxSetter
2561 public void setOnemptied(final Object onemptied) {
2562 setEventHandler(Event.TYPE_EMPTIED, onemptied);
2563 }
2564
2565
2566
2567
2568
2569 @JsxGetter
2570 public Function getOnended() {
2571 return getEventHandler(Event.TYPE_ENDED);
2572 }
2573
2574
2575
2576
2577
2578 @JsxSetter
2579 public void setOnended(final Object onended) {
2580 setEventHandler(Event.TYPE_ENDED, onended);
2581 }
2582
2583
2584
2585
2586
2587 @JsxGetter({CHROME, EDGE})
2588 public Function getOngotpointercapture() {
2589 return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
2590 }
2591
2592
2593
2594
2595
2596 @JsxSetter({CHROME, EDGE})
2597 public void setOngotpointercapture(final Object ongotpointercapture) {
2598 setEventHandler(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
2599 }
2600
2601
2602
2603
2604
2605 @JsxGetter
2606 public Function getOninvalid() {
2607 return getEventHandler(Event.TYPE_INVALID);
2608 }
2609
2610
2611
2612
2613
2614 @JsxSetter
2615 public void setOninvalid(final Object oninvalid) {
2616 setEventHandler(Event.TYPE_INVALID, oninvalid);
2617 }
2618
2619
2620
2621
2622
2623 @JsxGetter
2624 public Function getOnload() {
2625 return getEventHandler(Event.TYPE_LOAD);
2626 }
2627
2628
2629
2630
2631
2632 @JsxSetter
2633 public void setOnload(final Object onload) {
2634 setEventHandler(Event.TYPE_LOAD, onload);
2635 }
2636
2637
2638
2639
2640
2641 @JsxGetter
2642 public Function getOnloadeddata() {
2643 return getEventHandler(Event.TYPE_LOADEDDATA);
2644 }
2645
2646
2647
2648
2649
2650 @JsxSetter
2651 public void setOnloadeddata(final Object onloadeddata) {
2652 setEventHandler(Event.TYPE_LOADEDDATA, onloadeddata);
2653 }
2654
2655
2656
2657
2658
2659 @JsxGetter
2660 public Function getOnloadedmetadata() {
2661 return getEventHandler(Event.TYPE_LOADEDMETADATA);
2662 }
2663
2664
2665
2666
2667
2668 @JsxSetter
2669 public void setOnloadedmetadata(final Object onloadedmetadata) {
2670 setEventHandler(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
2671 }
2672
2673
2674
2675
2676
2677 @JsxGetter
2678 public Function getOnloadstart() {
2679 return getEventHandler(Event.TYPE_LOAD_START);
2680 }
2681
2682
2683
2684
2685
2686 @JsxSetter
2687 public void setOnloadstart(final Object onloadstart) {
2688 setEventHandler(Event.TYPE_LOAD_START, onloadstart);
2689 }
2690
2691
2692
2693
2694
2695 @JsxGetter({CHROME, EDGE})
2696 public Function getOnlostpointercapture() {
2697 return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2698 }
2699
2700
2701
2702
2703
2704 @JsxSetter({CHROME, EDGE})
2705 public void setOnlostpointercapture(final Object onlostpointercapture) {
2706 setEventHandler(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2707 }
2708
2709
2710
2711
2712
2713 @JsxGetter
2714 public Function getOnmouseenter() {
2715 return getEventHandler(Event.TYPE_MOUDEENTER);
2716 }
2717
2718
2719
2720
2721
2722 @JsxSetter
2723 public void setOnmouseenter(final Object onmouseenter) {
2724 setEventHandler(Event.TYPE_MOUDEENTER, onmouseenter);
2725 }
2726
2727
2728
2729
2730
2731 @JsxGetter
2732 public Function getOnmouseleave() {
2733 return getEventHandler(Event.TYPE_MOUSELEAVE);
2734 }
2735
2736
2737
2738
2739
2740 @JsxSetter
2741 public void setOnmouseleave(final Object onmouseleave) {
2742 setEventHandler(Event.TYPE_MOUSELEAVE, onmouseleave);
2743 }
2744
2745
2746
2747
2748
2749 @JsxGetter({CHROME, EDGE})
2750 public Function getOnmousewheel() {
2751 return getEventHandler(Event.TYPE_MOUSEWHEEL);
2752 }
2753
2754
2755
2756
2757
2758 @JsxSetter({CHROME, EDGE})
2759 public void setOnmousewheel(final Object onmousewheel) {
2760 setEventHandler(Event.TYPE_MOUSEWHEEL, onmousewheel);
2761 }
2762
2763
2764
2765
2766
2767 @JsxGetter
2768 public Function getOnpaste() {
2769 return getEventHandler(Event.TYPE_PASTE);
2770 }
2771
2772
2773
2774
2775
2776 @JsxSetter
2777 public void setOnpaste(final Object onpaste) {
2778 setEventHandler(Event.TYPE_PASTE, onpaste);
2779 }
2780
2781
2782
2783
2784
2785 @JsxGetter
2786 public Function getOnpause() {
2787 return getEventHandler(Event.TYPE_PAUSE);
2788 }
2789
2790
2791
2792
2793
2794 @JsxSetter
2795 public void setOnpause(final Object onpause) {
2796 setEventHandler(Event.TYPE_PAUSE, onpause);
2797 }
2798
2799
2800
2801
2802
2803 @JsxGetter
2804 public Function getOnplay() {
2805 return getEventHandler(Event.TYPE_PLAY);
2806 }
2807
2808
2809
2810
2811
2812 @JsxSetter
2813 public void setOnplay(final Object onplay) {
2814 setEventHandler(Event.TYPE_PLAY, onplay);
2815 }
2816
2817
2818
2819
2820
2821 @JsxGetter
2822 public Function getOnplaying() {
2823 return getEventHandler(Event.TYPE_PLAYING);
2824 }
2825
2826
2827
2828
2829
2830 @JsxSetter
2831 public void setOnplaying(final Object onplaying) {
2832 setEventHandler(Event.TYPE_PLAYING, onplaying);
2833 }
2834
2835
2836
2837
2838
2839 @JsxGetter({CHROME, EDGE})
2840 public Function getOnpointercancel() {
2841 return getEventHandler(Event.TYPE_POINTERCANCEL);
2842 }
2843
2844
2845
2846
2847
2848 @JsxSetter({CHROME, EDGE})
2849 public void setOnpointercancel(final Object onpointercancel) {
2850 setEventHandler(Event.TYPE_POINTERCANCEL, onpointercancel);
2851 }
2852
2853
2854
2855
2856
2857 @JsxGetter({CHROME, EDGE})
2858 public Function getOnpointerdown() {
2859 return getEventHandler(Event.TYPE_POINTERDOWN);
2860 }
2861
2862
2863
2864
2865
2866 @JsxSetter({CHROME, EDGE})
2867 public void setOnpointerdown(final Object onpointerdown) {
2868 setEventHandler(Event.TYPE_POINTERDOWN, onpointerdown);
2869 }
2870
2871
2872
2873
2874
2875 @JsxGetter({CHROME, EDGE})
2876 public Function getOnpointerenter() {
2877 return getEventHandler(Event.TYPE_POINTERENTER);
2878 }
2879
2880
2881
2882
2883
2884 @JsxSetter({CHROME, EDGE})
2885 public void setOnpointerenter(final Object onpointerenter) {
2886 setEventHandler(Event.TYPE_POINTERENTER, onpointerenter);
2887 }
2888
2889
2890
2891
2892
2893 @JsxGetter({CHROME, EDGE})
2894 public Function getOnpointerleave() {
2895 return getEventHandler(Event.TYPE_POINTERLEAVE);
2896 }
2897
2898
2899
2900
2901
2902 @JsxSetter({CHROME, EDGE})
2903 public void setOnpointerleave(final Object onpointerleave) {
2904 setEventHandler(Event.TYPE_POINTERLEAVE, onpointerleave);
2905 }
2906
2907
2908
2909
2910
2911 @JsxGetter({CHROME, EDGE})
2912 public Function getOnpointerlockchange() {
2913 return getEventHandler(Event.TYPE_POINTERLOCKCHANGE);
2914 }
2915
2916
2917
2918
2919
2920 @JsxSetter({CHROME, EDGE})
2921 public void setOnpointerlockchange(final Object onpointerlockchange) {
2922 setEventHandler(Event.TYPE_POINTERLOCKCHANGE, onpointerlockchange);
2923 }
2924
2925
2926
2927
2928
2929 @JsxGetter({CHROME, EDGE})
2930 public Function getOnpointerlockerror() {
2931 return getEventHandler(Event.TYPE_POINTERLOCKERROR);
2932 }
2933
2934
2935
2936
2937
2938 @JsxSetter({CHROME, EDGE})
2939 public void setOnpointerlockerror(final Object onpointerlockerror) {
2940 setEventHandler(Event.TYPE_POINTERLOCKERROR, onpointerlockerror);
2941 }
2942
2943
2944
2945
2946
2947 @JsxGetter({CHROME, EDGE})
2948 public Function getOnpointermove() {
2949 return getEventHandler(Event.TYPE_POINTERMOVE);
2950 }
2951
2952
2953
2954
2955
2956 @JsxSetter({CHROME, EDGE})
2957 public void setOnpointermove(final Object onpointermove) {
2958 setEventHandler(Event.TYPE_POINTERMOVE, onpointermove);
2959 }
2960
2961
2962
2963
2964
2965 @JsxGetter({CHROME, EDGE})
2966 public Function getOnpointerout() {
2967 return getEventHandler(Event.TYPE_POINTEROUT);
2968 }
2969
2970
2971
2972
2973
2974 @JsxSetter({CHROME, EDGE})
2975 public void setOnpointerout(final Object onpointerout) {
2976 setEventHandler(Event.TYPE_POINTEROUT, onpointerout);
2977 }
2978
2979
2980
2981
2982
2983 @JsxGetter({CHROME, EDGE})
2984 public Function getOnpointerover() {
2985 return getEventHandler(Event.TYPE_POINTEROVER);
2986 }
2987
2988
2989
2990
2991
2992 @JsxSetter({CHROME, EDGE})
2993 public void setOnpointerover(final Object onpointerover) {
2994 setEventHandler(Event.TYPE_POINTEROVER, onpointerover);
2995 }
2996
2997
2998
2999
3000
3001 @JsxGetter({CHROME, EDGE})
3002 public Function getOnpointerup() {
3003 return getEventHandler(Event.TYPE_POINTERUP);
3004 }
3005
3006
3007
3008
3009
3010 @JsxSetter({CHROME, EDGE})
3011 public void setOnpointerup(final Object onpointerup) {
3012 setEventHandler(Event.TYPE_POINTERUP, onpointerup);
3013 }
3014
3015
3016
3017
3018
3019 @JsxGetter
3020 public Function getOnprogress() {
3021 return getEventHandler(Event.TYPE_PROGRESS);
3022 }
3023
3024
3025
3026
3027
3028 @JsxSetter
3029 public void setOnprogress(final Object onprogress) {
3030 setEventHandler(Event.TYPE_PROGRESS, onprogress);
3031 }
3032
3033
3034
3035
3036
3037 @JsxGetter
3038 public Function getOnratechange() {
3039 return getEventHandler(Event.TYPE_RATECHANGE);
3040 }
3041
3042
3043
3044
3045
3046 @JsxSetter
3047 public void setOnratechange(final Object onratechange) {
3048 setEventHandler(Event.TYPE_RATECHANGE, onratechange);
3049 }
3050
3051
3052
3053
3054
3055 @JsxGetter
3056 public Function getOnreadystatechange() {
3057 return getEventHandler(Event.TYPE_READY_STATE_CHANGE);
3058 }
3059
3060
3061
3062
3063
3064 @JsxSetter
3065 public void setOnreadystatechange(final Object onreadystatechange) {
3066 setEventHandler(Event.TYPE_READY_STATE_CHANGE, onreadystatechange);
3067 }
3068
3069
3070
3071
3072
3073 @JsxGetter
3074 public Function getOnreset() {
3075 return getEventHandler(Event.TYPE_RESET);
3076 }
3077
3078
3079
3080
3081
3082 @JsxSetter
3083 public void setOnreset(final Object onreset) {
3084 setEventHandler(Event.TYPE_RESET, onreset);
3085 }
3086
3087
3088
3089
3090
3091 @JsxGetter
3092 public Function getOnscroll() {
3093 return getEventHandler(Event.TYPE_SCROLL);
3094 }
3095
3096
3097
3098
3099
3100 @JsxSetter
3101 public void setOnscroll(final Object onscroll) {
3102 setEventHandler(Event.TYPE_SCROLL, onscroll);
3103 }
3104
3105
3106
3107
3108
3109 @JsxGetter({CHROME, EDGE})
3110 public Function getOnsearch() {
3111 return getEventHandler(Event.TYPE_SEARCH);
3112 }
3113
3114
3115
3116
3117
3118 @JsxSetter({CHROME, EDGE})
3119 public void setOnsearch(final Object onsearch) {
3120 setEventHandler(Event.TYPE_SEARCH, onsearch);
3121 }
3122
3123
3124
3125
3126
3127 @JsxGetter
3128 public Function getOnseeked() {
3129 return getEventHandler(Event.TYPE_SEEKED);
3130 }
3131
3132
3133
3134
3135
3136 @JsxSetter
3137 public void setOnseeked(final Object onseeked) {
3138 setEventHandler(Event.TYPE_SEEKED, onseeked);
3139 }
3140
3141
3142
3143
3144
3145 @JsxGetter
3146 public Function getOnseeking() {
3147 return getEventHandler(Event.TYPE_SEEKING);
3148 }
3149
3150
3151
3152
3153
3154 @JsxSetter
3155 public void setOnseeking(final Object onseeking) {
3156 setEventHandler(Event.TYPE_SEEKING, onseeking);
3157 }
3158
3159
3160
3161
3162
3163 @JsxGetter
3164 public Function getOnselect() {
3165 return getEventHandler(Event.TYPE_SELECT);
3166 }
3167
3168
3169
3170
3171
3172 @JsxSetter
3173 public void setOnselect(final Object onselect) {
3174 setEventHandler(Event.TYPE_SELECT, onselect);
3175 }
3176
3177
3178
3179
3180
3181 @JsxGetter({CHROME, EDGE})
3182 public Function getOnselectionchange() {
3183 return getEventHandler(Event.TYPE_SELECTIONCHANGE);
3184 }
3185
3186
3187
3188
3189
3190 @JsxSetter({CHROME, EDGE})
3191 public void setOnselectionchange(final Object onselectionchange) {
3192 setEventHandler(Event.TYPE_SELECTIONCHANGE, onselectionchange);
3193 }
3194
3195
3196
3197
3198
3199 @JsxGetter
3200 public Function getOnselectstart() {
3201 return getEventHandler(Event.TYPE_SELECTSTART);
3202 }
3203
3204
3205
3206
3207
3208 @JsxSetter
3209 public void setOnselectstart(final Object onselectstart) {
3210 setEventHandler(Event.TYPE_SELECTSTART, onselectstart);
3211 }
3212
3213
3214
3215
3216
3217 @JsxGetter
3218 public Function getOnstalled() {
3219 return getEventHandler(Event.TYPE_STALLED);
3220 }
3221
3222
3223
3224
3225
3226 @JsxSetter
3227 public void setOnstalled(final Object onstalled) {
3228 setEventHandler(Event.TYPE_STALLED, onstalled);
3229 }
3230
3231
3232
3233
3234
3235 @JsxGetter
3236 public Function getOnsubmit() {
3237 return getEventHandler(Event.TYPE_SUBMIT);
3238 }
3239
3240
3241
3242
3243
3244 @JsxSetter
3245 public void setOnsubmit(final Object onsubmit) {
3246 setEventHandler(Event.TYPE_SUBMIT, onsubmit);
3247 }
3248
3249
3250
3251
3252
3253 @JsxGetter
3254 public Function getOnsuspend() {
3255 return getEventHandler(Event.TYPE_SUSPEND);
3256 }
3257
3258
3259
3260
3261
3262 @JsxSetter
3263 public void setOnsuspend(final Object onsuspend) {
3264 setEventHandler(Event.TYPE_SUSPEND, onsuspend);
3265 }
3266
3267
3268
3269
3270
3271 @JsxGetter
3272 public Function getOntimeupdate() {
3273 return getEventHandler(Event.TYPE_TIMEUPDATE);
3274 }
3275
3276
3277
3278
3279
3280 @JsxSetter
3281 public void setOntimeupdate(final Object ontimeupdate) {
3282 setEventHandler(Event.TYPE_TIMEUPDATE, ontimeupdate);
3283 }
3284
3285
3286
3287
3288
3289 @JsxGetter({CHROME, EDGE})
3290 public Function getOntoggle() {
3291 return getEventHandler(Event.TYPE_TOGGLE);
3292 }
3293
3294
3295
3296
3297
3298 @JsxSetter({CHROME, EDGE})
3299 public void setOntoggle(final Object ontoggle) {
3300 setEventHandler(Event.TYPE_TOGGLE, ontoggle);
3301 }
3302
3303
3304
3305
3306
3307 @JsxGetter
3308 public Function getOnvolumechange() {
3309 return getEventHandler(Event.TYPE_VOLUMECHANGE);
3310 }
3311
3312
3313
3314
3315
3316 @JsxSetter
3317 public void setOnvolumechange(final Object onvolumechange) {
3318 setEventHandler(Event.TYPE_VOLUMECHANGE, onvolumechange);
3319 }
3320
3321
3322
3323
3324
3325 @JsxGetter
3326 public Function getOnwaiting() {
3327 return getEventHandler(Event.TYPE_WAITING);
3328 }
3329
3330
3331
3332
3333
3334 @JsxSetter
3335 public void setOnwaiting(final Object onwaiting) {
3336 setEventHandler(Event.TYPE_WAITING, onwaiting);
3337 }
3338
3339
3340
3341
3342
3343 @JsxGetter({CHROME, EDGE})
3344 public Function getOnwebkitfullscreenchange() {
3345 return getEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE);
3346 }
3347
3348
3349
3350
3351
3352 @JsxSetter({CHROME, EDGE})
3353 public void setOnwebkitfullscreenchange(final Object onwebkitfullscreenchange) {
3354 setEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE, onwebkitfullscreenchange);
3355 }
3356
3357
3358
3359
3360
3361 @JsxGetter({CHROME, EDGE})
3362 public Function getOnwebkitfullscreenerror() {
3363 return getEventHandler(Event.TYPE_WEBKITFULLSCREENERROR);
3364 }
3365
3366
3367
3368
3369
3370 @JsxSetter
3371 public void setOnwebkitfullscreenerror(final Object onwebkitfullscreenerror) {
3372 setEventHandler(Event.TYPE_WEBKITFULLSCREENERROR, onwebkitfullscreenerror);
3373 }
3374
3375
3376
3377
3378
3379 @JsxGetter
3380 public Function getOnwheel() {
3381 return getEventHandler(Event.TYPE_WHEEL);
3382 }
3383
3384
3385
3386
3387
3388 @JsxSetter
3389 public void setOnwheel(final Object onwheel) {
3390 setEventHandler(Event.TYPE_WHEEL, onwheel);
3391 }
3392
3393
3394
3395
3396
3397 @JsxGetter({FF, FF_ESR})
3398 public Function getOnafterscriptexecute() {
3399 return getEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE);
3400 }
3401
3402
3403
3404
3405
3406 @JsxSetter({FF, FF_ESR})
3407 public void setOnafterscriptexecute(final Object onafterscriptexecute) {
3408 setEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE, onafterscriptexecute);
3409 }
3410
3411
3412
3413
3414
3415 @JsxGetter({FF, FF_ESR})
3416 public Function getOnbeforescriptexecute() {
3417 return getEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE);
3418 }
3419
3420
3421
3422
3423
3424 @JsxSetter({FF, FF_ESR})
3425 public void setOnbeforescriptexecute(final Object onbeforescriptexecute) {
3426 setEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE, onbeforescriptexecute);
3427 }
3428
3429
3430
3431
3432
3433 @JsxGetter({FF, FF_ESR})
3434 public Function getOnmozfullscreenchange() {
3435 return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
3436 }
3437
3438
3439
3440
3441
3442 @JsxSetter({FF, FF_ESR})
3443 public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
3444 setEventHandler(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
3445 }
3446
3447
3448
3449
3450
3451 @JsxGetter({FF, FF_ESR})
3452 public Function getOnmozfullscreenerror() {
3453 return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
3454 }
3455
3456
3457
3458
3459
3460 @JsxSetter({FF, FF_ESR})
3461 public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
3462 setEventHandler(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
3463 }
3464
3465
3466
3467
3468 @JsxGetter
3469 public ScriptableObject getCurrentScript() {
3470 return currentScript_;
3471 }
3472
3473
3474
3475
3476 public void setCurrentScript(final ScriptableObject script) {
3477 currentScript_ = script;
3478 }
3479
3480
3481
3482
3483 @JsxGetter
3484 public ScriptableObject getFonts() {
3485 if (fonts_ == null) {
3486 final FontFaceSet fonts = new FontFaceSet();
3487 fonts.setParentScope(getParentScope());
3488 fonts.setPrototype(getPrototype(fonts.getClass()));
3489 fonts_ = fonts;
3490 }
3491 return fonts_;
3492 }
3493
3494
3495
3496
3497
3498 @JsxGetter
3499 public HTMLAllCollection getAll() {
3500 final HTMLAllCollection all = new HTMLAllCollection(getDomNodeOrDie());
3501 all.setAvoidObjectDetection(true);
3502 all.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> true);
3503 return all;
3504 }
3505
3506
3507
3508
3509
3510
3511 @JsxFunction
3512 public HtmlUnitScriptable getElementById(final String id) {
3513 final DomNode domNode = getDomNodeOrDie();
3514 for (final DomElement descendant : domNode.getDomElementDescendants()) {
3515 if (id.equals(descendant.getId())) {
3516 return descendant.getScriptableObject();
3517 }
3518 }
3519 return null;
3520 }
3521
3522
3523
3524
3525
3526
3527
3528 @JsxFunction
3529 public HtmlUnitScriptable createProcessingInstruction(final String target, final String data) {
3530 final ProcessingInstruction node = getPage().createProcessingInstruction(target, data);
3531 return getScriptableFor(node);
3532 }
3533
3534
3535
3536
3537
3538
3539 @JsxFunction
3540 public HtmlUnitScriptable createCDATASection(final String data) {
3541 final CDATASection node = getPage().createCDATASection(data);
3542 return getScriptableFor(node);
3543 }
3544
3545
3546
3547
3548
3549 @JsxFunction
3550 public void clear() {
3551
3552 }
3553
3554
3555
3556
3557 @JsxFunction
3558 @Override
3559 public boolean contains(final Object element) {
3560 return getDocumentElement().contains(element);
3561 }
3562
3563
3564
3565
3566
3567
3568 public String generateBlobUrl(final Blob blob) {
3569 final URL url = getPage().getUrl();
3570
3571 String origin = "null";
3572 if (!UrlUtils.URL_ABOUT_BLANK.equals(url)) {
3573 origin = url.getProtocol() + "://" + url.getAuthority();
3574 }
3575
3576 final String blobUrl = "blob:" + origin + "/" + UUID.randomUUID();
3577 blobUrl2Blobs_.put(blobUrl, blob);
3578 return blobUrl;
3579 }
3580
3581
3582
3583
3584
3585 public Blob resolveBlobUrl(final String url) {
3586 return blobUrl2Blobs_.get(url);
3587 }
3588
3589
3590
3591
3592
3593 public void revokeBlobUrl(final String url) {
3594 blobUrl2Blobs_.remove(url);
3595 }
3596 }