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