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 @Override
1710 public Object call(final Context cx, final Scriptable scope,
1711 final Scriptable thisObj, final Object[] args) {
1712 throw JavaScriptEngine.typeError("document.forms is not a function");
1713 }
1714 };
1715
1716 forms.setIsMatchingPredicate(
1717 (Predicate<DomNode> & Serializable)
1718 node -> node instanceof HtmlForm && node.getPrefix() == null);
1719 return forms;
1720 }
1721
1722
1723
1724
1725
1726 @JsxGetter
1727 public HTMLCollection getEmbeds() {
1728 final HTMLCollection embeds = new HTMLCollection(getDomNodeOrDie(), false) {
1729 @Override
1730 public Object call(final Context cx, final Scriptable scope,
1731 final Scriptable thisObj, final Object[] args) {
1732 throw JavaScriptEngine.typeError("document.embeds is not a function");
1733 }
1734 };
1735
1736 embeds.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlEmbed);
1737 return embeds;
1738 }
1739
1740
1741
1742
1743
1744 @JsxGetter
1745 public HTMLCollection getImages() {
1746 final HTMLCollection images = new HTMLCollection(getDomNodeOrDie(), false) {
1747 @Override
1748 public Object call(final Context cx, final Scriptable scope,
1749 final Scriptable thisObj, final Object[] args) {
1750 throw JavaScriptEngine.typeError("document.images is not a function");
1751 }
1752 };
1753
1754 images.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlImage);
1755 return images;
1756 }
1757
1758
1759
1760
1761
1762 @JsxGetter
1763 public HTMLCollection getScripts() {
1764 final HTMLCollection scripts = new HTMLCollection(getDomNodeOrDie(), false) {
1765 @Override
1766 public Object call(final Context cx, final Scriptable scope,
1767 final Scriptable thisObj, final Object[] args) {
1768 throw JavaScriptEngine.typeError("document.scripts is not a function");
1769 }
1770 };
1771
1772 scripts.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> node instanceof HtmlScript);
1773 return scripts;
1774 }
1775
1776
1777
1778
1779
1780
1781
1782
1783 @JsxGetter
1784 public StyleSheetList getStyleSheets() {
1785 if (styleSheetList_ == null) {
1786 styleSheetList_ = new StyleSheetList(this);
1787 }
1788 return styleSheetList_;
1789 }
1790
1791
1792
1793
1794
1795 @JsxGetter
1796 public HTMLCollection getPlugins() {
1797 return getEmbeds();
1798 }
1799
1800
1801
1802
1803
1804
1805 @JsxGetter
1806 public HTMLCollection getLinks() {
1807 final HTMLCollection links = new HTMLCollection(getDomNodeOrDie(), true);
1808
1809 links.setEffectOnCacheFunction(
1810 (java.util.function.Function<HtmlAttributeChangeEvent, EffectOnCache> & Serializable)
1811 event -> {
1812 final HtmlElement node = event.getHtmlElement();
1813 if ((node instanceof HtmlAnchor || node instanceof HtmlArea) && "href".equals(event.getName())) {
1814 return EffectOnCache.RESET;
1815 }
1816 return EffectOnCache.NONE;
1817 });
1818
1819 links.setIsMatchingPredicate(
1820 (Predicate<DomNode> & Serializable)
1821 node ->
1822 (node instanceof HtmlAnchor || node instanceof HtmlArea)
1823 && ((HtmlElement) node).hasAttribute("href"));
1824
1825 return links;
1826 }
1827
1828
1829
1830
1831
1832
1833
1834 @JsxFunction
1835 public HTMLCollection getElementsByClassName(final String className) {
1836 return null;
1837 }
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848 @JsxFunction
1849 public NodeList getElementsByName(final String elementName) {
1850 return null;
1851 }
1852
1853
1854
1855
1856
1857
1858 @JsxFunction
1859 public boolean hasFocus() {
1860 return false;
1861 }
1862
1863
1864
1865
1866
1867 @JsxGetter
1868 public String getTitle() {
1869 return "";
1870 }
1871
1872
1873
1874
1875
1876 @JsxSetter
1877 public void setTitle(final String title) {
1878
1879 }
1880
1881
1882
1883
1884 @Override
1885 @JsxGetter
1886 public HTMLCollection getChildren() {
1887 return super.getChildren();
1888 }
1889
1890
1891
1892
1893
1894 @JsxGetter
1895 public String getContentType() {
1896 return getPage().getContentType();
1897 }
1898
1899
1900
1901
1902
1903 @JsxFunction
1904 public Selection getSelection() {
1905 return null;
1906 }
1907
1908
1909
1910
1911
1912 @JsxGetter
1913 public Object getHead() {
1914 return null;
1915 }
1916
1917
1918
1919
1920
1921 @JsxGetter
1922 public String getInputEncoding() {
1923 return getPage().getCharset().name();
1924 }
1925
1926
1927
1928
1929
1930
1931 @JsxGetter
1932 public String getLastModified() {
1933 if (lastModified_ == null) {
1934 final WebResponse webResponse = getPage().getWebResponse();
1935 final Date lastModified;
1936 if (webResponse != null) {
1937 String stringDate = webResponse.getResponseHeaderValue("Last-Modified");
1938 if (stringDate == null) {
1939 stringDate = webResponse.getResponseHeaderValue("Date");
1940 }
1941 lastModified = parseDateOrNow(stringDate);
1942 }
1943 else {
1944 lastModified = new Date();
1945 }
1946
1947 final ZoneId zoneid = Context.getCurrentContext().getTimeZone().toZoneId();
1948 lastModified_ = LAST_MODIFIED_DATE_FORMATTER.format(lastModified.toInstant().atZone(zoneid));
1949 }
1950 return lastModified_;
1951 }
1952
1953 private static Date parseDateOrNow(final String stringDate) {
1954 final Date date = HttpUtils.parseDate(stringDate);
1955 if (date == null) {
1956 return new Date();
1957 }
1958 return date;
1959 }
1960
1961
1962
1963
1964 @JsxFunction({FF, FF_ESR})
1965 public void releaseCapture() {
1966
1967 }
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979 @JsxGetter
1980 public String getReadyState() {
1981 return getDomNodeOrDie().getReadyState();
1982 }
1983
1984
1985
1986
1987
1988
1989
1990 @JsxFunction
1991 public void captureEvents(final String type) {
1992
1993 }
1994
1995
1996
1997
1998
1999
2000
2001 @JsxFunction
2002 public void releaseEvents(final String type) {
2003
2004 }
2005
2006
2007
2008
2009
2010 @JsxGetter
2011 public String getAlinkColor() {
2012 final HTMLElement body = getBody();
2013 if (body instanceof HTMLBodyElement) {
2014 return ((HTMLBodyElement) body).getALink();
2015 }
2016 return null;
2017 }
2018
2019
2020
2021
2022
2023 @JsxSetter
2024 public void setAlinkColor(final String color) {
2025 final HTMLElement body = getBody();
2026 if (body instanceof HTMLBodyElement) {
2027 ((HTMLBodyElement) body).setALink(color);
2028 }
2029 }
2030
2031
2032
2033
2034
2035
2036 @JsxGetter
2037 public String getBgColor() {
2038 final HTMLElement body = getBody();
2039 if (body instanceof HTMLBodyElement) {
2040 return ((HTMLBodyElement) body).getBgColor();
2041 }
2042 return null;
2043 }
2044
2045
2046
2047
2048
2049
2050 @JsxSetter
2051 public void setBgColor(final String color) {
2052 final HTMLElement body = getBody();
2053 if (body instanceof HTMLBodyElement) {
2054 ((HTMLBodyElement) body).setBgColor(color);
2055 }
2056 }
2057
2058
2059
2060
2061
2062 @JsxGetter
2063 public String getFgColor() {
2064 final HTMLElement body = getBody();
2065 if (body instanceof HTMLBodyElement) {
2066 return ((HTMLBodyElement) body).getText();
2067 }
2068 return null;
2069 }
2070
2071
2072
2073
2074
2075 @JsxSetter
2076 public void setFgColor(final String color) {
2077 final HTMLElement body = getBody();
2078 if (body instanceof HTMLBodyElement) {
2079 ((HTMLBodyElement) body).setText(color);
2080 }
2081 }
2082
2083
2084
2085
2086
2087 @JsxGetter
2088 public String getLinkColor() {
2089 final HTMLElement body = getBody();
2090 if (body instanceof HTMLBodyElement) {
2091 return ((HTMLBodyElement) body).getLink();
2092 }
2093 return null;
2094 }
2095
2096
2097
2098
2099
2100 @JsxSetter
2101 public void setLinkColor(final String color) {
2102 final HTMLElement body = getBody();
2103 if (body instanceof HTMLBodyElement) {
2104 ((HTMLBodyElement) body).setLink(color);
2105 }
2106 }
2107
2108
2109
2110
2111
2112 @JsxGetter
2113 public String getVlinkColor() {
2114 final HTMLElement body = getBody();
2115 if (body instanceof HTMLBodyElement) {
2116 return ((HTMLBodyElement) body).getVLink();
2117 }
2118 return null;
2119 }
2120
2121
2122
2123
2124
2125 @JsxSetter
2126 public void setVlinkColor(final String color) {
2127 final HTMLElement body = getBody();
2128 if (body instanceof HTMLBodyElement) {
2129 ((HTMLBodyElement) body).setVLink(color);
2130 }
2131 }
2132
2133
2134
2135
2136 @Override
2137 @JsxGetter
2138 public Element getLastElementChild() {
2139 return super.getLastElementChild();
2140 }
2141
2142
2143
2144
2145 @Override
2146 @JsxGetter
2147 public Element getFirstElementChild() {
2148 return super.getFirstElementChild();
2149 }
2150
2151
2152
2153
2154
2155 @JsxGetter({CHROME, EDGE})
2156 public String getXmlEncoding() {
2157 return getPage().getXmlEncoding();
2158 }
2159
2160
2161
2162
2163
2164 @JsxGetter({CHROME, EDGE})
2165 public boolean isXmlStandalone() {
2166 return getPage().getXmlStandalone();
2167 }
2168
2169
2170
2171
2172
2173 @JsxGetter({CHROME, EDGE})
2174 public String getXmlVersion() {
2175 return getPage().getXmlVersion();
2176 }
2177
2178
2179
2180
2181
2182 @JsxGetter
2183 public Function getOnabort() {
2184 return getEventHandler(Event.TYPE_ABORT);
2185 }
2186
2187
2188
2189
2190
2191 @JsxSetter
2192 public void setOnabort(final Object onabort) {
2193 setEventHandler(Event.TYPE_ABORT, onabort);
2194 }
2195
2196
2197
2198
2199
2200 @JsxGetter({CHROME, EDGE})
2201 public Function getOnauxclick() {
2202 return getEventHandler(Event.TYPE_AUXCLICK);
2203 }
2204
2205
2206
2207
2208
2209 @JsxSetter({CHROME, EDGE})
2210 public void setOnauxclick(final Object onauxclick) {
2211 setEventHandler(Event.TYPE_AUXCLICK, onauxclick);
2212 }
2213
2214
2215
2216
2217
2218 @JsxGetter({CHROME, EDGE})
2219 public Function getOnbeforecopy() {
2220 return getEventHandler(Event.TYPE_BEFORECOPY);
2221 }
2222
2223
2224
2225
2226
2227 @JsxSetter({CHROME, EDGE})
2228 public void setOnbeforecopy(final Object onbeforecopy) {
2229 setEventHandler(Event.TYPE_BEFORECOPY, onbeforecopy);
2230 }
2231
2232
2233
2234
2235
2236 @JsxGetter({CHROME, EDGE})
2237 public Function getOnbeforecut() {
2238 return getEventHandler(Event.TYPE_BEFORECUT);
2239 }
2240
2241
2242
2243
2244
2245 @JsxSetter({CHROME, EDGE})
2246 public void setOnbeforecut(final Object onbeforecut) {
2247 setEventHandler(Event.TYPE_BEFORECUT, onbeforecut);
2248 }
2249
2250
2251
2252
2253
2254 @JsxGetter({CHROME, EDGE})
2255 public Function getOnbeforepaste() {
2256 return getEventHandler(Event.TYPE_BEFOREPASTE);
2257 }
2258
2259
2260
2261
2262
2263 @JsxSetter({CHROME, EDGE})
2264 public void setOnbeforepaste(final Object onbeforepaste) {
2265 setEventHandler(Event.TYPE_BEFOREPASTE, onbeforepaste);
2266 }
2267
2268
2269
2270
2271
2272 @JsxGetter({CHROME, EDGE})
2273 public Function getOncancel() {
2274 return getEventHandler(Event.TYPE_CANCEL);
2275 }
2276
2277
2278
2279
2280
2281 @JsxSetter({CHROME, EDGE})
2282 public void setOncancel(final Object oncancel) {
2283 setEventHandler(Event.TYPE_CANCEL, oncancel);
2284 }
2285
2286
2287
2288
2289
2290 @JsxGetter
2291 public Function getOncanplay() {
2292 return getEventHandler(Event.TYPE_CANPLAY);
2293 }
2294
2295
2296
2297
2298
2299 @JsxSetter
2300 public void setOncanplay(final Object oncanplay) {
2301 setEventHandler(Event.TYPE_CANPLAY, oncanplay);
2302 }
2303
2304
2305
2306
2307
2308 @JsxGetter
2309 public Function getOncanplaythrough() {
2310 return getEventHandler(Event.TYPE_CANPLAYTHROUGH);
2311 }
2312
2313
2314
2315
2316
2317 @JsxSetter
2318 public void setOncanplaythrough(final Object oncanplaythrough) {
2319 setEventHandler(Event.TYPE_CANPLAYTHROUGH, oncanplaythrough);
2320 }
2321
2322
2323
2324
2325
2326 @JsxGetter
2327 public Function getOnchange() {
2328 return getEventHandler(Event.TYPE_CHANGE);
2329 }
2330
2331
2332
2333
2334
2335 @JsxSetter
2336 public void setOnchange(final Object onchange) {
2337 setEventHandler(Event.TYPE_CHANGE, onchange);
2338 }
2339
2340
2341
2342
2343
2344 @JsxGetter({CHROME, EDGE})
2345 public Function getOnclose() {
2346 return getEventHandler(Event.TYPE_CLOSE);
2347 }
2348
2349
2350
2351
2352
2353 @JsxSetter({CHROME, EDGE})
2354 public void setOnclose(final Object onclose) {
2355 setEventHandler(Event.TYPE_CLOSE, onclose);
2356 }
2357
2358
2359
2360
2361
2362 @JsxGetter
2363 public Function getOncopy() {
2364 return getEventHandler(Event.TYPE_COPY);
2365 }
2366
2367
2368
2369
2370
2371 @JsxSetter
2372 public void setOncopy(final Object oncopy) {
2373 setEventHandler(Event.TYPE_COPY, oncopy);
2374 }
2375
2376
2377
2378
2379
2380 @JsxGetter({CHROME, EDGE})
2381 public Function getOncuechange() {
2382 return getEventHandler(Event.TYPE_CUECHANGE);
2383 }
2384
2385
2386
2387
2388
2389 @JsxSetter({CHROME, EDGE})
2390 public void setOncuechange(final Object oncuechange) {
2391 setEventHandler(Event.TYPE_CUECHANGE, oncuechange);
2392 }
2393
2394
2395
2396
2397
2398 @JsxGetter
2399 public Function getOncut() {
2400 return getEventHandler(Event.TYPE_CUT);
2401 }
2402
2403
2404
2405
2406
2407 @JsxSetter
2408 public void setOncut(final Object oncut) {
2409 setEventHandler(Event.TYPE_CUT, oncut);
2410 }
2411
2412
2413
2414
2415
2416 @JsxGetter
2417 public Function getOndrag() {
2418 return getEventHandler(Event.TYPE_DRAG);
2419 }
2420
2421
2422
2423
2424
2425 @JsxSetter
2426 public void setOndrag(final Object ondrag) {
2427 setEventHandler(Event.TYPE_DRAG, ondrag);
2428 }
2429
2430
2431
2432
2433
2434 @JsxGetter
2435 public Function getOndragend() {
2436 return getEventHandler(Event.TYPE_DRAGEND);
2437 }
2438
2439
2440
2441
2442
2443 @JsxSetter
2444 public void setOndragend(final Object ondragend) {
2445 setEventHandler(Event.TYPE_DRAGEND, ondragend);
2446 }
2447
2448
2449
2450
2451
2452 @JsxGetter
2453 public Function getOndragenter() {
2454 return getEventHandler(Event.TYPE_DRAGENTER);
2455 }
2456
2457
2458
2459
2460
2461 @JsxSetter
2462 public void setOndragenter(final Object ondragenter) {
2463 setEventHandler(Event.TYPE_DRAGENTER, ondragenter);
2464 }
2465
2466
2467
2468
2469
2470 @JsxGetter
2471 public Function getOndragleave() {
2472 return getEventHandler(Event.TYPE_DRAGLEAVE);
2473 }
2474
2475
2476
2477
2478
2479 @JsxSetter
2480 public void setOndragleave(final Object ondragleave) {
2481 setEventHandler(Event.TYPE_DRAGLEAVE, ondragleave);
2482 }
2483
2484
2485
2486
2487
2488 @JsxGetter
2489 public Function getOndragover() {
2490 return getEventHandler(Event.TYPE_DRAGOVER);
2491 }
2492
2493
2494
2495
2496
2497 @JsxSetter
2498 public void setOndragover(final Object ondragover) {
2499 setEventHandler(Event.TYPE_DRAGOVER, ondragover);
2500 }
2501
2502
2503
2504
2505
2506 @JsxGetter
2507 public Function getOndragstart() {
2508 return getEventHandler(Event.TYPE_DRAGSTART);
2509 }
2510
2511
2512
2513
2514
2515 @JsxSetter
2516 public void setOndragstart(final Object ondragstart) {
2517 setEventHandler(Event.TYPE_DRAGSTART, ondragstart);
2518 }
2519
2520
2521
2522
2523
2524 @JsxGetter
2525 public Function getOndrop() {
2526 return getEventHandler(Event.TYPE_DROP);
2527 }
2528
2529
2530
2531
2532
2533 @JsxSetter
2534 public void setOndrop(final Object ondrop) {
2535 setEventHandler(Event.TYPE_DROP, ondrop);
2536 }
2537
2538
2539
2540
2541
2542 @JsxGetter
2543 public Function getOndurationchange() {
2544 return getEventHandler(Event.TYPE_DURATIONCHANGE);
2545 }
2546
2547
2548
2549
2550
2551 @JsxSetter
2552 public void setOndurationchange(final Object ondurationchange) {
2553 setEventHandler(Event.TYPE_DURATIONCHANGE, ondurationchange);
2554 }
2555
2556
2557
2558
2559
2560 @JsxGetter
2561 public Function getOnemptied() {
2562 return getEventHandler(Event.TYPE_EMPTIED);
2563 }
2564
2565
2566
2567
2568
2569 @JsxSetter
2570 public void setOnemptied(final Object onemptied) {
2571 setEventHandler(Event.TYPE_EMPTIED, onemptied);
2572 }
2573
2574
2575
2576
2577
2578 @JsxGetter
2579 public Function getOnended() {
2580 return getEventHandler(Event.TYPE_ENDED);
2581 }
2582
2583
2584
2585
2586
2587 @JsxSetter
2588 public void setOnended(final Object onended) {
2589 setEventHandler(Event.TYPE_ENDED, onended);
2590 }
2591
2592
2593
2594
2595
2596 @JsxGetter({CHROME, EDGE})
2597 public Function getOngotpointercapture() {
2598 return getEventHandler(Event.TYPE_GOTPOINTERCAPTURE);
2599 }
2600
2601
2602
2603
2604
2605 @JsxSetter({CHROME, EDGE})
2606 public void setOngotpointercapture(final Object ongotpointercapture) {
2607 setEventHandler(Event.TYPE_GOTPOINTERCAPTURE, ongotpointercapture);
2608 }
2609
2610
2611
2612
2613
2614 @JsxGetter
2615 public Function getOninvalid() {
2616 return getEventHandler(Event.TYPE_INVALID);
2617 }
2618
2619
2620
2621
2622
2623 @JsxSetter
2624 public void setOninvalid(final Object oninvalid) {
2625 setEventHandler(Event.TYPE_INVALID, oninvalid);
2626 }
2627
2628
2629
2630
2631
2632 @JsxGetter
2633 public Function getOnload() {
2634 return getEventHandler(Event.TYPE_LOAD);
2635 }
2636
2637
2638
2639
2640
2641 @JsxSetter
2642 public void setOnload(final Object onload) {
2643 setEventHandler(Event.TYPE_LOAD, onload);
2644 }
2645
2646
2647
2648
2649
2650 @JsxGetter
2651 public Function getOnloadeddata() {
2652 return getEventHandler(Event.TYPE_LOADEDDATA);
2653 }
2654
2655
2656
2657
2658
2659 @JsxSetter
2660 public void setOnloadeddata(final Object onloadeddata) {
2661 setEventHandler(Event.TYPE_LOADEDDATA, onloadeddata);
2662 }
2663
2664
2665
2666
2667
2668 @JsxGetter
2669 public Function getOnloadedmetadata() {
2670 return getEventHandler(Event.TYPE_LOADEDMETADATA);
2671 }
2672
2673
2674
2675
2676
2677 @JsxSetter
2678 public void setOnloadedmetadata(final Object onloadedmetadata) {
2679 setEventHandler(Event.TYPE_LOADEDMETADATA, onloadedmetadata);
2680 }
2681
2682
2683
2684
2685
2686 @JsxGetter
2687 public Function getOnloadstart() {
2688 return getEventHandler(Event.TYPE_LOAD_START);
2689 }
2690
2691
2692
2693
2694
2695 @JsxSetter
2696 public void setOnloadstart(final Object onloadstart) {
2697 setEventHandler(Event.TYPE_LOAD_START, onloadstart);
2698 }
2699
2700
2701
2702
2703
2704 @JsxGetter({CHROME, EDGE})
2705 public Function getOnlostpointercapture() {
2706 return getEventHandler(Event.TYPE_LOSTPOINTERCAPTURE);
2707 }
2708
2709
2710
2711
2712
2713 @JsxSetter({CHROME, EDGE})
2714 public void setOnlostpointercapture(final Object onlostpointercapture) {
2715 setEventHandler(Event.TYPE_LOSTPOINTERCAPTURE, onlostpointercapture);
2716 }
2717
2718
2719
2720
2721
2722 @JsxGetter
2723 public Function getOnmouseenter() {
2724 return getEventHandler(Event.TYPE_MOUDEENTER);
2725 }
2726
2727
2728
2729
2730
2731 @JsxSetter
2732 public void setOnmouseenter(final Object onmouseenter) {
2733 setEventHandler(Event.TYPE_MOUDEENTER, onmouseenter);
2734 }
2735
2736
2737
2738
2739
2740 @JsxGetter
2741 public Function getOnmouseleave() {
2742 return getEventHandler(Event.TYPE_MOUSELEAVE);
2743 }
2744
2745
2746
2747
2748
2749 @JsxSetter
2750 public void setOnmouseleave(final Object onmouseleave) {
2751 setEventHandler(Event.TYPE_MOUSELEAVE, onmouseleave);
2752 }
2753
2754
2755
2756
2757
2758 @JsxGetter({CHROME, EDGE})
2759 public Function getOnmousewheel() {
2760 return getEventHandler(Event.TYPE_MOUSEWHEEL);
2761 }
2762
2763
2764
2765
2766
2767 @JsxSetter({CHROME, EDGE})
2768 public void setOnmousewheel(final Object onmousewheel) {
2769 setEventHandler(Event.TYPE_MOUSEWHEEL, onmousewheel);
2770 }
2771
2772
2773
2774
2775
2776 @JsxGetter
2777 public Function getOnpaste() {
2778 return getEventHandler(Event.TYPE_PASTE);
2779 }
2780
2781
2782
2783
2784
2785 @JsxSetter
2786 public void setOnpaste(final Object onpaste) {
2787 setEventHandler(Event.TYPE_PASTE, onpaste);
2788 }
2789
2790
2791
2792
2793
2794 @JsxGetter
2795 public Function getOnpause() {
2796 return getEventHandler(Event.TYPE_PAUSE);
2797 }
2798
2799
2800
2801
2802
2803 @JsxSetter
2804 public void setOnpause(final Object onpause) {
2805 setEventHandler(Event.TYPE_PAUSE, onpause);
2806 }
2807
2808
2809
2810
2811
2812 @JsxGetter
2813 public Function getOnplay() {
2814 return getEventHandler(Event.TYPE_PLAY);
2815 }
2816
2817
2818
2819
2820
2821 @JsxSetter
2822 public void setOnplay(final Object onplay) {
2823 setEventHandler(Event.TYPE_PLAY, onplay);
2824 }
2825
2826
2827
2828
2829
2830 @JsxGetter
2831 public Function getOnplaying() {
2832 return getEventHandler(Event.TYPE_PLAYING);
2833 }
2834
2835
2836
2837
2838
2839 @JsxSetter
2840 public void setOnplaying(final Object onplaying) {
2841 setEventHandler(Event.TYPE_PLAYING, onplaying);
2842 }
2843
2844
2845
2846
2847
2848 @JsxGetter({CHROME, EDGE})
2849 public Function getOnpointercancel() {
2850 return getEventHandler(Event.TYPE_POINTERCANCEL);
2851 }
2852
2853
2854
2855
2856
2857 @JsxSetter({CHROME, EDGE})
2858 public void setOnpointercancel(final Object onpointercancel) {
2859 setEventHandler(Event.TYPE_POINTERCANCEL, onpointercancel);
2860 }
2861
2862
2863
2864
2865
2866 @JsxGetter({CHROME, EDGE})
2867 public Function getOnpointerdown() {
2868 return getEventHandler(Event.TYPE_POINTERDOWN);
2869 }
2870
2871
2872
2873
2874
2875 @JsxSetter({CHROME, EDGE})
2876 public void setOnpointerdown(final Object onpointerdown) {
2877 setEventHandler(Event.TYPE_POINTERDOWN, onpointerdown);
2878 }
2879
2880
2881
2882
2883
2884 @JsxGetter({CHROME, EDGE})
2885 public Function getOnpointerenter() {
2886 return getEventHandler(Event.TYPE_POINTERENTER);
2887 }
2888
2889
2890
2891
2892
2893 @JsxSetter({CHROME, EDGE})
2894 public void setOnpointerenter(final Object onpointerenter) {
2895 setEventHandler(Event.TYPE_POINTERENTER, onpointerenter);
2896 }
2897
2898
2899
2900
2901
2902 @JsxGetter({CHROME, EDGE})
2903 public Function getOnpointerleave() {
2904 return getEventHandler(Event.TYPE_POINTERLEAVE);
2905 }
2906
2907
2908
2909
2910
2911 @JsxSetter({CHROME, EDGE})
2912 public void setOnpointerleave(final Object onpointerleave) {
2913 setEventHandler(Event.TYPE_POINTERLEAVE, onpointerleave);
2914 }
2915
2916
2917
2918
2919
2920 @JsxGetter({CHROME, EDGE})
2921 public Function getOnpointerlockchange() {
2922 return getEventHandler(Event.TYPE_POINTERLOCKCHANGE);
2923 }
2924
2925
2926
2927
2928
2929 @JsxSetter({CHROME, EDGE})
2930 public void setOnpointerlockchange(final Object onpointerlockchange) {
2931 setEventHandler(Event.TYPE_POINTERLOCKCHANGE, onpointerlockchange);
2932 }
2933
2934
2935
2936
2937
2938 @JsxGetter({CHROME, EDGE})
2939 public Function getOnpointerlockerror() {
2940 return getEventHandler(Event.TYPE_POINTERLOCKERROR);
2941 }
2942
2943
2944
2945
2946
2947 @JsxSetter({CHROME, EDGE})
2948 public void setOnpointerlockerror(final Object onpointerlockerror) {
2949 setEventHandler(Event.TYPE_POINTERLOCKERROR, onpointerlockerror);
2950 }
2951
2952
2953
2954
2955
2956 @JsxGetter({CHROME, EDGE})
2957 public Function getOnpointermove() {
2958 return getEventHandler(Event.TYPE_POINTERMOVE);
2959 }
2960
2961
2962
2963
2964
2965 @JsxSetter({CHROME, EDGE})
2966 public void setOnpointermove(final Object onpointermove) {
2967 setEventHandler(Event.TYPE_POINTERMOVE, onpointermove);
2968 }
2969
2970
2971
2972
2973
2974 @JsxGetter({CHROME, EDGE})
2975 public Function getOnpointerout() {
2976 return getEventHandler(Event.TYPE_POINTEROUT);
2977 }
2978
2979
2980
2981
2982
2983 @JsxSetter({CHROME, EDGE})
2984 public void setOnpointerout(final Object onpointerout) {
2985 setEventHandler(Event.TYPE_POINTEROUT, onpointerout);
2986 }
2987
2988
2989
2990
2991
2992 @JsxGetter({CHROME, EDGE})
2993 public Function getOnpointerover() {
2994 return getEventHandler(Event.TYPE_POINTEROVER);
2995 }
2996
2997
2998
2999
3000
3001 @JsxSetter({CHROME, EDGE})
3002 public void setOnpointerover(final Object onpointerover) {
3003 setEventHandler(Event.TYPE_POINTEROVER, onpointerover);
3004 }
3005
3006
3007
3008
3009
3010 @JsxGetter({CHROME, EDGE})
3011 public Function getOnpointerup() {
3012 return getEventHandler(Event.TYPE_POINTERUP);
3013 }
3014
3015
3016
3017
3018
3019 @JsxSetter({CHROME, EDGE})
3020 public void setOnpointerup(final Object onpointerup) {
3021 setEventHandler(Event.TYPE_POINTERUP, onpointerup);
3022 }
3023
3024
3025
3026
3027
3028 @JsxGetter
3029 public Function getOnprogress() {
3030 return getEventHandler(Event.TYPE_PROGRESS);
3031 }
3032
3033
3034
3035
3036
3037 @JsxSetter
3038 public void setOnprogress(final Object onprogress) {
3039 setEventHandler(Event.TYPE_PROGRESS, onprogress);
3040 }
3041
3042
3043
3044
3045
3046 @JsxGetter
3047 public Function getOnratechange() {
3048 return getEventHandler(Event.TYPE_RATECHANGE);
3049 }
3050
3051
3052
3053
3054
3055 @JsxSetter
3056 public void setOnratechange(final Object onratechange) {
3057 setEventHandler(Event.TYPE_RATECHANGE, onratechange);
3058 }
3059
3060
3061
3062
3063
3064 @JsxGetter
3065 public Function getOnreadystatechange() {
3066 return getEventHandler(Event.TYPE_READY_STATE_CHANGE);
3067 }
3068
3069
3070
3071
3072
3073 @JsxSetter
3074 public void setOnreadystatechange(final Object onreadystatechange) {
3075 setEventHandler(Event.TYPE_READY_STATE_CHANGE, onreadystatechange);
3076 }
3077
3078
3079
3080
3081
3082 @JsxGetter
3083 public Function getOnreset() {
3084 return getEventHandler(Event.TYPE_RESET);
3085 }
3086
3087
3088
3089
3090
3091 @JsxSetter
3092 public void setOnreset(final Object onreset) {
3093 setEventHandler(Event.TYPE_RESET, onreset);
3094 }
3095
3096
3097
3098
3099
3100 @JsxGetter
3101 public Function getOnscroll() {
3102 return getEventHandler(Event.TYPE_SCROLL);
3103 }
3104
3105
3106
3107
3108
3109 @JsxSetter
3110 public void setOnscroll(final Object onscroll) {
3111 setEventHandler(Event.TYPE_SCROLL, onscroll);
3112 }
3113
3114
3115
3116
3117
3118 @JsxGetter({CHROME, EDGE})
3119 public Function getOnsearch() {
3120 return getEventHandler(Event.TYPE_SEARCH);
3121 }
3122
3123
3124
3125
3126
3127 @JsxSetter({CHROME, EDGE})
3128 public void setOnsearch(final Object onsearch) {
3129 setEventHandler(Event.TYPE_SEARCH, onsearch);
3130 }
3131
3132
3133
3134
3135
3136 @JsxGetter
3137 public Function getOnseeked() {
3138 return getEventHandler(Event.TYPE_SEEKED);
3139 }
3140
3141
3142
3143
3144
3145 @JsxSetter
3146 public void setOnseeked(final Object onseeked) {
3147 setEventHandler(Event.TYPE_SEEKED, onseeked);
3148 }
3149
3150
3151
3152
3153
3154 @JsxGetter
3155 public Function getOnseeking() {
3156 return getEventHandler(Event.TYPE_SEEKING);
3157 }
3158
3159
3160
3161
3162
3163 @JsxSetter
3164 public void setOnseeking(final Object onseeking) {
3165 setEventHandler(Event.TYPE_SEEKING, onseeking);
3166 }
3167
3168
3169
3170
3171
3172 @JsxGetter
3173 public Function getOnselect() {
3174 return getEventHandler(Event.TYPE_SELECT);
3175 }
3176
3177
3178
3179
3180
3181 @JsxSetter
3182 public void setOnselect(final Object onselect) {
3183 setEventHandler(Event.TYPE_SELECT, onselect);
3184 }
3185
3186
3187
3188
3189
3190 @JsxGetter({CHROME, EDGE})
3191 public Function getOnselectionchange() {
3192 return getEventHandler(Event.TYPE_SELECTIONCHANGE);
3193 }
3194
3195
3196
3197
3198
3199 @JsxSetter({CHROME, EDGE})
3200 public void setOnselectionchange(final Object onselectionchange) {
3201 setEventHandler(Event.TYPE_SELECTIONCHANGE, onselectionchange);
3202 }
3203
3204
3205
3206
3207
3208 @JsxGetter
3209 public Function getOnselectstart() {
3210 return getEventHandler(Event.TYPE_SELECTSTART);
3211 }
3212
3213
3214
3215
3216
3217 @JsxSetter
3218 public void setOnselectstart(final Object onselectstart) {
3219 setEventHandler(Event.TYPE_SELECTSTART, onselectstart);
3220 }
3221
3222
3223
3224
3225
3226 @JsxGetter
3227 public Function getOnstalled() {
3228 return getEventHandler(Event.TYPE_STALLED);
3229 }
3230
3231
3232
3233
3234
3235 @JsxSetter
3236 public void setOnstalled(final Object onstalled) {
3237 setEventHandler(Event.TYPE_STALLED, onstalled);
3238 }
3239
3240
3241
3242
3243
3244 @JsxGetter
3245 public Function getOnsubmit() {
3246 return getEventHandler(Event.TYPE_SUBMIT);
3247 }
3248
3249
3250
3251
3252
3253 @JsxSetter
3254 public void setOnsubmit(final Object onsubmit) {
3255 setEventHandler(Event.TYPE_SUBMIT, onsubmit);
3256 }
3257
3258
3259
3260
3261
3262 @JsxGetter
3263 public Function getOnsuspend() {
3264 return getEventHandler(Event.TYPE_SUSPEND);
3265 }
3266
3267
3268
3269
3270
3271 @JsxSetter
3272 public void setOnsuspend(final Object onsuspend) {
3273 setEventHandler(Event.TYPE_SUSPEND, onsuspend);
3274 }
3275
3276
3277
3278
3279
3280 @JsxGetter
3281 public Function getOntimeupdate() {
3282 return getEventHandler(Event.TYPE_TIMEUPDATE);
3283 }
3284
3285
3286
3287
3288
3289 @JsxSetter
3290 public void setOntimeupdate(final Object ontimeupdate) {
3291 setEventHandler(Event.TYPE_TIMEUPDATE, ontimeupdate);
3292 }
3293
3294
3295
3296
3297
3298 @JsxGetter({CHROME, EDGE})
3299 public Function getOntoggle() {
3300 return getEventHandler(Event.TYPE_TOGGLE);
3301 }
3302
3303
3304
3305
3306
3307 @JsxSetter({CHROME, EDGE})
3308 public void setOntoggle(final Object ontoggle) {
3309 setEventHandler(Event.TYPE_TOGGLE, ontoggle);
3310 }
3311
3312
3313
3314
3315
3316 @JsxGetter
3317 public Function getOnvolumechange() {
3318 return getEventHandler(Event.TYPE_VOLUMECHANGE);
3319 }
3320
3321
3322
3323
3324
3325 @JsxSetter
3326 public void setOnvolumechange(final Object onvolumechange) {
3327 setEventHandler(Event.TYPE_VOLUMECHANGE, onvolumechange);
3328 }
3329
3330
3331
3332
3333
3334 @JsxGetter
3335 public Function getOnwaiting() {
3336 return getEventHandler(Event.TYPE_WAITING);
3337 }
3338
3339
3340
3341
3342
3343 @JsxSetter
3344 public void setOnwaiting(final Object onwaiting) {
3345 setEventHandler(Event.TYPE_WAITING, onwaiting);
3346 }
3347
3348
3349
3350
3351
3352 @JsxGetter({CHROME, EDGE})
3353 public Function getOnwebkitfullscreenchange() {
3354 return getEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE);
3355 }
3356
3357
3358
3359
3360
3361 @JsxSetter({CHROME, EDGE})
3362 public void setOnwebkitfullscreenchange(final Object onwebkitfullscreenchange) {
3363 setEventHandler(Event.TYPE_WEBKITFULLSCREENCHANGE, onwebkitfullscreenchange);
3364 }
3365
3366
3367
3368
3369
3370 @JsxGetter({CHROME, EDGE})
3371 public Function getOnwebkitfullscreenerror() {
3372 return getEventHandler(Event.TYPE_WEBKITFULLSCREENERROR);
3373 }
3374
3375
3376
3377
3378
3379 @JsxSetter
3380 public void setOnwebkitfullscreenerror(final Object onwebkitfullscreenerror) {
3381 setEventHandler(Event.TYPE_WEBKITFULLSCREENERROR, onwebkitfullscreenerror);
3382 }
3383
3384
3385
3386
3387
3388 @JsxGetter
3389 public Function getOnwheel() {
3390 return getEventHandler(Event.TYPE_WHEEL);
3391 }
3392
3393
3394
3395
3396
3397 @JsxSetter
3398 public void setOnwheel(final Object onwheel) {
3399 setEventHandler(Event.TYPE_WHEEL, onwheel);
3400 }
3401
3402
3403
3404
3405
3406 @JsxGetter({FF, FF_ESR})
3407 public Function getOnafterscriptexecute() {
3408 return getEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE);
3409 }
3410
3411
3412
3413
3414
3415 @JsxSetter({FF, FF_ESR})
3416 public void setOnafterscriptexecute(final Object onafterscriptexecute) {
3417 setEventHandler(Event.TYPE_AFTERSCRIPTEXECUTE, onafterscriptexecute);
3418 }
3419
3420
3421
3422
3423
3424 @JsxGetter({FF, FF_ESR})
3425 public Function getOnbeforescriptexecute() {
3426 return getEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE);
3427 }
3428
3429
3430
3431
3432
3433 @JsxSetter({FF, FF_ESR})
3434 public void setOnbeforescriptexecute(final Object onbeforescriptexecute) {
3435 setEventHandler(Event.TYPE_BEFORESCRIPTEXECUTE, onbeforescriptexecute);
3436 }
3437
3438
3439
3440
3441
3442 @JsxGetter({FF, FF_ESR})
3443 public Function getOnmozfullscreenchange() {
3444 return getEventHandler(Event.TYPE_MOZFULLSCREENCHANGE);
3445 }
3446
3447
3448
3449
3450
3451 @JsxSetter({FF, FF_ESR})
3452 public void setOnmozfullscreenchange(final Object onmozfullscreenchange) {
3453 setEventHandler(Event.TYPE_MOZFULLSCREENCHANGE, onmozfullscreenchange);
3454 }
3455
3456
3457
3458
3459
3460 @JsxGetter({FF, FF_ESR})
3461 public Function getOnmozfullscreenerror() {
3462 return getEventHandler(Event.TYPE_MOZFULLSCREENERROR);
3463 }
3464
3465
3466
3467
3468
3469 @JsxSetter({FF, FF_ESR})
3470 public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
3471 setEventHandler(Event.TYPE_MOZFULLSCREENERROR, onmozfullscreenerror);
3472 }
3473
3474
3475
3476
3477 @JsxGetter
3478 public ScriptableObject getCurrentScript() {
3479 return currentScript_;
3480 }
3481
3482
3483
3484
3485 public void setCurrentScript(final ScriptableObject script) {
3486 currentScript_ = script;
3487 }
3488
3489
3490
3491
3492 @JsxGetter
3493 public ScriptableObject getFonts() {
3494 if (fonts_ == null) {
3495 final FontFaceSet fonts = new FontFaceSet();
3496 fonts.setParentScope(getWindow());
3497 fonts.setPrototype(getPrototype(fonts.getClass()));
3498 fonts_ = fonts;
3499 }
3500 return fonts_;
3501 }
3502
3503
3504
3505
3506
3507 @JsxGetter
3508 public HTMLCollection getAll() {
3509 final HTMLCollection all = new HTMLAllCollection(getDomNodeOrDie());
3510 all.setAvoidObjectDetection(true);
3511 all.setIsMatchingPredicate((Predicate<DomNode> & Serializable) node -> true);
3512 return all;
3513 }
3514
3515
3516
3517
3518
3519
3520 @JsxFunction
3521 public HtmlUnitScriptable getElementById(final String id) {
3522 final DomNode domNode = getDomNodeOrDie();
3523 for (final DomElement descendant : domNode.getDomElementDescendants()) {
3524 if (id.equals(descendant.getId())) {
3525 return descendant.getScriptableObject();
3526 }
3527 }
3528 return null;
3529 }
3530
3531
3532
3533
3534
3535
3536
3537 @JsxFunction
3538 public HtmlUnitScriptable createProcessingInstruction(final String target, final String data) {
3539 final ProcessingInstruction node = getPage().createProcessingInstruction(target, data);
3540 return getScriptableFor(node);
3541 }
3542
3543
3544
3545
3546
3547
3548 @JsxFunction
3549 public HtmlUnitScriptable createCDATASection(final String data) {
3550 final CDATASection node = getPage().createCDATASection(data);
3551 return getScriptableFor(node);
3552 }
3553
3554
3555
3556
3557
3558 @JsxFunction
3559 public void clear() {
3560
3561 }
3562
3563
3564
3565
3566 @JsxFunction
3567 @Override
3568 public boolean contains(final Object element) {
3569 return getDocumentElement().contains(element);
3570 }
3571
3572
3573
3574
3575
3576
3577 public String generateBlobUrl(final Blob blob) {
3578 final URL url = getPage().getUrl();
3579
3580 String origin = "null";
3581 if (!UrlUtils.URL_ABOUT_BLANK.equals(url)) {
3582 origin = url.getProtocol() + "://" + url.getAuthority();
3583 }
3584
3585 final String blobUrl = "blob:" + origin + "/" + UUID.randomUUID();
3586 blobUrl2Blobs_.put(blobUrl, blob);
3587 return blobUrl;
3588 }
3589
3590
3591
3592
3593
3594 public Blob resolveBlobUrl(final String url) {
3595 return blobUrl2Blobs_.get(url);
3596 }
3597
3598
3599
3600
3601
3602 public void revokeBlobUrl(final String url) {
3603 blobUrl2Blobs_.remove(url);
3604 }
3605 }