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_TEXTEVENT;
22 import static org.htmlunit.BrowserVersionFeatures.EVENT_TYPE_WHEELEVENT;
23 import static org.htmlunit.BrowserVersionFeatures.HTMLDOCUMENT_COOKIES_IGNORE_BLANK;
24 import static org.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_EVALUATE_RECREATES_RESULT;
25 import static org.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_SELECTION_RANGE_COUNT;
26 import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
27 import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
28 import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
29 import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
30
31 import java.io.IOException;
32 import java.io.Serializable;
33 import java.lang.reflect.InvocationTargetException;
34 import java.net.URL;
35 import java.time.ZoneId;
36 import java.time.format.DateTimeFormatter;
37 import java.util.Collections;
38 import java.util.Date;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.Set;
44 import java.util.UUID;
45 import java.util.function.Predicate;
46
47 import org.apache.commons.lang3.StringUtils;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.htmlunit.HttpHeader;
51 import org.htmlunit.Page;
52 import org.htmlunit.SgmlPage;
53 import org.htmlunit.WebClient;
54 import org.htmlunit.WebResponse;
55 import org.htmlunit.WebWindow;
56 import org.htmlunit.corejs.javascript.Callable;
57 import org.htmlunit.corejs.javascript.Context;
58 import org.htmlunit.corejs.javascript.Function;
59 import org.htmlunit.corejs.javascript.NativeFunction;
60 import org.htmlunit.corejs.javascript.Scriptable;
61 import org.htmlunit.corejs.javascript.ScriptableObject;
62 import org.htmlunit.cssparser.parser.CSSException;
63 import org.htmlunit.html.DomComment;
64 import org.htmlunit.html.DomDocumentFragment;
65 import org.htmlunit.html.DomElement;
66 import org.htmlunit.html.DomNode;
67 import org.htmlunit.html.DomText;
68 import org.htmlunit.html.FrameWindow;
69 import org.htmlunit.html.Html;
70 import org.htmlunit.html.HtmlAnchor;
71 import org.htmlunit.html.HtmlArea;
72 import org.htmlunit.html.HtmlAttributeChangeEvent;
73 import org.htmlunit.html.HtmlElement;
74 import org.htmlunit.html.HtmlEmbed;
75 import org.htmlunit.html.HtmlForm;
76 import org.htmlunit.html.HtmlFrameSet;
77 import org.htmlunit.html.HtmlImage;
78 import org.htmlunit.html.HtmlPage;
79 import org.htmlunit.html.HtmlRb;
80 import org.htmlunit.html.HtmlRp;
81 import org.htmlunit.html.HtmlRt;
82 import org.htmlunit.html.HtmlRtc;
83 import org.htmlunit.html.HtmlScript;
84 import org.htmlunit.html.HtmlSvg;
85 import org.htmlunit.html.HtmlUnknownElement;
86 import org.htmlunit.html.UnknownElementFactory;
87 import org.htmlunit.html.impl.SimpleRange;
88 import org.htmlunit.http.HttpUtils;
89 import org.htmlunit.httpclient.HtmlUnitBrowserCompatCookieSpec;
90 import org.htmlunit.javascript.HtmlUnitScriptable;
91 import org.htmlunit.javascript.JavaScriptEngine;
92 import org.htmlunit.javascript.configuration.JsxClass;
93 import org.htmlunit.javascript.configuration.JsxConstructor;
94 import org.htmlunit.javascript.configuration.JsxFunction;
95 import org.htmlunit.javascript.configuration.JsxGetter;
96 import org.htmlunit.javascript.configuration.JsxSetter;
97 import org.htmlunit.javascript.host.Element;
98 import org.htmlunit.javascript.host.FontFaceSet;
99 import org.htmlunit.javascript.host.Location;
100 import org.htmlunit.javascript.host.NativeFunctionPrefixResolver;
101 import org.htmlunit.javascript.host.Window;
102 import org.htmlunit.javascript.host.animations.AnimationEvent;
103 import org.htmlunit.javascript.host.css.StyleSheetList;
104 import org.htmlunit.javascript.host.dom.AbstractList.EffectOnCache;
105 import org.htmlunit.javascript.host.event.BeforeUnloadEvent;
106 import org.htmlunit.javascript.host.event.CloseEvent;
107 import org.htmlunit.javascript.host.event.CompositionEvent;
108 import org.htmlunit.javascript.host.event.CustomEvent;
109 import org.htmlunit.javascript.host.event.DragEvent;
110 import org.htmlunit.javascript.host.event.Event;
111 import org.htmlunit.javascript.host.event.FocusEvent;
112 import org.htmlunit.javascript.host.event.HashChangeEvent;
113 import org.htmlunit.javascript.host.event.KeyboardEvent;
114 import org.htmlunit.javascript.host.event.MessageEvent;
115 import org.htmlunit.javascript.host.event.MouseEvent;
116 import org.htmlunit.javascript.host.event.MutationEvent;
117 import org.htmlunit.javascript.host.event.PointerEvent;
118 import org.htmlunit.javascript.host.event.PopStateEvent;
119 import org.htmlunit.javascript.host.event.ProgressEvent;
120 import org.htmlunit.javascript.host.event.TextEvent;
121 import org.htmlunit.javascript.host.event.UIEvent;
122 import org.htmlunit.javascript.host.event.WheelEvent;
123 import org.htmlunit.javascript.host.file.Blob;
124 import org.htmlunit.javascript.host.html.HTMLAllCollection;
125 import org.htmlunit.javascript.host.html.HTMLBodyElement;
126 import org.htmlunit.javascript.host.html.HTMLCollection;
127 import org.htmlunit.javascript.host.html.HTMLElement;
128 import org.htmlunit.javascript.host.html.HTMLFrameSetElement;
129 import org.htmlunit.util.Cookie;
130 import org.htmlunit.util.UrlUtils;
131 import org.htmlunit.xpath.xml.utils.PrefixResolver;
132 import org.w3c.dom.CDATASection;
133 import org.w3c.dom.DOMException;
134 import org.w3c.dom.DocumentType;
135 import org.w3c.dom.ProcessingInstruction;
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 @JsxClass
162 public class Document extends Node {
163
164 private static final Log LOG = LogFactory.getLog(Document.class);
165
166
167
168
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 (org.htmlunit.util.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 final SgmlPage sgmlPage = getPage();
1120 final WebClient client = sgmlPage.getWebClient();
1121
1122 if (StringUtils.isBlank(newCookie)
1123 && client.getBrowserVersion().hasFeature(HTMLDOCUMENT_COOKIES_IGNORE_BLANK)) {
1124 return;
1125 }
1126 client.addCookie(newCookie, sgmlPage.getUrl(), this);
1127 }
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140 @JsxFunction
1141 public Event createEvent(final String eventType) throws DOMException {
1142 Class<? extends Event> clazz = SUPPORTED_DOM2_EVENT_TYPE_MAP.get(eventType);
1143 if (clazz == null) {
1144 clazz = SUPPORTED_DOM3_EVENT_TYPE_MAP.get(eventType);
1145 if (CloseEvent.class == clazz
1146 && getBrowserVersion().hasFeature(EVENT_ONCLOSE_DOCUMENT_CREATE_NOT_SUPPORTED)) {
1147 clazz = null;
1148 }
1149 else if (TextEvent.class == clazz
1150 && !getBrowserVersion().hasFeature(EVENT_TYPE_TEXTEVENT)) {
1151 clazz = CompositionEvent.class;
1152 }
1153 }
1154
1155 if (MutationEvent.class == clazz
1156 && !getBrowserVersion().hasFeature(EVENT_TYPE_MUTATIONEVENT)) {
1157 clazz = null;
1158 }
1159 else if (clazz == null
1160 && ("Events".equals(eventType)
1161 || "HashChangeEvent".equals(eventType)
1162 || "BeforeUnloadEvent".equals(eventType)
1163 || "PopStateEvent".equals(eventType)
1164 || "FocusEvent".equals(eventType)
1165 || "WheelEvent".equals(eventType)
1166 && getBrowserVersion().hasFeature(EVENT_TYPE_WHEELEVENT)
1167 || "AnimationEvent".equals(eventType))) {
1168 clazz = SUPPORTED_VENDOR_EVENT_TYPE_MAP.get(eventType);
1169
1170 if (PopStateEvent.class == clazz
1171 && getBrowserVersion().hasFeature(EVENT_ONPOPSTATE_DOCUMENT_CREATE_NOT_SUPPORTED)) {
1172 clazz = null;
1173 }
1174 if (AnimationEvent.class == clazz
1175 && getBrowserVersion().hasFeature(EVENT_ONANIMATION_DOCUMENT_CREATE_NOT_SUPPORTED)) {
1176 clazz = null;
1177 }
1178 }
1179
1180 if (clazz == null) {
1181 throw JavaScriptEngine.asJavaScriptException(
1182 this,
1183 "Event Type '" + eventType + "' is not supported.",
1184 org.htmlunit.javascript.host.dom.DOMException.NOT_SUPPORTED_ERR);
1185 }
1186
1187 try {
1188 final Event event = clazz.getDeclaredConstructor().newInstance();
1189 event.setParentScope(getWindow());
1190 event.setPrototype(getPrototype(clazz));
1191 event.eventCreated();
1192 return event;
1193 }
1194 catch (final InstantiationException | IllegalAccessException
1195 | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
1196 throw JavaScriptEngine.reportRuntimeError("Failed to instantiate event: class ='" + clazz.getName()
1197 + "' for event type of '" + eventType + "': " + e.getMessage());
1198 }
1199 }
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210 @JsxFunction
1211 public NodeIterator createNodeIterator(final Node root, final int whatToShow, final Scriptable filter) {
1212 final org.w3c.dom.traversal.NodeFilter filterWrapper = createFilterWrapper(filter, false);
1213 final NodeIterator iterator = new NodeIterator(root, whatToShow, filterWrapper);
1214 iterator.setParentScope(getParentScope());
1215 iterator.setPrototype(getPrototype(iterator.getClass()));
1216 return iterator;
1217 }
1218
1219 private static org.w3c.dom.traversal.NodeFilter createFilterWrapper(final Scriptable filter,
1220 final boolean filterFunctionOnly) {
1221 org.w3c.dom.traversal.NodeFilter filterWrapper = null;
1222 if (filter != null) {
1223 filterWrapper = n -> {
1224 final Object[] args = {((DomNode) n).getScriptableObject()};
1225 final Object response;
1226 if (filter instanceof Callable) {
1227 response = ((Callable) filter).call(Context.getCurrentContext(), filter, filter, args);
1228 }
1229 else {
1230 if (filterFunctionOnly) {
1231 throw JavaScriptEngine.reportRuntimeError("only a function is allowed as filter");
1232 }
1233 response = ScriptableObject.callMethod(filter, "acceptNode", args);
1234 }
1235 return (short) JavaScriptEngine.toNumber(response);
1236 };
1237 }
1238 return filterWrapper;
1239 }
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262 @JsxFunction
1263 public TreeWalker createTreeWalker(final Node root, final double whatToShow, final Scriptable filter,
1264 boolean expandEntityReferences) throws DOMException {
1265
1266
1267
1268 final int whatToShowI = (int) Double.valueOf(whatToShow).longValue();
1269
1270 expandEntityReferences = false;
1271
1272 final org.w3c.dom.traversal.NodeFilter filterWrapper = createFilterWrapper(filter, false);
1273 final TreeWalker t = new TreeWalker(root, whatToShowI, filterWrapper, expandEntityReferences);
1274 t.setParentScope(getWindow(this));
1275 t.setPrototype(staticGetPrototype(getWindow(this), TreeWalker.class));
1276 return t;
1277 }
1278
1279 @SuppressWarnings("unchecked")
1280 private static Scriptable staticGetPrototype(final Window window,
1281 final Class<? extends HtmlUnitScriptable> javaScriptClass) {
1282 final Scriptable prototype = window.getPrototype(javaScriptClass);
1283 if (prototype == null && javaScriptClass != HtmlUnitScriptable.class) {
1284 return staticGetPrototype(window, (Class<? extends HtmlUnitScriptable>) javaScriptClass.getSuperclass());
1285 }
1286 return prototype;
1287 }
1288
1289
1290
1291
1292
1293
1294 @JsxFunction
1295 public Range createRange() {
1296 final Range range = new Range(this);
1297 range.setParentScope(getWindow());
1298 range.setPrototype(getPrototype(Range.class));
1299 return range;
1300 }
1301
1302
1303
1304
1305
1306
1307
1308
1309 @JsxGetter
1310 public String getDomain() {
1311 if (domain_ == null && getPage().getWebResponse() != null) {
1312 URL url = getPage().getUrl();
1313 if (url == UrlUtils.URL_ABOUT_BLANK) {
1314 final WebWindow w = getWindow().getWebWindow();
1315 if (w instanceof FrameWindow) {
1316 url = ((FrameWindow) w).getEnclosingPage().getUrl();
1317 }
1318 else {
1319 return null;
1320 }
1321 }
1322 domain_ = url.getHost().toLowerCase(Locale.ROOT);
1323 }
1324
1325 return domain_;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356 @JsxSetter
1357 public void setDomain(String newDomain) {
1358 newDomain = newDomain.toLowerCase(Locale.ROOT);
1359
1360 final String currentDomain = getDomain();
1361 if (currentDomain.equalsIgnoreCase(newDomain)) {
1362 return;
1363 }
1364
1365 if (newDomain.indexOf('.') == -1) {
1366 throw JavaScriptEngine.reportRuntimeError("Illegal domain value, cannot set domain from: \""
1367 + currentDomain + "\" to: \"" + newDomain + "\" (new domain has to contain a dot).");
1368 }
1369
1370 if (currentDomain.indexOf('.') > -1
1371 && !currentDomain.toLowerCase(Locale.ROOT).endsWith("." + newDomain.toLowerCase(Locale.ROOT))) {
1372 throw JavaScriptEngine.reportRuntimeError("Illegal domain value, cannot set domain from: \""
1373 + currentDomain + "\" to: \"" + newDomain + "\"");
1374 }
1375
1376 domain_ = newDomain;
1377 }
1378
1379
1380
1381
1382
1383 @JsxSetter
1384 public void setOnclick(final Object handler) {
1385 setEventHandler(MouseEvent.TYPE_CLICK, handler);
1386 }
1387
1388
1389
1390
1391
1392 @JsxGetter
1393 public Function getOnclick() {
1394 return getEventHandler(MouseEvent.TYPE_CLICK);
1395 }
1396
1397
1398
1399
1400
1401 @JsxSetter
1402 public void setOndblclick(final Object handler) {
1403 setEventHandler(MouseEvent.TYPE_DBL_CLICK, handler);
1404 }
1405
1406
1407
1408
1409
1410 @JsxGetter
1411 public Function getOndblclick() {
1412 return getEventHandler(MouseEvent.TYPE_DBL_CLICK);
1413 }
1414
1415
1416
1417
1418
1419 @JsxSetter
1420 public void setOnblur(final Object handler) {
1421 setEventHandler(Event.TYPE_BLUR, handler);
1422 }
1423
1424
1425
1426
1427
1428 @JsxGetter
1429 public Function getOnblur() {
1430 return getEventHandler(Event.TYPE_BLUR);
1431 }
1432
1433
1434
1435
1436
1437 @JsxSetter
1438 public void setOnfocus(final Object handler) {
1439 setEventHandler(Event.TYPE_FOCUS, handler);
1440 }
1441
1442
1443
1444
1445
1446 @JsxGetter
1447 public Function getOnfocus() {
1448 return getEventHandler(Event.TYPE_FOCUS);
1449 }
1450
1451
1452
1453
1454
1455 @JsxSetter
1456 public void setOnkeydown(final Object handler) {
1457 setEventHandler(Event.TYPE_KEY_DOWN, handler);
1458 }
1459
1460
1461
1462
1463
1464 @JsxGetter
1465 public Function getOnkeydown() {
1466 return getEventHandler(Event.TYPE_KEY_DOWN);
1467 }
1468
1469
1470
1471
1472
1473 @JsxSetter
1474 public void setOnkeypress(final Object handler) {
1475 setEventHandler(Event.TYPE_KEY_PRESS, handler);
1476 }
1477
1478
1479
1480
1481
1482 @JsxGetter
1483 public Function getOnkeypress() {
1484 return getEventHandler(Event.TYPE_KEY_PRESS);
1485 }
1486
1487
1488
1489
1490
1491 @JsxSetter
1492 public void setOnkeyup(final Object handler) {
1493 setEventHandler(Event.TYPE_KEY_UP, handler);
1494 }
1495
1496
1497
1498
1499
1500 @JsxGetter
1501 public Function getOnkeyup() {
1502 return getEventHandler(Event.TYPE_KEY_UP);
1503 }
1504
1505
1506
1507
1508
1509 @JsxSetter
1510 public void setOnmousedown(final Object handler) {
1511 setEventHandler(MouseEvent.TYPE_MOUSE_DOWN, handler);
1512 }
1513
1514
1515
1516
1517
1518 @JsxGetter
1519 public Function getOnmousedown() {
1520 return getEventHandler(MouseEvent.TYPE_MOUSE_DOWN);
1521 }
1522
1523
1524
1525
1526
1527 @JsxSetter
1528 public void setOnmousemove(final Object handler) {
1529 setEventHandler(MouseEvent.TYPE_MOUSE_MOVE, handler);
1530 }
1531
1532
1533
1534
1535
1536 @JsxGetter
1537 public Function getOnmousemove() {
1538 return getEventHandler(MouseEvent.TYPE_MOUSE_MOVE);
1539 }
1540
1541
1542
1543
1544
1545 @JsxSetter
1546 public void setOnmouseout(final Object handler) {
1547 setEventHandler(MouseEvent.TYPE_MOUSE_OUT, handler);
1548 }
1549
1550
1551
1552
1553
1554 @JsxGetter
1555 public Function getOnmouseout() {
1556 return getEventHandler(MouseEvent.TYPE_MOUSE_OUT);
1557 }
1558
1559
1560
1561
1562
1563 @JsxSetter
1564 public void setOnmouseover(final Object handler) {
1565 setEventHandler(MouseEvent.TYPE_MOUSE_OVER, handler);
1566 }
1567
1568
1569
1570
1571
1572 @JsxGetter
1573 public Function getOnmouseover() {
1574 return getEventHandler(MouseEvent.TYPE_MOUSE_OVER);
1575 }
1576
1577
1578
1579
1580
1581 @JsxSetter
1582 public void setOnmouseup(final Object handler) {
1583 setEventHandler(MouseEvent.TYPE_MOUSE_UP, handler);
1584 }
1585
1586
1587
1588
1589
1590 @JsxGetter
1591 public Function getOnmouseup() {
1592 return getEventHandler(MouseEvent.TYPE_MOUSE_UP);
1593 }
1594
1595
1596
1597
1598
1599 @JsxSetter
1600 public void setOncontextmenu(final Object handler) {
1601 setEventHandler(MouseEvent.TYPE_CONTEXT_MENU, handler);
1602 }
1603
1604
1605
1606
1607
1608 @JsxGetter
1609 public Function getOncontextmenu() {
1610 return getEventHandler(MouseEvent.TYPE_CONTEXT_MENU);
1611 }
1612
1613
1614
1615
1616
1617 @JsxSetter
1618 public void setOnresize(final Object handler) {
1619 setEventHandler(Event.TYPE_RESIZE, handler);
1620 }
1621
1622
1623
1624
1625
1626 @JsxGetter
1627 public Function getOnresize() {
1628 return getEventHandler(Event.TYPE_RESIZE);
1629 }
1630
1631
1632
1633
1634
1635 @JsxSetter
1636 public void setOnerror(final Object handler) {
1637 setEventHandler(Event.TYPE_ERROR, handler);
1638 }
1639
1640
1641
1642
1643
1644 @JsxGetter
1645 public Function getOnerror() {
1646 return getEventHandler(Event.TYPE_ERROR);
1647 }
1648
1649
1650
1651
1652
1653 @JsxGetter
1654 public Function getOninput() {
1655 return getEventHandler(Event.TYPE_INPUT);
1656 }
1657
1658
1659
1660
1661
1662 @JsxSetter
1663 public void setOninput(final Object oninput) {
1664 setEventHandler(Event.TYPE_INPUT, oninput);
1665 }
1666
1667
1668
1669
1670
1671 @JsxGetter
1672 public boolean getHidden() {
1673 return false;
1674 }
1675
1676
1677
1678
1679 @Override
1680 @JsxGetter
1681 public int getChildElementCount() {
1682 int counter = 0;
1683 if (getPage().getDocumentElement() != null) {
1684 counter++;
1685 }
1686 return counter;
1687 }
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697 @JsxFunction
1698 public HtmlUnitScriptable elementFromPoint(final int x, final int y) {
1699 return null;
1700 }
1701
1702
1703
1704
1705
1706 @JsxGetter
1707 public HTMLCollection getForms() {
1708 final HTMLCollection forms = new HTMLCollection(getDomNodeOrDie(), false);
1709
1710 forms.setIsMatchingPredicate(
1711 (Predicate<DomNode> & Serializable)
1712 node -> node instanceof HtmlForm && node.getPrefix() == null);
1713 return forms;
1714 }
1715
1716
1717
1718
1719
1720 @JsxGetter
1721 public HTMLCollection getEmbeds() {
1722 final HTMLCollection embeds = new HTMLCollection(getDomNodeOrDie(), false);
1723
1724 embeds.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlEmbed);
1725 return embeds;
1726 }
1727
1728
1729
1730
1731
1732 @JsxGetter
1733 public HTMLCollection getImages() {
1734 final HTMLCollection images = new HTMLCollection(getDomNodeOrDie(), false);
1735
1736 images.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlImage);
1737 return images;
1738 }
1739
1740
1741
1742
1743
1744 @JsxGetter
1745 public HTMLCollection getScripts() {
1746 final HTMLCollection scripts = new HTMLCollection(getDomNodeOrDie(), false);
1747
1748 scripts.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlScript);
1749 return scripts;
1750 }
1751
1752
1753
1754
1755
1756
1757
1758
1759 @JsxGetter
1760 public StyleSheetList getStyleSheets() {
1761 if (styleSheetList_ == null) {
1762 styleSheetList_ = new StyleSheetList(this);
1763 }
1764 return styleSheetList_;
1765 }
1766
1767
1768
1769
1770
1771 @JsxGetter
1772 public HTMLCollection getPlugins() {
1773 return getEmbeds();
1774 }
1775
1776
1777
1778
1779
1780
1781 @JsxGetter
1782 public HTMLCollection getLinks() {
1783 final HTMLCollection links = new HTMLCollection(getDomNodeOrDie(), true);
1784
1785 links.setEffectOnCacheFunction(
1786 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1787 event -> {
1788 final HtmlElement node = event.getHtmlElement();
1789 if ((node instanceof HtmlAnchor || node instanceof HtmlArea) && "href".equals(event.getName())) {
1790 return EffectOnCache.RESET;
1791 }
1792 return EffectOnCache.NONE;
1793 });
1794
1795 links.setIsMatchingPredicate(
1796 (Predicate<DomNode> & Serializable)
1797 node ->
1798 (node instanceof HtmlAnchor || node instanceof HtmlArea)
1799 && ((HtmlElement) node).hasAttribute("href"));
1800
1801 return links;
1802 }
1803
1804
1805
1806
1807
1808
1809
1810 @JsxFunction
1811 public HTMLCollection getElementsByClassName(final String className) {
1812 return null;
1813 }
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824 @JsxFunction
1825 public NodeList getElementsByName(final String elementName) {
1826 return null;
1827 }
1828
1829
1830
1831
1832
1833
1834 @JsxFunction
1835 public boolean hasFocus() {
1836 return false;
1837 }
1838
1839
1840
1841
1842
1843 @JsxGetter
1844 public String getTitle() {
1845 return "";
1846 }
1847
1848
1849
1850
1851
1852 @JsxSetter
1853 public void setTitle(final String title) {
1854
1855 }
1856
1857
1858
1859
1860 @Override
1861 @JsxGetter
1862 public HTMLCollection getChildren() {
1863 return super.getChildren();
1864 }
1865
1866
1867
1868
1869
1870 @JsxGetter
1871 public String getContentType() {
1872 return getPage().getContentType();
1873 }
1874
1875
1876
1877
1878
1879 @JsxFunction
1880 public Selection getSelection() {
1881 return null;
1882 }
1883
1884
1885
1886
1887
1888 @JsxGetter
1889 public Object getHead() {
1890 return null;
1891 }
1892
1893
1894
1895
1896
1897 @JsxGetter
1898 public String getInputEncoding() {
1899 return getPage().getCharset().name();
1900 }
1901
1902
1903
1904
1905
1906
1907 @JsxGetter
1908 public String getLastModified() {
1909 if (lastModified_ == null) {
1910 final WebResponse webResponse = getPage().getWebResponse();
1911 final Date lastModified;
1912 if (webResponse != null) {
1913 String stringDate = webResponse.getResponseHeaderValue("Last-Modified");
1914 if (stringDate == null) {
1915 stringDate = webResponse.getResponseHeaderValue("Date");
1916 }
1917 lastModified = parseDateOrNow(stringDate);
1918 }
1919 else {
1920 lastModified = new Date();
1921 }
1922
1923 final ZoneId zoneid = Context.getCurrentContext().getTimeZone().toZoneId();
1924 lastModified_ = LAST_MODIFIED_DATE_FORMATTER.format(lastModified.toInstant().atZone(zoneid));
1925 }
1926 return lastModified_;
1927 }
1928
1929 private static Date parseDateOrNow(final String stringDate) {
1930 final Date date = HttpUtils.parseDate(stringDate);
1931 if (date == null) {
1932 return new Date();
1933 }
1934 return date;
1935 }
1936
1937
1938
1939
1940 @JsxFunction({FF, FF_ESR})
1941 public void releaseCapture() {
1942
1943 }
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955 @JsxGetter
1956 public String getReadyState() {
1957 return getDomNodeOrDie().getReadyState();
1958 }
1959
1960
1961
1962
1963
1964
1965
1966 @JsxFunction
1967 public void captureEvents(final String type) {
1968
1969 }
1970
1971
1972
1973
1974
1975
1976
1977 @JsxFunction
1978 public void releaseEvents(final String type) {
1979
1980 }
1981
1982
1983
1984
1985
1986 @JsxGetter
1987 public String getAlinkColor() {
1988 final HTMLElement body = getBody();
1989 if (body instanceof HTMLBodyElement) {
1990 return ((HTMLBodyElement) body).getALink();
1991 }
1992 return null;
1993 }
1994
1995
1996
1997
1998
1999 @JsxSetter
2000 public void setAlinkColor(final String color) {
2001 final HTMLElement body = getBody();
2002 if (body instanceof HTMLBodyElement) {
2003 ((HTMLBodyElement) body).setALink(color);
2004 }
2005 }
2006
2007
2008
2009
2010
2011
2012 @JsxGetter
2013 public String getBgColor() {
2014 final HTMLElement body = getBody();
2015 if (body instanceof HTMLBodyElement) {
2016 return ((HTMLBodyElement) body).getBgColor();
2017 }
2018 return null;
2019 }
2020
2021
2022
2023
2024
2025
2026 @JsxSetter
2027 public void setBgColor(final String color) {
2028 final HTMLElement body = getBody();
2029 if (body instanceof HTMLBodyElement) {
2030 ((HTMLBodyElement) body).setBgColor(color);
2031 }
2032 }
2033
2034
2035
2036
2037
2038 @JsxGetter
2039 public String getFgColor() {
2040 final HTMLElement body = getBody();
2041 if (body instanceof HTMLBodyElement) {
2042 return ((HTMLBodyElement) body).getText();
2043 }
2044 return null;
2045 }
2046
2047
2048
2049
2050
2051 @JsxSetter
2052 public void setFgColor(final String color) {
2053 final HTMLElement body = getBody();
2054 if (body instanceof HTMLBodyElement) {
2055 ((HTMLBodyElement) body).setText(color);
2056 }
2057 }
2058
2059
2060
2061
2062
2063 @JsxGetter
2064 public String getLinkColor() {
2065 final HTMLElement body = getBody();
2066 if (body instanceof HTMLBodyElement) {
2067 return ((HTMLBodyElement) body).getLink();
2068 }
2069 return null;
2070 }
2071
2072
2073
2074
2075
2076 @JsxSetter
2077 public void setLinkColor(final String color) {
2078 final HTMLElement body = getBody();
2079 if (body instanceof HTMLBodyElement) {
2080 ((HTMLBodyElement) body).setLink(color);
2081 }
2082 }
2083
2084
2085
2086
2087
2088 @JsxGetter
2089 public String getVlinkColor() {
2090 final HTMLElement body = getBody();
2091 if (body instanceof HTMLBodyElement) {
2092 return ((HTMLBodyElement) body).getVLink();
2093 }
2094 return null;
2095 }
2096
2097
2098
2099
2100
2101 @JsxSetter
2102 public void setVlinkColor(final String color) {
2103 final HTMLElement body = getBody();
2104 if (body instanceof HTMLBodyElement) {
2105 ((HTMLBodyElement) body).setVLink(color);
2106 }
2107 }
2108
2109
2110
2111
2112 @Override
2113 @JsxGetter
2114 public Element getLastElementChild() {
2115 return super.getLastElementChild();
2116 }
2117
2118
2119
2120
2121 @Override
2122 @JsxGetter
2123 public Element getFirstElementChild() {
2124 return super.getFirstElementChild();
2125 }
2126
2127
2128
2129
2130
2131 @JsxGetter({CHROME, EDGE})
2132 public String getXmlEncoding() {
2133 return getPage().getXmlEncoding();
2134 }
2135
2136
2137
2138
2139
2140 @JsxGetter({CHROME, EDGE})
2141 public boolean isXmlStandalone() {
2142 return getPage().getXmlStandalone();
2143 }
2144
2145
2146
2147
2148
2149 @JsxGetter({CHROME, EDGE})
2150 public String getXmlVersion() {
2151 return getPage().getXmlVersion();
2152 }
2153
2154
2155
2156
2157
2158 @JsxGetter
2159 public Function getOnabort() {
2160 return getEventHandler(Event.TYPE_ABORT);
2161 }
2162
2163
2164
2165
2166
2167 @JsxSetter
2168 public void setOnabort(final Object onabort) {
2169 setEventHandler(Event.TYPE_ABORT, onabort);
2170 }
2171
2172
2173
2174
2175
2176 @JsxGetter({CHROME, EDGE})
2177 public Function getOnauxclick() {
2178 return getEventHandler(Event.TYPE_AUXCLICK);
2179 }
2180
2181
2182
2183
2184
2185 @JsxSetter({CHROME, EDGE})
2186 public void setOnauxclick(final Object onauxclick) {
2187 setEventHandler(Event.TYPE_AUXCLICK, onauxclick);
2188 }
2189
2190
2191
2192
2193
2194 @JsxGetter({CHROME, EDGE})
2195 public Function getOnbeforecopy() {
2196 return getEventHandler(Event.TYPE_BEFORECOPY);
2197 }
2198
2199
2200
2201
2202
2203 @JsxSetter({CHROME, EDGE})
2204 public void setOnbeforecopy(final Object onbeforecopy) {
2205 setEventHandler(Event.TYPE_BEFORECOPY, onbeforecopy);
2206 }
2207
2208
2209
2210
2211
2212 @JsxGetter({CHROME, EDGE})
2213 public Function getOnbeforecut() {
2214 return getEventHandler(Event.TYPE_BEFORECUT);
2215 }
2216
2217
2218
2219
2220
2221 @JsxSetter({CHROME, EDGE})
2222 public void setOnbeforecut(final Object onbeforecut) {
2223 setEventHandler(Event.TYPE_BEFORECUT, onbeforecut);
2224 }
2225
2226
2227
2228
2229
2230 @JsxGetter({CHROME, EDGE})
2231 public Function getOnbeforepaste() {
2232 return getEventHandler(Event.TYPE_BEFOREPASTE);
2233 }
2234
2235
2236
2237
2238
2239 @JsxSetter({CHROME, EDGE})
2240 public void setOnbeforepaste(final Object onbeforepaste) {
2241 setEventHandler(Event.TYPE_BEFOREPASTE, onbeforepaste);
2242 }
2243
2244
2245
2246
2247
2248 @JsxGetter({CHROME, EDGE})
2249 public Function getOncancel() {
2250 return getEventHandler(Event.TYPE_CANCEL);
2251 }
2252
2253
2254
2255
2256
2257 @JsxSetter({CHROME, EDGE})
2258 public void setOncancel(final Object oncancel) {
2259 setEventHandler(Event.TYPE_CANCEL, oncancel);
2260 }
2261
2262
2263
2264
2265
2266 @JsxGetter
2267 public Function getOncanplay() {
2268 return getEventHandler(Event.TYPE_CANPLAY);
2269 }
2270
2271
2272
2273
2274
2275 @JsxSetter
2276 public void setOncanplay(final Object oncanplay) {
2277 setEventHandler(Event.TYPE_CANPLAY, oncanplay);
2278 }
2279
2280
2281
2282
2283
2284 @JsxGetter
2285 public Function getOncanplaythrough() {
2286 return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2287 }
2288
2289
2290
2291
2292
2293 @JsxSetter
2294 public void setOncanplaythrough(final Object oncanplaythrough) {
2295 setEventHandler(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2296 }
2297
2298
2299
2300
2301
2302 @JsxGetter
2303 public Function getOnchange() {
2304 return getEventHandler(Event.TYPE_CHANGE);
2305 }
2306
2307
2308
2309
2310
2311 @JsxSetter
2312 public void setOnchange(final Object onchange) {
2313 setEventHandler(Event.TYPE_CHANGE, onchange);
2314 }
2315
2316
2317
2318
2319
2320 @JsxGetter({CHROME, EDGE})
2321 public Function getOnclose() {
2322 return getEventHandler(Event.TYPE_CLOSE);
2323 }
2324
2325
2326
2327
2328
2329 @JsxSetter({CHROME, EDGE})
2330 public void setOnclose(final Object onclose) {
2331 setEventHandler(Event.TYPE_CLOSE, onclose);
2332 }
2333
2334
2335
2336
2337
2338 @JsxGetter
2339 public Function getOncopy() {
2340 return getEventHandler(Event.TYPE_COPY);
2341 }
2342
2343
2344
2345
2346
2347 @JsxSetter
2348 public void setOncopy(final Object oncopy) {
2349 setEventHandler(Event.TYPE_COPY, oncopy);
2350 }
2351
2352
2353
2354
2355
2356 @JsxGetter({CHROME, EDGE})
2357 public Function getOncuechange() {
2358 return getEventHandler(Event.TYPE_CUECHANGE);
2359 }
2360
2361
2362
2363
2364
2365 @JsxSetter({CHROME, EDGE})
2366 public void setOncuechange(final Object oncuechange) {
2367 setEventHandler(Event.TYPE_CUECHANGE, oncuechange);
2368 }
2369
2370
2371
2372
2373
2374 @JsxGetter
2375 public Function getOncut() {
2376 return getEventHandler(Event.TYPE_CUT);
2377 }
2378
2379
2380
2381
2382
2383 @JsxSetter
2384 public void setOncut(final Object oncut) {
2385 setEventHandler(Event.TYPE_CUT, oncut);
2386 }
2387
2388
2389
2390
2391
2392 @JsxGetter
2393 public Function getOndrag() {
2394 return getEventHandler(Event.TYPE_DRAG);
2395 }
2396
2397
2398
2399
2400
2401 @JsxSetter
2402 public void setOndrag(final Object ondrag) {
2403 setEventHandler(Event.TYPE_DRAG, ondrag);
2404 }
2405
2406
2407
2408
2409
2410 @JsxGetter
2411 public Function getOndragend() {
2412 return getEventHandler(Event.TYPE_DRAGEND);
2413 }
2414
2415
2416
2417
2418
2419 @JsxSetter
2420 public void setOndragend(final Object ondragend) {
2421 setEventHandler(Event.TYPE_DRAGEND, ondragend);
2422 }
2423
2424
2425
2426
2427
2428 @JsxGetter
2429 public Function getOndragenter() {
2430 return getEventHandler(Event.TYPE_DRAGENTER);
2431 }
2432
2433
2434
2435
2436
2437 @JsxSetter
2438 public void setOndragenter(final Object ondragenter) {
2439 setEventHandler(Event.TYPE_DRAGENTER, ondragenter);
2440 }
2441
2442
2443
2444
2445
2446 @JsxGetter
2447 public Function getOndragleave() {
2448 return getEventHandler(Event.TYPE_DRAGLEAVE);
2449 }
2450
2451
2452
2453
2454
2455 @JsxSetter
2456 public void setOndragleave(final Object ondragleave) {
2457 setEventHandler(Event.TYPE_DRAGLEAVE, ondragleave);
2458 }
2459
2460
2461
2462
2463
2464 @JsxGetter
2465 public Function getOndragover() {
2466 return getEventHandler(Event.TYPE_DRAGOVER);
2467 }
2468
2469
2470
2471
2472
2473 @JsxSetter
2474 public void setOndragover(final Object ondragover) {
2475 setEventHandler(Event.TYPE_DRAGOVER, ondragover);
2476 }
2477
2478
2479
2480
2481
2482 @JsxGetter
2483 public Function getOndragstart() {
2484 return getEventHandler(Event.TYPE_DRAGSTART);
2485 }
2486
2487
2488
2489
2490
2491 @JsxSetter
2492 public void setOndragstart(final Object ondragstart) {
2493 setEventHandler(Event.TYPE_DRAGSTART, ondragstart);
2494 }
2495
2496
2497
2498
2499
2500 @JsxGetter
2501 public Function getOndrop() {
2502 return getEventHandler(Event.TYPE_DROP);
2503 }
2504
2505
2506
2507
2508
2509 @JsxSetter
2510 public void setOndrop(final Object ondrop) {
2511 setEventHandler(Event.TYPE_DROP, ondrop);
2512 }
2513
2514
2515
2516
2517
2518 @JsxGetter
2519 public Function getOndurationchange() {
2520 return getEventHandler(Event.TYPE_DURATIONCHANGE);
2521 }
2522
2523
2524
2525
2526
2527 @JsxSetter
2528 public void setOndurationchange(final Object ondurationchange) {
2529 setEventHandler(Event.TYPE_DURATIONCHANGE, ondurationchange);
2530 }
2531
2532
2533
2534
2535
2536 @JsxGetter
2537 public Function getOnemptied() {
2538 return getEventHandler(Event.TYPE_EMPTIED);
2539 }
2540
2541
2542
2543
2544
2545 @JsxSetter
2546 public void setOnemptied(final Object onemptied) {
2547 setEventHandler(Event.TYPE_EMPTIED, onemptied);
2548 }
2549
2550
2551
2552
2553
2554 @JsxGetter
2555 public Function getOnended() {
2556 return getEventHandler(Event.TYPE_ENDED);
2557 }
2558
2559
2560
2561
2562
2563 @JsxSetter
2564 public void setOnended(final Object onended) {
2565 setEventHandler(Event.TYPE_ENDED, onended);
2566 }
2567
2568
2569
2570
2571
2572 @JsxGetter({CHROME, EDGE})
2573 public Function getOngotpointercapture() {
2574 return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
2575 }
2576
2577
2578
2579
2580
2581 @JsxSetter({CHROME, EDGE})
2582 public void setOngotpointercapture(final Object ongotpointercapture) {
2583 setEventHandler(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
2584 }
2585
2586
2587
2588
2589
2590 @JsxGetter
2591 public Function getOninvalid() {
2592 return getEventHandler(Event.TYPE_INVALID);
2593 }
2594
2595
2596
2597
2598
2599 @JsxSetter
2600 public void setOninvalid(final Object oninvalid) {
2601 setEventHandler(Event.TYPE_INVALID, oninvalid);
2602 }
2603
2604
2605
2606
2607
2608 @JsxGetter
2609 public Function getOnload() {
2610 return getEventHandler(Event.TYPE_LOAD);
2611 }
2612
2613
2614
2615
2616
2617 @JsxSetter
2618 public void setOnload(final Object onload) {
2619 setEventHandler(Event.TYPE_LOAD, onload);
2620 }
2621
2622
2623
2624
2625
2626 @JsxGetter
2627 public Function getOnloadeddata() {
2628 return getEventHandler(Event.TYPE_LOADEDDATA);
2629 }
2630
2631
2632
2633
2634
2635 @JsxSetter
2636 public void setOnloadeddata(final Object onloadeddata) {
2637 setEventHandler(Event.TYPE_LOADEDDATA, onloadeddata);
2638 }
2639
2640
2641
2642
2643
2644 @JsxGetter
2645 public Function getOnloadedmetadata() {
2646 return getEventHandler(Event.TYPE_LOADEDMETADATA);
2647 }
2648
2649
2650
2651
2652
2653 @JsxSetter
2654 public void setOnloadedmetadata(final Object onloadedmetadata) {
2655 setEventHandler(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
2656 }
2657
2658
2659
2660
2661
2662 @JsxGetter
2663 public Function getOnloadstart() {
2664 return getEventHandler(Event.TYPE_LOAD_START);
2665 }
2666
2667
2668
2669
2670
2671 @JsxSetter
2672 public void setOnloadstart(final Object onloadstart) {
2673 setEventHandler(Event.TYPE_LOAD_START, onloadstart);
2674 }
2675
2676
2677
2678
2679
2680 @JsxGetter({CHROME, EDGE})
2681 public Function getOnlostpointercapture() {
2682 return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2683 }
2684
2685
2686
2687
2688
2689 @JsxSetter({CHROME, EDGE})
2690 public void setOnlostpointercapture(final Object onlostpointercapture) {
2691 setEventHandler(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2692 }
2693
2694
2695
2696
2697
2698 @JsxGetter
2699 public Function getOnmouseenter() {
2700 return getEventHandler(Event.TYPE_MOUDEENTER);
2701 }
2702
2703
2704
2705
2706
2707 @JsxSetter
2708 public void setOnmouseenter(final Object onmouseenter) {
2709 setEventHandler(Event.TYPE_MOUDEENTER, onmouseenter);
2710 }
2711
2712
2713
2714
2715
2716 @JsxGetter
2717 public Function getOnmouseleave() {
2718 return getEventHandler(Event.TYPE_MOUSELEAVE);
2719 }
2720
2721
2722
2723
2724
2725 @JsxSetter
2726 public void setOnmouseleave(final Object onmouseleave) {
2727 setEventHandler(Event.TYPE_MOUSELEAVE, onmouseleave);
2728 }
2729
2730
2731
2732
2733
2734 @JsxGetter({CHROME, EDGE})
2735 public Function getOnmousewheel() {
2736 return getEventHandler(Event.TYPE_MOUSEWHEEL);
2737 }
2738
2739
2740
2741
2742
2743 @JsxSetter({CHROME, EDGE})
2744 public void setOnmousewheel(final Object onmousewheel) {
2745 setEventHandler(Event.TYPE_MOUSEWHEEL, onmousewheel);
2746 }
2747
2748
2749
2750
2751
2752 @JsxGetter
2753 public Function getOnpaste() {
2754 return getEventHandler(Event.TYPE_PASTE);
2755 }
2756
2757
2758
2759
2760
2761 @JsxSetter
2762 public void setOnpaste(final Object onpaste) {
2763 setEventHandler(Event.TYPE_PASTE, onpaste);
2764 }
2765
2766
2767
2768
2769
2770 @JsxGetter
2771 public Function getOnpause() {
2772 return getEventHandler(Event.TYPE_PAUSE);
2773 }
2774
2775
2776
2777
2778
2779 @JsxSetter
2780 public void setOnpause(final Object onpause) {
2781 setEventHandler(Event.TYPE_PAUSE, onpause);
2782 }
2783
2784
2785
2786
2787
2788 @JsxGetter
2789 public Function getOnplay() {
2790 return getEventHandler(Event.TYPE_PLAY);
2791 }
2792
2793
2794
2795
2796
2797 @JsxSetter
2798 public void setOnplay(final Object onplay) {
2799 setEventHandler(Event.TYPE_PLAY, onplay);
2800 }
2801
2802
2803
2804
2805
2806 @JsxGetter
2807 public Function getOnplaying() {
2808 return getEventHandler(Event.TYPE_PLAYING);
2809 }
2810
2811
2812
2813
2814
2815 @JsxSetter
2816 public void setOnplaying(final Object onplaying) {
2817 setEventHandler(Event.TYPE_PLAYING, onplaying);
2818 }
2819
2820
2821
2822
2823
2824 @JsxGetter({CHROME, EDGE})
2825 public Function getOnpointercancel() {
2826 return getEventHandler(Event.TYPE_POINTERCANCEL);
2827 }
2828
2829
2830
2831
2832
2833 @JsxSetter({CHROME, EDGE})
2834 public void setOnpointercancel(final Object onpointercancel) {
2835 setEventHandler(Event.TYPE_POINTERCANCEL, onpointercancel);
2836 }
2837
2838
2839
2840
2841
2842 @JsxGetter({CHROME, EDGE})
2843 public Function getOnpointerdown() {
2844 return getEventHandler(Event.TYPE_POINTERDOWN);
2845 }
2846
2847
2848
2849
2850
2851 @JsxSetter({CHROME, EDGE})
2852 public void setOnpointerdown(final Object onpointerdown) {
2853 setEventHandler(Event.TYPE_POINTERDOWN, onpointerdown);
2854 }
2855
2856
2857
2858
2859
2860 @JsxGetter({CHROME, EDGE})
2861 public Function getOnpointerenter() {
2862 return getEventHandler(Event.TYPE_POINTERENTER);
2863 }
2864
2865
2866
2867
2868
2869 @JsxSetter({CHROME, EDGE})
2870 public void setOnpointerenter(final Object onpointerenter) {
2871 setEventHandler(Event.TYPE_POINTERENTER, onpointerenter);
2872 }
2873
2874
2875
2876
2877
2878 @JsxGetter({CHROME, EDGE})
2879 public Function getOnpointerleave() {
2880 return getEventHandler(Event.TYPE_POINTERLEAVE);
2881 }
2882
2883
2884
2885
2886
2887 @JsxSetter({CHROME, EDGE})
2888 public void setOnpointerleave(final Object onpointerleave) {
2889 setEventHandler(Event.TYPE_POINTERLEAVE, onpointerleave);
2890 }
2891
2892
2893
2894
2895
2896 @JsxGetter({CHROME, EDGE})
2897 public Function getOnpointerlockchange() {
2898 return getEventHandler(Event.TYPE_POINTERLOCKCHANGE);
2899 }
2900
2901
2902
2903
2904
2905 @JsxSetter({CHROME, EDGE})
2906 public void setOnpointerlockchange(final Object onpointerlockchange) {
2907 setEventHandler(Event.TYPE_POINTERLOCKCHANGE, onpointerlockchange);
2908 }
2909
2910
2911
2912
2913
2914 @JsxGetter({CHROME, EDGE})
2915 public Function getOnpointerlockerror() {
2916 return getEventHandler(Event.TYPE_POINTERLOCKERROR);
2917 }
2918
2919
2920
2921
2922
2923 @JsxSetter({CHROME, EDGE})
2924 public void setOnpointerlockerror(final Object onpointerlockerror) {
2925 setEventHandler(Event.TYPE_POINTERLOCKERROR, onpointerlockerror);
2926 }
2927
2928
2929
2930
2931
2932 @JsxGetter({CHROME, EDGE})
2933 public Function getOnpointermove() {
2934 return getEventHandler(Event.TYPE_POINTERMOVE);
2935 }
2936
2937
2938
2939
2940
2941 @JsxSetter({CHROME, EDGE})
2942 public void setOnpointermove(final Object onpointermove) {
2943 setEventHandler(Event.TYPE_POINTERMOVE, onpointermove);
2944 }
2945
2946
2947
2948
2949
2950 @JsxGetter({CHROME, EDGE})
2951 public Function getOnpointerout() {
2952 return getEventHandler(Event.TYPE_POINTEROUT);
2953 }
2954
2955
2956
2957
2958
2959 @JsxSetter({CHROME, EDGE})
2960 public void setOnpointerout(final Object onpointerout) {
2961 setEventHandler(Event.TYPE_POINTEROUT, onpointerout);
2962 }
2963
2964
2965
2966
2967
2968 @JsxGetter({CHROME, EDGE})
2969 public Function getOnpointerover() {
2970 return getEventHandler(Event.TYPE_POINTEROVER);
2971 }
2972
2973
2974
2975
2976
2977 @JsxSetter({CHROME, EDGE})
2978 public void setOnpointerover(final Object onpointerover) {
2979 setEventHandler(Event.TYPE_POINTEROVER, onpointerover);
2980 }
2981
2982
2983
2984
2985
2986 @JsxGetter({CHROME, EDGE})
2987 public Function getOnpointerup() {
2988 return getEventHandler(Event.TYPE_POINTERUP);
2989 }
2990
2991
2992
2993
2994
2995 @JsxSetter({CHROME, EDGE})
2996 public void setOnpointerup(final Object onpointerup) {
2997 setEventHandler(Event.TYPE_POINTERUP, onpointerup);
2998 }
2999
3000
3001
3002
3003
3004 @JsxGetter
3005 public Function getOnprogress() {
3006 return getEventHandler(Event.TYPE_PROGRESS);
3007 }
3008
3009
3010
3011
3012
3013 @JsxSetter
3014 public void setOnprogress(final Object onprogress) {
3015 setEventHandler(Event.TYPE_PROGRESS, onprogress);
3016 }
3017
3018
3019
3020
3021
3022 @JsxGetter
3023 public Function getOnratechange() {
3024 return getEventHandler(Event.TYPE_RATECHANGE);
3025 }
3026
3027
3028
3029
3030
3031 @JsxSetter
3032 public void setOnratechange(final Object onratechange) {
3033 setEventHandler(Event.TYPE_RATECHANGE, onratechange);
3034 }
3035
3036
3037
3038
3039
3040 @JsxGetter
3041 public Function getOnreadystatechange() {
3042 return getEventHandler(Event.TYPE_READY_STATE_CHANGE);
3043 }
3044
3045
3046
3047
3048
3049 @JsxSetter
3050 public void setOnreadystatechange(final Object onreadystatechange) {
3051 setEventHandler(Event.TYPE_READY_STATE_CHANGE, onreadystatechange);
3052 }
3053
3054
3055
3056
3057
3058 @JsxGetter
3059 public Function getOnreset() {
3060 return getEventHandler(Event.TYPE_RESET);
3061 }
3062
3063
3064
3065
3066
3067 @JsxSetter
3068 public void setOnreset(final Object onreset) {
3069 setEventHandler(Event.TYPE_RESET, onreset);
3070 }
3071
3072
3073
3074
3075
3076 @JsxGetter
3077 public Function getOnscroll() {
3078 return getEventHandler(Event.TYPE_SCROLL);
3079 }
3080
3081
3082
3083
3084
3085 @JsxSetter
3086 public void setOnscroll(final Object onscroll) {
3087 setEventHandler(Event.TYPE_SCROLL, onscroll);
3088 }
3089
3090
3091
3092
3093
3094 @JsxGetter({CHROME, EDGE})
3095 public Function getOnsearch() {
3096 return getEventHandler(Event.TYPE_SEARCH);
3097 }
3098
3099
3100
3101
3102
3103 @JsxSetter({CHROME, EDGE})
3104 public void setOnsearch(final Object onsearch) {
3105 setEventHandler(Event.TYPE_SEARCH, onsearch);
3106 }
3107
3108
3109
3110
3111
3112 @JsxGetter
3113 public Function getOnseeked() {
3114 return getEventHandler(Event.TYPE_SEEKED);
3115 }
3116
3117
3118
3119
3120
3121 @JsxSetter
3122 public void setOnseeked(final Object onseeked) {
3123 setEventHandler(Event.TYPE_SEEKED, onseeked);
3124 }
3125
3126
3127
3128
3129
3130 @JsxGetter
3131 public Function getOnseeking() {
3132 return getEventHandler(Event.TYPE_SEEKING);
3133 }
3134
3135
3136
3137
3138
3139 @JsxSetter
3140 public void setOnseeking(final Object onseeking) {
3141 setEventHandler(Event.TYPE_SEEKING, onseeking);
3142 }
3143
3144
3145
3146
3147
3148 @JsxGetter
3149 public Function getOnselect() {
3150 return getEventHandler(Event.TYPE_SELECT);
3151 }
3152
3153
3154
3155
3156
3157 @JsxSetter
3158 public void setOnselect(final Object onselect) {
3159 setEventHandler(Event.TYPE_SELECT, onselect);
3160 }
3161
3162
3163
3164
3165
3166 @JsxGetter({CHROME, EDGE})
3167 public Function getOnselectionchange() {
3168 return getEventHandler(Event.TYPE_SELECTIONCHANGE);
3169 }
3170
3171
3172
3173
3174
3175 @JsxSetter({CHROME, EDGE})
3176 public void setOnselectionchange(final Object onselectionchange) {
3177 setEventHandler(Event.TYPE_SELECTIONCHANGE, onselectionchange);
3178 }
3179
3180
3181
3182
3183
3184 @JsxGetter
3185 public Function getOnselectstart() {
3186 return getEventHandler(Event.TYPE_SELECTSTART);
3187 }
3188
3189
3190
3191
3192
3193 @JsxSetter
3194 public void setOnselectstart(final Object onselectstart) {
3195 setEventHandler(Event.TYPE_SELECTSTART, onselectstart);
3196 }
3197
3198
3199
3200
3201
3202 @JsxGetter
3203 public Function getOnstalled() {
3204 return getEventHandler(Event.TYPE_STALLED);
3205 }
3206
3207
3208
3209
3210
3211 @JsxSetter
3212 public void setOnstalled(final Object onstalled) {
3213 setEventHandler(Event.TYPE_STALLED, onstalled);
3214 }
3215
3216
3217
3218
3219
3220 @JsxGetter
3221 public Function getOnsubmit() {
3222 return getEventHandler(Event.TYPE_SUBMIT);
3223 }
3224
3225
3226
3227
3228
3229 @JsxSetter
3230 public void setOnsubmit(final Object onsubmit) {
3231 setEventHandler(Event.TYPE_SUBMIT, onsubmit);
3232 }
3233
3234
3235
3236
3237
3238 @JsxGetter
3239 public Function getOnsuspend() {
3240 return getEventHandler(Event.TYPE_SUSPEND);
3241 }
3242
3243
3244
3245
3246
3247 @JsxSetter
3248 public void setOnsuspend(final Object onsuspend) {
3249 setEventHandler(Event.TYPE_SUSPEND, onsuspend);
3250 }
3251
3252
3253
3254
3255
3256 @JsxGetter
3257 public Function getOntimeupdate() {
3258 return getEventHandler(Event.TYPE_TIMEUPDATE);
3259 }
3260
3261
3262
3263
3264
3265 @JsxSetter
3266 public void setOntimeupdate(final Object ontimeupdate) {
3267 setEventHandler(Event.TYPE_TIMEUPDATE, ontimeupdate);
3268 }
3269
3270
3271
3272
3273
3274 @JsxGetter({CHROME, EDGE})
3275 public Function getOntoggle() {
3276 return getEventHandler(Event.TYPE_TOGGLE);
3277 }
3278
3279
3280
3281
3282
3283 @JsxSetter({CHROME, EDGE})
3284 public void setOntoggle(final Object ontoggle) {
3285 setEventHandler(Event.TYPE_TOGGLE, ontoggle);
3286 }
3287
3288
3289
3290
3291
3292 @JsxGetter
3293 public Function getOnvolumechange() {
3294 return getEventHandler(Event.TYPE_VOLUMECHANGE);
3295 }
3296
3297
3298
3299
3300
3301 @JsxSetter
3302 public void setOnvolumechange(final Object onvolumechange) {
3303 setEventHandler(Event.TYPE_VOLUMECHANGE, onvolumechange);
3304 }
3305
3306
3307
3308
3309
3310 @JsxGetter
3311 public Function getOnwaiting() {
3312 return getEventHandler(Event.TYPE_WAITING);
3313 }
3314
3315
3316
3317
3318
3319 @JsxSetter
3320 public void setOnwaiting(final Object onwaiting) {
3321 setEventHandler(Event.TYPE_WAITING, onwaiting);
3322 }
3323
3324
3325
3326
3327
3328 @JsxGetter({CHROME, EDGE})
3329 public Function getOnwebkitfullscreenchange() {
3330 return getEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE);
3331 }
3332
3333
3334
3335
3336
3337 @JsxSetter({CHROME, EDGE})
3338 public void setOnwebkitfullscreenchange(final Object onwebkitfullscreenchange) {
3339 setEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE, onwebkitfullscreenchange);
3340 }
3341
3342
3343
3344
3345
3346 @JsxGetter({CHROME, EDGE})
3347 public Function getOnwebkitfullscreenerror() {
3348 return getEventHandler(Event.TYPE_WEBKITFULLSCREENERROR);
3349 }
3350
3351
3352
3353
3354
3355 @JsxSetter
3356 public void setOnwebkitfullscreenerror(final Object onwebkitfullscreenerror) {
3357 setEventHandler(Event.TYPE_WEBKITFULLSCREENERROR, onwebkitfullscreenerror);
3358 }
3359
3360
3361
3362
3363
3364 @JsxGetter
3365 public Function getOnwheel() {
3366 return getEventHandler(Event.TYPE_WHEEL);
3367 }
3368
3369
3370
3371
3372
3373 @JsxSetter
3374 public void setOnwheel(final Object onwheel) {
3375 setEventHandler(Event.TYPE_WHEEL, onwheel);
3376 }
3377
3378
3379
3380
3381
3382 @JsxGetter({FF, FF_ESR})
3383 public Function getOnafterscriptexecute() {
3384 return getEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE);
3385 }
3386
3387
3388
3389
3390
3391 @JsxSetter({FF, FF_ESR})
3392 public void setOnafterscriptexecute(final Object onafterscriptexecute) {
3393 setEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE, onafterscriptexecute);
3394 }
3395
3396
3397
3398
3399
3400 @JsxGetter({FF, FF_ESR})
3401 public Function getOnbeforescriptexecute() {
3402 return getEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE);
3403 }
3404
3405
3406
3407
3408
3409 @JsxSetter({FF, FF_ESR})
3410 public void setOnbeforescriptexecute(final Object onbeforescriptexecute) {
3411 setEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE, onbeforescriptexecute);
3412 }
3413
3414
3415
3416
3417
3418 @JsxGetter({FF, FF_ESR})
3419 public Function getOnmozfullscreenchange() {
3420 return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
3421 }
3422
3423
3424
3425
3426
3427 @JsxSetter({FF, FF_ESR})
3428 public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
3429 setEventHandler(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
3430 }
3431
3432
3433
3434
3435
3436 @JsxGetter({FF, FF_ESR})
3437 public Function getOnmozfullscreenerror() {
3438 return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
3439 }
3440
3441
3442
3443
3444
3445 @JsxSetter({FF, FF_ESR})
3446 public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
3447 setEventHandler(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
3448 }
3449
3450
3451
3452
3453 @JsxGetter
3454 public ScriptableObject getCurrentScript() {
3455 return currentScript_;
3456 }
3457
3458
3459
3460
3461 public void setCurrentScript(final ScriptableObject script) {
3462 currentScript_ = script;
3463 }
3464
3465
3466
3467
3468 @JsxGetter
3469 public ScriptableObject getFonts() {
3470 if (fonts_ == null) {
3471 final FontFaceSet fonts = new FontFaceSet();
3472 fonts.setParentScope(getWindow());
3473 fonts.setPrototype(getPrototype(fonts.getClass()));
3474 fonts_ = fonts;
3475 }
3476 return fonts_;
3477 }
3478
3479
3480
3481
3482
3483 @JsxGetter
3484 public HTMLAllCollection getAll() {
3485 final HTMLAllCollection all = new HTMLAllCollection(getDomNodeOrDie());
3486 all.setAvoidObjectDetection(true);
3487 all.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> true);
3488 return all;
3489 }
3490
3491
3492
3493
3494
3495
3496 @JsxFunction
3497 public HtmlUnitScriptable getElementById(final String id) {
3498 final DomNode domNode = getDomNodeOrDie();
3499 for (final DomElement descendant : domNode.getDomElementDescendants()) {
3500 if (id.equals(descendant.getId())) {
3501 return descendant.getScriptableObject();
3502 }
3503 }
3504 return null;
3505 }
3506
3507
3508
3509
3510
3511
3512
3513 @JsxFunction
3514 public HtmlUnitScriptable createProcessingInstruction(final String target, final String data) {
3515 final ProcessingInstruction node = getPage().createProcessingInstruction(target, data);
3516 return getScriptableFor(node);
3517 }
3518
3519
3520
3521
3522
3523
3524 @JsxFunction
3525 public HtmlUnitScriptable createCDATASection(final String data) {
3526 final CDATASection node = getPage().createCDATASection(data);
3527 return getScriptableFor(node);
3528 }
3529
3530
3531
3532
3533
3534 @JsxFunction
3535 public void clear() {
3536
3537 }
3538
3539
3540
3541
3542 @JsxFunction
3543 @Override
3544 public boolean contains(final Object element) {
3545 return getDocumentElement().contains(element);
3546 }
3547
3548
3549
3550
3551
3552
3553 public String generateBlobUrl(final Blob blob) {
3554 final URL url = getPage().getUrl();
3555
3556 String origin = "null";
3557 if (!UrlUtils.URL_ABOUT_BLANK.equals(url)) {
3558 origin = url.getProtocol() + "://" + url.getAuthority();
3559 }
3560
3561 final String blobUrl = "blob:" + origin + "/" + UUID.randomUUID();
3562 blobUrl2Blobs_.put(blobUrl, blob);
3563 return blobUrl;
3564 }
3565
3566
3567
3568
3569
3570 public Blob resolveBlobUrl(final String url) {
3571 return blobUrl2Blobs_.get(url);
3572 }
3573
3574
3575
3576
3577
3578 public void revokeBlobUrl(final String url) {
3579 blobUrl2Blobs_.remove(url);
3580 }
3581 }