1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import static org.htmlunit.BrowserVersionFeatures.FORM_IGNORE_REL_NOREFERRER;
18 import static org.htmlunit.BrowserVersionFeatures.FORM_SUBMISSION_HEADER_CACHE_CONTROL_MAX_AGE;
19
20 import java.net.MalformedURLException;
21 import java.net.URL;
22 import java.nio.charset.Charset;
23 import java.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Map;
31 import java.util.Objects;
32 import java.util.function.Predicate;
33 import java.util.regex.Pattern;
34
35 import org.apache.commons.lang3.ArrayUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.htmlunit.BrowserVersion;
40 import org.htmlunit.ElementNotFoundException;
41 import org.htmlunit.FormEncodingType;
42 import org.htmlunit.HttpHeader;
43 import org.htmlunit.HttpMethod;
44 import org.htmlunit.Page;
45 import org.htmlunit.ScriptResult;
46 import org.htmlunit.SgmlPage;
47 import org.htmlunit.WebAssert;
48 import org.htmlunit.WebClient;
49 import org.htmlunit.WebRequest;
50 import org.htmlunit.WebWindow;
51 import org.htmlunit.http.HttpUtils;
52 import org.htmlunit.javascript.host.event.Event;
53 import org.htmlunit.javascript.host.event.SubmitEvent;
54 import org.htmlunit.protocol.javascript.JavaScriptURLConnection;
55 import org.htmlunit.util.EncodingSniffer;
56 import org.htmlunit.util.NameValuePair;
57 import org.htmlunit.util.UrlUtils;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public class HtmlForm extends HtmlElement {
77 private static final Log LOG = LogFactory.getLog(HtmlForm.class);
78
79
80 public static final String TAG_NAME = "form";
81
82
83 private static final String ATTRIBUTE_NOVALIDATE = "novalidate";
84
85
86 public static final String ATTRIBUTE_FORMNOVALIDATE = "formnovalidate";
87
88 private static final HashSet<String> SUBMITTABLE_TAG_NAMES = new HashSet<>(Arrays.asList(HtmlInput.TAG_NAME,
89 HtmlButton.TAG_NAME, HtmlSelect.TAG_NAME, HtmlTextArea.TAG_NAME));
90
91 private static final Pattern SUBMIT_CHARSET_PATTERN = Pattern.compile("[ ,].*");
92
93 private boolean isPreventDefault_;
94
95
96
97
98
99
100
101
102 HtmlForm(final String qualifiedName, final SgmlPage htmlPage,
103 final Map<String, DomAttr> attributes) {
104 super(qualifiedName, htmlPage, attributes);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public void submit(final SubmittableElement submitElement) {
121 final HtmlPage htmlPage = (HtmlPage) getPage();
122 final WebClient webClient = htmlPage.getWebClient();
123
124 if (webClient.isJavaScriptEnabled()) {
125 if (submitElement != null) {
126 isPreventDefault_ = false;
127
128 boolean validate = true;
129 if (submitElement instanceof HtmlSubmitInput
130 && ((HtmlSubmitInput) submitElement).isFormNoValidate()) {
131 validate = false;
132 }
133 else if (submitElement instanceof HtmlButton) {
134 final HtmlButton htmlButton = (HtmlButton) submitElement;
135 if ("submit".equalsIgnoreCase(htmlButton.getType())
136 && htmlButton.isFormNoValidate()) {
137 validate = false;
138 }
139 }
140
141 if (validate
142 && getAttributeDirect(ATTRIBUTE_NOVALIDATE) != ATTRIBUTE_NOT_DEFINED) {
143 validate = false;
144 }
145
146 if (validate && !areChildrenValid()) {
147 return;
148 }
149 final ScriptResult scriptResult = fireEvent(new SubmitEvent(this,
150 ((HtmlElement) submitElement).getScriptableObject()));
151 if (isPreventDefault_) {
152
153 if (scriptResult == null) {
154 return;
155 }
156 return;
157 }
158 }
159
160 final String action = getActionAttribute().trim();
161 if (StringUtils.startsWithIgnoreCase(action, JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
162 htmlPage.executeJavaScript(action, "Form action", getStartLineNumber());
163 return;
164 }
165 }
166 else {
167 if (StringUtils.startsWithIgnoreCase(getActionAttribute(), JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
168
169 return;
170 }
171 }
172
173
174 if (submitElement != null) {
175 updateHtml5Attributes(submitElement);
176 }
177
178
179 final String methodAttribute = getMethodAttribute();
180 if ("dialog".equalsIgnoreCase(methodAttribute)) {
181
182 final HtmlElement dialog = getEnclosingElement("dialog");
183 if (dialog != null) {
184 ((HtmlDialog) dialog).close("");
185 }
186 return;
187 }
188
189 final WebRequest request = getWebRequest(submitElement);
190 final String target = htmlPage.getResolvedTarget(getTargetAttribute());
191
192 final WebWindow webWindow = htmlPage.getEnclosingWindow();
193
194 webClient.download(webWindow, target, request, false, false, null, "JS form.submit()");
195 }
196
197
198
199
200
201
202
203 private void updateHtml5Attributes(final SubmittableElement submitElement) {
204 if (submitElement instanceof HtmlElement) {
205 final HtmlElement element = (HtmlElement) submitElement;
206
207 final String type = element.getAttributeDirect(TYPE_ATTRIBUTE);
208 boolean typeImage = false;
209 final boolean isInput = HtmlInput.TAG_NAME.equals(element.getTagName());
210 if (isInput) {
211 typeImage = "image".equalsIgnoreCase(type);
212 }
213
214
215
216
217
218 final boolean typeSubmit = "submit".equalsIgnoreCase(type);
219 if (isInput && !typeSubmit && !typeImage) {
220 return;
221 }
222 else if (HtmlButton.TAG_NAME.equals(element.getTagName())
223 && !"submit".equals(((HtmlButton) element).getType())) {
224 return;
225 }
226
227 final String formaction = element.getAttributeDirect("formaction");
228 if (ATTRIBUTE_NOT_DEFINED != formaction) {
229 setActionAttribute(formaction);
230 }
231 final String formmethod = element.getAttributeDirect("formmethod");
232 if (ATTRIBUTE_NOT_DEFINED != formmethod) {
233 setMethodAttribute(formmethod);
234 }
235 final String formtarget = element.getAttributeDirect("formtarget");
236 if (ATTRIBUTE_NOT_DEFINED != formtarget) {
237 setTargetAttribute(formtarget);
238 }
239 final String formenctype = element.getAttributeDirect("formenctype");
240 if (ATTRIBUTE_NOT_DEFINED != formenctype) {
241 setEnctypeAttribute(formenctype);
242 }
243 }
244 }
245
246 private boolean areChildrenValid() {
247 boolean valid = true;
248 for (final HtmlElement element : getElements(htmlElement -> htmlElement instanceof HtmlInput)) {
249 if (!element.isValid()) {
250 if (LOG.isInfoEnabled()) {
251 LOG.info("Form validation failed; element '" + element + "' was not valid. Submit cancelled.");
252 }
253 valid = false;
254 break;
255 }
256 }
257 return valid;
258 }
259
260
261
262
263
264
265
266
267 public WebRequest getWebRequest(final SubmittableElement submitElement) {
268 final HttpMethod method;
269 final String methodAttribute = getMethodAttribute();
270 if ("post".equalsIgnoreCase(methodAttribute)) {
271 method = HttpMethod.POST;
272 }
273 else {
274 if (!"get".equalsIgnoreCase(methodAttribute) && StringUtils.isNotBlank(methodAttribute)) {
275 notifyIncorrectness("Incorrect submit method >" + getMethodAttribute() + "<. Using >GET<.");
276 }
277 method = HttpMethod.GET;
278 }
279
280 String actionUrl = getActionAttribute();
281 String anchor = null;
282 String queryFormFields = "";
283 Charset enc = getSubmitCharset();
284 if (StandardCharsets.UTF_16 == enc
285 || StandardCharsets.UTF_16BE == enc
286 || StandardCharsets.UTF_16LE == enc) {
287 enc = StandardCharsets.UTF_8;
288 }
289
290 final List<NameValuePair> parameters = getParameterListForSubmit(submitElement);
291 if (HttpMethod.GET == method) {
292 if (actionUrl.contains("#")) {
293 anchor = StringUtils.substringAfter(actionUrl, "#");
294 }
295 queryFormFields = HttpUtils.toQueryFormFields(parameters, enc);
296
297
298 actionUrl = StringUtils.substringBefore(actionUrl, "#");
299 actionUrl = StringUtils.substringBefore(actionUrl, "?");
300 parameters.clear();
301 }
302
303 final HtmlPage htmlPage = (HtmlPage) getPage();
304 URL url;
305 try {
306 if (actionUrl.isEmpty()) {
307 url = WebClient.expandUrl(htmlPage.getUrl(), actionUrl);
308 }
309 else {
310 url = htmlPage.getFullyQualifiedUrl(actionUrl);
311 }
312
313 if (!queryFormFields.isEmpty()) {
314 url = UrlUtils.getUrlWithNewQuery(url, queryFormFields);
315 }
316
317 if (anchor != null && UrlUtils.URL_ABOUT_BLANK != url) {
318 url = UrlUtils.getUrlWithNewRef(url, anchor);
319 }
320 }
321 catch (final MalformedURLException e) {
322 throw new IllegalArgumentException("Not a valid url: " + actionUrl, e);
323 }
324
325 final BrowserVersion browser = htmlPage.getWebClient().getBrowserVersion();
326 final WebRequest request = new WebRequest(url, browser.getHtmlAcceptHeader(),
327 browser.getAcceptEncodingHeader());
328 request.setHttpMethod(method);
329 request.setRequestParameters(parameters);
330 if (HttpMethod.POST == method) {
331 request.setEncodingType(FormEncodingType.getInstance(getEnctypeAttribute()));
332 }
333 request.setCharset(enc);
334
335
336 if (browser.hasFeature(FORM_IGNORE_REL_NOREFERRER)
337 || !relContainsNoreferrer()) {
338 request.setRefererHeader(htmlPage.getUrl());
339 }
340
341 if (HttpMethod.POST == method) {
342 try {
343 request.setAdditionalHeader(HttpHeader.ORIGIN,
344 UrlUtils.getUrlWithProtocolAndAuthority(htmlPage.getUrl()).toExternalForm());
345 }
346 catch (final MalformedURLException e) {
347 if (LOG.isInfoEnabled()) {
348 LOG.info("Invalid origin url '" + htmlPage.getUrl() + "'");
349 }
350 }
351 }
352 if (HttpMethod.POST == method) {
353 if (browser.hasFeature(FORM_SUBMISSION_HEADER_CACHE_CONTROL_MAX_AGE)) {
354 request.setAdditionalHeader(HttpHeader.CACHE_CONTROL, "max-age=0");
355 }
356 }
357
358 return request;
359 }
360
361 private boolean relContainsNoreferrer() {
362 String rel = getRelAttribute();
363 if (rel != null) {
364 rel = rel.toLowerCase(Locale.ROOT);
365 return ArrayUtils.contains(org.htmlunit.util.StringUtils.splitAtBlank(rel), "noreferrer");
366 }
367 return false;
368 }
369
370
371
372
373
374
375
376 private Charset getSubmitCharset() {
377 String charset = getAcceptCharsetAttribute();
378 if (!charset.isEmpty()) {
379 charset = charset.trim();
380 return EncodingSniffer.toCharset(
381 SUBMIT_CHARSET_PATTERN.matcher(charset).replaceAll("").toUpperCase(Locale.ROOT));
382 }
383 return getPage().getCharset();
384 }
385
386
387
388
389
390
391
392
393
394
395
396
397
398 public List<NameValuePair> getParameterListForSubmit(final SubmittableElement submitElement) {
399 final Collection<SubmittableElement> submittableElements = getSubmittableElements(submitElement);
400
401 final List<NameValuePair> parameterList = new ArrayList<>(submittableElements.size());
402 for (final SubmittableElement element : submittableElements) {
403 parameterList.addAll(Arrays.asList(element.getSubmitNameValuePairs()));
404 }
405
406 return parameterList;
407 }
408
409
410
411
412
413
414
415
416 public Page reset() {
417 final SgmlPage htmlPage = getPage();
418 final ScriptResult scriptResult = fireEvent(Event.TYPE_RESET);
419 if (ScriptResult.isFalse(scriptResult)) {
420 return htmlPage.getWebClient().getCurrentWindow().getEnclosedPage();
421 }
422
423 for (final HtmlElement next : getHtmlElementDescendants()) {
424 if (next instanceof SubmittableElement) {
425 ((SubmittableElement) next).reset();
426 }
427 }
428
429 return htmlPage;
430 }
431
432
433
434
435 @Override
436 public boolean isValid() {
437 for (final HtmlElement element : getFormElements()) {
438 if (!element.isValid()) {
439 return false;
440 }
441 }
442 return super.isValid();
443 }
444
445
446
447
448
449
450
451
452
453 Collection<SubmittableElement> getSubmittableElements(final SubmittableElement submitElement) {
454 final List<SubmittableElement> submittableElements = new ArrayList<>();
455
456 for (final HtmlElement element : getElements(htmlElement -> isSubmittable(htmlElement, submitElement))) {
457 submittableElements.add((SubmittableElement) element);
458 }
459
460 return submittableElements;
461 }
462
463 private static boolean isValidForSubmission(final HtmlElement element, final SubmittableElement submitElement) {
464 final String tagName = element.getTagName();
465 if (!SUBMITTABLE_TAG_NAMES.contains(tagName)) {
466 return false;
467 }
468 if (element.isDisabledElementAndDisabled()) {
469 return false;
470 }
471
472 if (element == submitElement && element instanceof HtmlImageInput) {
473 return true;
474 }
475
476 if (!element.hasAttribute(NAME_ATTRIBUTE)) {
477 return false;
478 }
479
480 if (org.htmlunit.util.StringUtils.isEmptyString(element.getAttributeDirect(NAME_ATTRIBUTE))) {
481 return false;
482 }
483
484 if (element instanceof HtmlInput) {
485 final HtmlInput input = (HtmlInput) element;
486 if (input.isCheckable()) {
487 return ((HtmlInput) element).isChecked();
488 }
489 }
490 if (HtmlSelect.TAG_NAME.equals(tagName)) {
491 return ((HtmlSelect) element).isValidForSubmission();
492 }
493 return true;
494 }
495
496
497
498
499
500
501
502
503
504
505 private static boolean isSubmittable(final HtmlElement element, final SubmittableElement submitElement) {
506 if (!isValidForSubmission(element, submitElement)) {
507 return false;
508 }
509
510
511 if (element == submitElement) {
512 return true;
513 }
514 if (element instanceof HtmlInput) {
515 final HtmlInput input = (HtmlInput) element;
516 if (!input.isSubmitable()) {
517 return false;
518 }
519 }
520
521 return !HtmlButton.TAG_NAME.equals(element.getTagName());
522 }
523
524
525
526
527
528
529
530 public List<HtmlInput> getInputsByName(final String name) {
531 return getFormElementsByAttribute(HtmlInput.TAG_NAME, NAME_ATTRIBUTE, name);
532 }
533
534
535
536
537
538 @SuppressWarnings("unchecked")
539 private <E extends HtmlElement> List<E> getFormElementsByAttribute(
540 final String elementName,
541 final String attributeName,
542 final String attributeValue) {
543
544 final List<E> list = new ArrayList<>();
545 final String lowerCaseTagName = elementName.toLowerCase(Locale.ROOT);
546
547 for (final HtmlElement element : getElements()) {
548 if (element.getTagName().equals(lowerCaseTagName)) {
549 final String attValue = element.getAttribute(attributeName);
550 if (attValue.equals(attributeValue)) {
551 list.add((E) element);
552 }
553 }
554 }
555 return list;
556 }
557
558
559
560
561
562
563 @Deprecated
564 public List<HtmlElement> getElements() {
565 return getElements(htmlElement -> SUBMITTABLE_TAG_NAMES.contains(htmlElement.getTagName()));
566 }
567
568
569
570
571
572
573
574
575
576 public List<HtmlElement> getFormElements() {
577 return getElements(htmlElement -> {
578 final String tagName = htmlElement.getTagName();
579 return HtmlButton.TAG_NAME.equals(tagName)
580 || HtmlFieldSet.TAG_NAME.equals(tagName)
581 || HtmlInput.TAG_NAME.equals(tagName)
582 || HtmlObject.TAG_NAME.equals(tagName)
583 || HtmlOutput.TAG_NAME.equals(tagName)
584 || HtmlSelect.TAG_NAME.equals(tagName)
585 || HtmlTextArea.TAG_NAME.equals(tagName);
586 });
587 }
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602 public List<HtmlElement> getElementsJS() {
603 return getElements(htmlElement -> {
604 final String tagName = htmlElement.getTagName();
605 if (HtmlInput.TAG_NAME.equals(tagName)) {
606 return !(htmlElement instanceof HtmlImageInput);
607 }
608
609 return HtmlButton.TAG_NAME.equals(tagName)
610 || HtmlFieldSet.TAG_NAME.equals(tagName)
611 || HtmlObject.TAG_NAME.equals(tagName)
612 || HtmlOutput.TAG_NAME.equals(tagName)
613 || HtmlSelect.TAG_NAME.equals(tagName)
614 || HtmlTextArea.TAG_NAME.equals(tagName);
615 });
616 }
617
618
619
620
621
622 public List<HtmlElement> getElements(final Predicate<HtmlElement> filter) {
623 final List<HtmlElement> elements = new ArrayList<>();
624
625 if (isAttachedToPage()) {
626 for (final HtmlElement element : getPage().getDocumentElement().getHtmlElementDescendants()) {
627 if (filter.test(element)
628 && element.getEnclosingForm() == this) {
629 elements.add(element);
630 }
631 }
632 }
633 else {
634 for (final HtmlElement element : getHtmlElementDescendants()) {
635 if (filter.test(element)) {
636 elements.add(element);
637 }
638 }
639 }
640
641 return elements;
642 }
643
644
645
646
647
648
649
650
651
652 @SuppressWarnings("unchecked")
653 public final <I extends HtmlInput> I getInputByName(final String name) throws ElementNotFoundException {
654 final List<HtmlInput> inputs = getInputsByName(name);
655
656 if (inputs.isEmpty()) {
657 throw new ElementNotFoundException(HtmlInput.TAG_NAME, NAME_ATTRIBUTE, name);
658 }
659 return (I) inputs.get(0);
660 }
661
662
663
664
665
666
667
668 public List<HtmlSelect> getSelectsByName(final String name) {
669 return getFormElementsByAttribute(HtmlSelect.TAG_NAME, NAME_ATTRIBUTE, name);
670 }
671
672
673
674
675
676
677
678
679
680 public HtmlSelect getSelectByName(final String name) throws ElementNotFoundException {
681 final List<HtmlSelect> list = getSelectsByName(name);
682 if (list.isEmpty()) {
683 throw new ElementNotFoundException(HtmlSelect.TAG_NAME, NAME_ATTRIBUTE, name);
684 }
685 return list.get(0);
686 }
687
688
689
690
691
692
693
694 public List<HtmlButton> getButtonsByName(final String name) {
695 return getFormElementsByAttribute(HtmlButton.TAG_NAME, NAME_ATTRIBUTE, name);
696 }
697
698
699
700
701
702
703
704
705
706 public HtmlButton getButtonByName(final String name) throws ElementNotFoundException {
707 final List<HtmlButton> list = getButtonsByName(name);
708 if (list.isEmpty()) {
709 throw new ElementNotFoundException(HtmlButton.TAG_NAME, NAME_ATTRIBUTE, name);
710 }
711 return list.get(0);
712 }
713
714
715
716
717
718
719
720 public List<HtmlTextArea> getTextAreasByName(final String name) {
721 return getFormElementsByAttribute(HtmlTextArea.TAG_NAME, NAME_ATTRIBUTE, name);
722 }
723
724
725
726
727
728
729
730
731
732 public HtmlTextArea getTextAreaByName(final String name) throws ElementNotFoundException {
733 final List<HtmlTextArea> list = getTextAreasByName(name);
734 if (list.isEmpty()) {
735 throw new ElementNotFoundException(HtmlTextArea.TAG_NAME, NAME_ATTRIBUTE, name);
736 }
737 return list.get(0);
738 }
739
740
741
742
743
744
745
746 public List<HtmlRadioButtonInput> getRadioButtonsByName(final String name) {
747 WebAssert.notNull("name", name);
748
749 final List<HtmlRadioButtonInput> results = new ArrayList<>();
750
751 for (final HtmlElement element : getInputsByName(name)) {
752 if (element instanceof HtmlRadioButtonInput) {
753 results.add((HtmlRadioButtonInput) element);
754 }
755 }
756
757 return results;
758 }
759
760
761
762
763
764
765
766 void setCheckedRadioButton(final HtmlRadioButtonInput radioButtonInput) {
767 if (radioButtonInput.getEnclosingForm() == null) {
768 throw new IllegalArgumentException("HtmlRadioButtonInput is not child of this HtmlForm");
769 }
770 final List<HtmlRadioButtonInput> radios = getRadioButtonsByName(radioButtonInput.getNameAttribute());
771
772 for (final HtmlRadioButtonInput input : radios) {
773 input.setCheckedInternal(input == radioButtonInput);
774 }
775 }
776
777
778
779
780
781
782
783
784 public HtmlRadioButtonInput getCheckedRadioButton(final String name) {
785 WebAssert.notNull("name", name);
786
787 for (final HtmlRadioButtonInput input : getRadioButtonsByName(name)) {
788 if (input.isChecked()) {
789 return input;
790 }
791 }
792 return null;
793 }
794
795
796
797
798
799
800
801
802 public final String getActionAttribute() {
803 return getAttributeDirect("action");
804 }
805
806
807
808
809
810
811
812
813 public final void setActionAttribute(final String action) {
814 setAttribute("action", action);
815 }
816
817
818
819
820
821
822
823
824 public final String getMethodAttribute() {
825 return getAttributeDirect("method");
826 }
827
828
829
830
831
832
833
834
835 public final void setMethodAttribute(final String method) {
836 setAttribute("method", method);
837 }
838
839
840
841
842
843
844
845
846 public final String getNameAttribute() {
847 return getAttributeDirect(NAME_ATTRIBUTE);
848 }
849
850
851
852
853
854
855
856
857 public final void setNameAttribute(final String name) {
858 setAttribute(NAME_ATTRIBUTE, name);
859 }
860
861
862
863
864
865
866
867
868
869 public final String getEnctypeAttribute() {
870 return getAttributeDirect("enctype");
871 }
872
873
874
875
876
877
878
879
880
881 public final void setEnctypeAttribute(final String encoding) {
882 setAttribute("enctype", encoding);
883 }
884
885
886
887
888
889
890
891
892 public final String getOnSubmitAttribute() {
893 return getAttributeDirect("onsubmit");
894 }
895
896
897
898
899
900
901
902
903 public final String getOnResetAttribute() {
904 return getAttributeDirect("onreset");
905 }
906
907
908
909
910
911
912
913
914 public final String getAcceptAttribute() {
915 return getAttribute(HttpHeader.ACCEPT_LC);
916 }
917
918
919
920
921
922
923
924
925 public final String getAcceptCharsetAttribute() {
926 return getAttribute("accept-charset");
927 }
928
929
930
931
932
933
934
935
936 public final String getTargetAttribute() {
937 return getAttributeDirect("target");
938 }
939
940
941
942
943
944
945
946
947 public final void setTargetAttribute(final String target) {
948 setAttribute("target", target);
949 }
950
951
952
953
954
955
956
957
958 public final String getRelAttribute() {
959 return getAttributeDirect("rel");
960 }
961
962
963
964
965
966
967
968
969 @SuppressWarnings("unchecked")
970 public <I extends HtmlInput> I getInputByValue(final String value) throws ElementNotFoundException {
971 final List<HtmlInput> list = getInputsByValue(value);
972 if (list.isEmpty()) {
973 throw new ElementNotFoundException(HtmlInput.TAG_NAME, VALUE_ATTRIBUTE, value);
974 }
975 return (I) list.get(0);
976 }
977
978
979
980
981
982
983 public List<HtmlInput> getInputsByValue(final String value) {
984 final List<HtmlInput> results = new ArrayList<>();
985
986 for (final HtmlElement element : getElements(htmlElement -> htmlElement instanceof HtmlInput)) {
987 if (Objects.equals(((HtmlInput) element).getValue(), value)) {
988 results.add((HtmlInput) element);
989 }
990 }
991
992 return results;
993 }
994
995
996
997
998 @Override
999 protected void preventDefault() {
1000 isPreventDefault_ = true;
1001 }
1002
1003
1004
1005
1006 @Override
1007 protected boolean isEmptyXmlTagExpanded() {
1008 return true;
1009 }
1010
1011
1012
1013
1014 public final boolean isNoValidate() {
1015 return hasAttribute(ATTRIBUTE_NOVALIDATE);
1016 }
1017
1018
1019
1020
1021
1022
1023 public final void setNoValidate(final boolean noValidate) {
1024 if (noValidate) {
1025 setAttribute(ATTRIBUTE_NOVALIDATE, ATTRIBUTE_NOVALIDATE);
1026 }
1027 else {
1028 removeAttribute(ATTRIBUTE_NOVALIDATE);
1029 }
1030 }
1031 }