View Javadoc
1   /*
2    * Copyright (c) 2002-2026 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.host.dom;
16  
17  import org.htmlunit.corejs.javascript.Scriptable;
18  import org.htmlunit.html.DomNode;
19  import org.htmlunit.html.HtmlRadioButtonInput;
20  import org.htmlunit.javascript.JavaScriptEngine;
21  import org.htmlunit.javascript.configuration.JsxClass;
22  import org.htmlunit.javascript.configuration.JsxConstructor;
23  import org.htmlunit.javascript.configuration.JsxGetter;
24  import org.htmlunit.javascript.configuration.JsxSetter;
25  import org.htmlunit.javascript.configuration.JsxSymbol;
26  
27  import java.util.List;
28  
29  import static org.htmlunit.html.DomElement.ATTRIBUTE_NOT_DEFINED;
30  
31  /**
32   * A JavaScript object for {@code RadioNodeList}.
33   *
34   * @author Ahmed Ashour
35   * @author Ronald Brill
36   * @author Lai Quang Duong
37   *
38   * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/RadioNodeList">MDN Documentation</a>
39   */
40  @JsxClass
41  public class RadioNodeList extends NodeList {
42  
43      /**
44       * Creates an instance.
45       */
46      public RadioNodeList() {
47          super();
48      }
49  
50      /**
51       * Creates an instance.
52       *
53       * @param domNode the {@link DomNode}
54       */
55      public RadioNodeList(final DomNode domNode) {
56          super(domNode, true);
57      }
58  
59      /**
60       * Creates an instance.
61       *
62       * @param domNode the {@link DomNode}
63       * @param attributeChangeSensitive indicates if the content of the collection may change when an attribute
64       *        of a descendant node of domNode changes (attribute added, modified or removed)
65       */
66      public RadioNodeList(final DomNode domNode, final boolean attributeChangeSensitive) {
67          super(domNode, attributeChangeSensitive);
68      }
69  
70      /**
71       * Constructs an instance with an initial cache value.
72       * @param domNode the parent scope, on which we listen for changes
73       * @param initialElements the initial content for the cache
74       */
75      public RadioNodeList(final DomNode domNode, final List<DomNode> initialElements) {
76          super(domNode, initialElements);
77      }
78  
79      /**
80       * JavaScript constructor.
81       */
82      @Override
83      @JsxConstructor
84      public void jsConstructor() {
85          super.jsConstructor();
86      }
87  
88      /**
89       * Returns the value of the first checked radio button represented by radioNodeList.
90       * @return the value of the first checked radio button represented by radioNodeList ("on" if value attribute
91       *         is not defined) or an empty string if no radio button is checked.
92       * @see <a href="https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#the-htmlformcontrolscollection-interface">HTML Standard</a>
93       */
94      @JsxGetter
95      public String getValue() {
96          for (final DomNode node : getElements()) {
97              if (node instanceof HtmlRadioButtonInput input && input.isChecked()) {
98                  final String value = input.getValueAttribute();
99                  return value == ATTRIBUTE_NOT_DEFINED ? "on" : value;
100             }
101         }
102 
103         return "";
104     }
105 
106     /**
107      * Checks the first radio button represented by radioNodeList that has value equal the specified value.
108      * @param newValue the value of the radio button to be checked.
109      * @see <a href="https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#the-htmlformcontrolscollection-interface">HTML Standard</a>
110      */
111     @JsxSetter
112     public void setValue(final String newValue) {
113         for (final DomNode node : getElements()) {
114             if (node instanceof HtmlRadioButtonInput input) {
115                 String value = input.getValueAttribute();
116                 if (value == ATTRIBUTE_NOT_DEFINED) {
117                     value = "on";
118                 }
119                 if (newValue.equals(value)) {
120                     input.setChecked(true);
121                     break;
122                 }
123             }
124         }
125     }
126 
127     /**
128      * Returns the {@code Symbol.iterator} function that allows iterating over this collection.
129      * @return the Iterator symbol
130      */
131     @JsxSymbol
132     public Scriptable iterator() {
133         return JavaScriptEngine.newArrayIteratorTypeValues(getParentScope(), this);
134     }
135 }