1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.html;
16
17 import org.htmlunit.SgmlPage;
18 import org.htmlunit.WebAssert;
19 import org.htmlunit.corejs.javascript.Context;
20 import org.htmlunit.corejs.javascript.Scriptable;
21 import org.htmlunit.corejs.javascript.ScriptableObject;
22 import org.htmlunit.html.ElementFactory;
23 import org.htmlunit.html.HtmlOption;
24 import org.htmlunit.html.HtmlSelect;
25 import org.htmlunit.javascript.HtmlUnitScriptable;
26 import org.htmlunit.javascript.JavaScriptEngine;
27 import org.htmlunit.javascript.configuration.JsxClass;
28 import org.htmlunit.javascript.configuration.JsxConstructor;
29 import org.htmlunit.javascript.configuration.JsxFunction;
30 import org.htmlunit.javascript.configuration.JsxGetter;
31 import org.htmlunit.javascript.configuration.JsxSetter;
32 import org.htmlunit.javascript.configuration.JsxSymbol;
33 import org.htmlunit.javascript.host.dom.DOMException;
34
35
36
37
38
39
40
41
42
43
44
45
46 @JsxClass
47 public class HTMLOptionsCollection extends HtmlUnitScriptable {
48
49 private HtmlSelect htmlSelect_;
50
51
52
53
54 public HTMLOptionsCollection() {
55 super();
56 }
57
58
59
60
61 @JsxConstructor
62 public void jsConstructor() {
63
64 }
65
66
67
68
69
70 public HTMLOptionsCollection(final HtmlUnitScriptable parentScope) {
71 super();
72 setParentScope(parentScope);
73 setPrototype(getPrototype(getClass()));
74 }
75
76
77
78
79
80 public void initialize(final HtmlSelect select) {
81 WebAssert.notNull("select", select);
82 htmlSelect_ = select;
83 }
84
85
86
87
88
89
90
91
92 @Override
93 public Object get(final int index, final Scriptable start) {
94 if (htmlSelect_ == null || index < 0) {
95 return JavaScriptEngine.UNDEFINED;
96 }
97
98 if (index >= htmlSelect_.getOptionSize()) {
99 return JavaScriptEngine.UNDEFINED;
100 }
101
102 return getScriptableFor(htmlSelect_.getOption(index));
103 }
104
105
106
107
108 @Override
109 public void put(final String name, final Scriptable start, final Object value) {
110 if (htmlSelect_ == null) {
111
112
113 super.put(name, start, value);
114 return;
115 }
116
117 final HTMLSelectElement parent = htmlSelect_.getScriptableObject();
118
119 if (!has(name, start) && ScriptableObject.hasProperty(parent, name)) {
120 ScriptableObject.putProperty(parent, name, value);
121 }
122 else {
123 super.put(name, start, value);
124 }
125 }
126
127
128
129
130
131
132
133 @JsxFunction
134 public Object item(final int index) {
135 final Object item = get(index, this);
136 if (JavaScriptEngine.UNDEFINED == item) {
137 return null;
138 }
139 return item;
140 }
141
142
143
144
145
146
147
148 @Override
149 public void put(final int index, final Scriptable start, final Object newValue) {
150 if (newValue == null) {
151
152 htmlSelect_.removeOption(index);
153 }
154 else {
155 final HTMLOptionElement option = (HTMLOptionElement) newValue;
156 final HtmlOption htmlOption = (HtmlOption) option.getDomNodeOrNull();
157 if (index >= getLength()) {
158 setLength(index);
159
160 htmlSelect_.appendOption(htmlOption);
161 }
162 else {
163
164 htmlSelect_.replaceOption(index, htmlOption);
165 }
166 }
167 }
168
169
170
171
172
173
174 @JsxGetter
175 public int getLength() {
176 return htmlSelect_.getOptionSize();
177 }
178
179
180
181
182
183
184
185 @JsxSetter
186 public void setLength(final int newLength) {
187 if (newLength < 0) {
188 return;
189 }
190
191 final int currentLength = htmlSelect_.getOptionSize();
192 if (currentLength > newLength) {
193 htmlSelect_.setOptionSize(newLength);
194 }
195 else {
196 final SgmlPage page = htmlSelect_.getPage();
197 final ElementFactory factory = page.getWebClient().getPageCreator()
198 .getHtmlParser().getFactory(HtmlOption.TAG_NAME);
199 for (int i = currentLength; i < newLength; i++) {
200 final HtmlOption option = (HtmlOption) factory.createElement(page, HtmlOption.TAG_NAME, null);
201 htmlSelect_.appendOption(option);
202 }
203 }
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 @JsxFunction
242 public void add(final Object newOptionObject, final Object beforeOptionObject) {
243 final HtmlOption htmlOption = (HtmlOption) ((HTMLOptionElement) newOptionObject).getDomNodeOrNull();
244
245 HtmlOption beforeOption = null;
246
247 if (beforeOptionObject instanceof Number) {
248 final int index = ((Integer) Context.jsToJava(beforeOptionObject, Integer.class)).intValue();
249 if (index < 0 || index >= getLength()) {
250
251 htmlSelect_.appendOption(htmlOption);
252 return;
253 }
254
255 beforeOption = (HtmlOption) ((HTMLOptionElement) item(index)).getDomNodeOrDie();
256 }
257 else if (beforeOptionObject instanceof HTMLOptionElement) {
258 beforeOption = (HtmlOption) ((HTMLOptionElement) beforeOptionObject).getDomNodeOrDie();
259 if (beforeOption.getParentNode() != htmlSelect_) {
260 throw JavaScriptEngine.asJavaScriptException(
261 getWindow(),
262 "Unknown option.",
263 DOMException.NOT_FOUND_ERR);
264
265 }
266 }
267
268 if (null == beforeOption) {
269 htmlSelect_.appendOption(htmlOption);
270 return;
271 }
272
273 beforeOption.insertBefore(htmlOption);
274 }
275
276
277
278
279
280 @JsxFunction
281 public void remove(final int index) {
282 int idx = index;
283 if (idx < 0) {
284 return;
285 }
286
287 idx = Math.max(idx, 0);
288 if (idx >= getLength()) {
289 return;
290 }
291
292 htmlSelect_.removeOption(idx);
293 }
294
295
296
297
298
299 @JsxGetter
300 public int getSelectedIndex() {
301 return htmlSelect_.getSelectedIndex();
302 }
303
304
305
306
307
308 @JsxSetter
309 public void setSelectedIndex(final int index) {
310 htmlSelect_.setSelectedIndex(index);
311 }
312
313
314
315
316 @JsxSymbol
317 public Scriptable iterator() {
318 return JavaScriptEngine.newArrayIteratorTypeValues(getParentScope(), this);
319 }
320 }