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