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