Skip to content

Commit c997b87

Browse files
committed
Accessing form elements by id (e.g. myForm.elementId) searches only form elements and not arbitrary descendants
1 parent 01a643b commit c997b87

File tree

4 files changed

+42
-31
lines changed

4 files changed

+42
-31
lines changed

src/changes/changes.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
<action type="update" dev="rbri">
2121
Upgrade Apache commons-io to 2.14.0.
2222
</action>
23+
<action type="fix" dev="rbri">
24+
Accessing form elements by id (e.g. myForm.elementId) searches only form elements and not
25+
arbitrary descendants.
26+
</action>
2327
<action type="fix" dev="rbri">
2428
Form elements are all elements that belong to a form; not only the child elements. We now
2529
take care of elements that use the form attribute to specify the associated form in many more places.

src/main/java/org/htmlunit/html/HtmlForm.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ private <E extends HtmlElement> List<E> getFormElementsByAttribute(
564564
/**
565565
* <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
566566
*
567-
* @return returns a list of all form controls contained in the <form> element or referenced by formId
567+
* @return returns a list of all form controls contained in the &lt;form&gt; element or referenced by formId
568568
* but ignoring elements that are contained in a nested form
569569
*/
570570
public List<HtmlElement> getElements() {
@@ -577,14 +577,6 @@ public List<HtmlElement> getElements() {
577577
}
578578
}
579579

580-
for (final HtmlElement element : lostChildren_) {
581-
if (SUBMITTABLE_ELEMENT_NAMES.contains(element.getTagName())
582-
&& element.getEnclosingForm() == this
583-
&& !elements.contains(element)) {
584-
elements.add(element);
585-
}
586-
}
587-
588580
return elements;
589581
}
590582

@@ -711,7 +703,7 @@ public List<HtmlRadioButtonInput> getRadioButtonsByName(final String name) {
711703
* @param radioButtonInput the radio button to select
712704
*/
713705
void setCheckedRadioButton(final HtmlRadioButtonInput radioButtonInput) {
714-
if (radioButtonInput.getEnclosingForm() == null && !lostChildren_.contains(radioButtonInput)) {
706+
if (radioButtonInput.getEnclosingForm() == null) {
715707
throw new IllegalArgumentException("HtmlRadioButtonInput is not child of this HtmlForm");
716708
}
717709
final List<HtmlRadioButtonInput> radios = getRadioButtonsByName(radioButtonInput.getNameAttribute());

src/main/java/org/htmlunit/javascript/host/html/HTMLFormElement.java

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,11 @@ List<HtmlElement> findElements(final String name) {
487487
return elements;
488488
}
489489

490-
addElements(name, form.getHtmlElementDescendants(), elements);
491-
addElements(name, form.getLostChildren(), elements);
490+
for (final HtmlElement element : form.getElements()) {
491+
if (isAccessibleByIdOrName(element, name)) {
492+
elements.add(element);
493+
}
494+
}
492495

493496
// If no form fields are found, browsers are able to find img elements by ID or name.
494497
if (elements.isEmpty()) {
@@ -505,28 +508,13 @@ List<HtmlElement> findElements(final String name) {
505508
return elements;
506509
}
507510

508-
private void addElements(final String name, final Iterable<HtmlElement> nodes,
509-
final List<HtmlElement> addTo) {
510-
for (final HtmlElement node : nodes) {
511-
if (isAccessibleByIdOrName(node, name)) {
512-
addTo.add(node);
513-
}
514-
}
515-
}
516-
517511
private HtmlElement findFirstElement(final String name) {
518512
final HtmlForm form = (HtmlForm) getDomNodeOrNull();
519513
if (form == null) {
520514
return null;
521515
}
522516

523-
for (final HtmlElement node : form.getHtmlElementDescendants()) {
524-
if (isAccessibleByIdOrName(node, name)) {
525-
return node;
526-
}
527-
}
528-
529-
for (final HtmlElement node : form.getLostChildren()) {
517+
for (final HtmlElement node : form.getElements()) {
530518
if (isAccessibleByIdOrName(node, name)) {
531519
return node;
532520
}

src/test/java/org/htmlunit/javascript/host/html/HTMLFormElementTest.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -943,14 +943,15 @@ private void fieldNamedSubmit(final String htmlSnippet, final String expected) t
943943
* @throws Exception if the test fails
944944
*/
945945
@Test
946-
@Alerts({"before", "2"})
947-
public void fieldFoundWithID() throws Exception {
946+
@Alerts({"before", "2", "undefined"})
947+
public void fieldFoundWithId() throws Exception {
948948
final String html = "<html><head>\n"
949949
+ "<script>\n"
950950
+ LOG_TITLE_FUNCTION
951951
+ "function test() {\n"
952952
+ " log(IRForm.IRText.value);\n"
953953
+ " log(IRForm.myField.length);\n"
954+
+ " log(IRForm.myDiv);\n"
954955
+ "}\n"
955956
+ "</script>\n"
956957
+ "</head>\n"
@@ -961,11 +962,37 @@ public void fieldFoundWithID() throws Exception {
961962
+ " <input type='image' id='myField' src='foo.gif'/>\n"
962963
+ " <input type='text' name='myField'/>\n"
963964
+ " <input type='text' id='myField'/>\n"
965+
+ " <div id='myDiv'>oooo</div>\n"
964966
+ " </form>\n"
965967
+ "</body>\n"
966968
+ "</html>";
967969

968-
getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
970+
loadPageVerifyTitle2(html);
971+
}
972+
973+
/**
974+
* @throws Exception if the test fails
975+
*/
976+
@Test
977+
@Alerts(DEFAULT = {"[object HTMLInputElement]", "[object HTMLInputElement]"},
978+
IE = {"undefined", "undefined"})
979+
public void fieldFoundWithIdByReference() throws Exception {
980+
final String html = "<html><head>\n"
981+
+ "<script>\n"
982+
+ LOG_TITLE_FUNCTION
983+
+ "function test() {\n"
984+
+ " log(IRForm.IRText);\n"
985+
+ " log(IRForm.myField);\n"
986+
+ "}\n"
987+
+ "</script>\n"
988+
+ "</head>\n"
989+
+ "<body onload='test()'>\n"
990+
+ " <form name='IRForm' id='testForm' action='#'>\n"
991+
+ " </form>\n"
992+
+ " <input type='text' id='IRText' value='abc' form='testForm' />\n"
993+
+ " <input type='text' id='myField' value='xy' form='testForm'/>\n"
994+
+ "</body>\n"
995+
+ "</html>";
969996

970997
loadPageVerifyTitle2(html);
971998
}

0 commit comments

Comments
 (0)