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