happy-dom 7.5.10 → 7.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of happy-dom might be problematic. Click here for more details.
- package/lib/nodes/element/Element.d.ts +1 -13
- package/lib/nodes/element/Element.js +0 -12
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/html-option-element/HTMLOptionElement.js +2 -2
- package/lib/nodes/html-option-element/HTMLOptionElement.js.map +1 -1
- package/lib/nodes/html-option-element/HTMLOptionsCollection.d.ts +11 -5
- package/lib/nodes/html-option-element/HTMLOptionsCollection.js +29 -15
- package/lib/nodes/html-option-element/HTMLOptionsCollection.js.map +1 -1
- package/lib/nodes/html-option-element/IHTMLOptionsCollection.d.ts +6 -0
- package/lib/nodes/html-select-element/HTMLSelectElement.d.ts +58 -8
- package/lib/nodes/html-select-element/HTMLSelectElement.js +142 -23
- package/lib/nodes/html-select-element/HTMLSelectElement.js.map +1 -1
- package/lib/nodes/html-select-element/IHTMLSelectElement.d.ts +26 -4
- package/lib/nodes/node/Node.d.ts +1 -1
- package/lib/nodes/node/Node.js +1 -1
- package/package.json +2 -2
- package/src/nodes/element/Element.ts +3 -15
- package/src/nodes/html-option-element/HTMLOptionElement.ts +3 -2
- package/src/nodes/html-option-element/HTMLOptionsCollection.ts +39 -19
- package/src/nodes/html-option-element/IHTMLOptionsCollection.ts +7 -0
- package/src/nodes/html-select-element/HTMLSelectElement.ts +178 -28
- package/src/nodes/html-select-element/IHTMLSelectElement.ts +32 -4
- package/src/nodes/node/Node.ts +1 -1
- package/lib/nodes/html-option-element/HTMLOptionElementValueSanitizer.d.ts +0 -11
- package/lib/nodes/html-option-element/HTMLOptionElementValueSanitizer.js +0 -18
- package/lib/nodes/html-option-element/HTMLOptionElementValueSanitizer.js.map +0 -1
- package/lib/nodes/html-select-element/HTMLSelectElementValueSanitizer.d.ts +0 -11
- package/lib/nodes/html-select-element/HTMLSelectElementValueSanitizer.js +0 -18
- package/lib/nodes/html-select-element/HTMLSelectElementValueSanitizer.js.map +0 -1
- package/src/nodes/html-option-element/HTMLOptionElementValueSanitizer.ts +0 -15
- package/src/nodes/html-select-element/HTMLSelectElementValueSanitizer.ts +0 -15
@@ -7,8 +7,9 @@ const DOMException_1 = __importDefault(require("../../exception/DOMException"));
|
|
7
7
|
const DOMExceptionNameEnum_1 = __importDefault(require("../../exception/DOMExceptionNameEnum"));
|
8
8
|
const HTMLElement_1 = __importDefault(require("../html-element/HTMLElement"));
|
9
9
|
const ValidityState_1 = __importDefault(require("../validity-state/ValidityState"));
|
10
|
+
const HTMLOptionElement_1 = __importDefault(require("../html-option-element/HTMLOptionElement"));
|
10
11
|
const HTMLOptionsCollection_1 = __importDefault(require("../html-option-element/HTMLOptionsCollection"));
|
11
|
-
const
|
12
|
+
const NodeTypeEnum_1 = __importDefault(require("../node/NodeTypeEnum"));
|
12
13
|
/**
|
13
14
|
* HTML Select Element.
|
14
15
|
*
|
@@ -18,12 +19,10 @@ const HTMLSelectElementValueSanitizer_1 = __importDefault(require("./HTMLSelectE
|
|
18
19
|
class HTMLSelectElement extends HTMLElement_1.default {
|
19
20
|
constructor() {
|
20
21
|
super(...arguments);
|
22
|
+
this.options = new HTMLOptionsCollection_1.default(this);
|
21
23
|
// Events
|
22
24
|
this.onchange = null;
|
23
25
|
this.oninput = null;
|
24
|
-
this._value = null;
|
25
|
-
this._selectedIndex = -1;
|
26
|
-
this._options = null;
|
27
26
|
}
|
28
27
|
/**
|
29
28
|
* Returns name.
|
@@ -104,6 +103,22 @@ class HTMLSelectElement extends HTMLElement_1.default {
|
|
104
103
|
this.setAttributeNS(null, 'autofocus', '');
|
105
104
|
}
|
106
105
|
}
|
106
|
+
/**
|
107
|
+
* Returns length.
|
108
|
+
*
|
109
|
+
* @returns length.
|
110
|
+
*/
|
111
|
+
get length() {
|
112
|
+
return this.options.length;
|
113
|
+
}
|
114
|
+
/**
|
115
|
+
* Sets length.
|
116
|
+
*
|
117
|
+
* @param length Length.
|
118
|
+
*/
|
119
|
+
set length(length) {
|
120
|
+
this.options.length = length;
|
121
|
+
}
|
107
122
|
/**
|
108
123
|
* Returns required.
|
109
124
|
*
|
@@ -125,13 +140,25 @@ class HTMLSelectElement extends HTMLElement_1.default {
|
|
125
140
|
this.setAttributeNS(null, 'required', '');
|
126
141
|
}
|
127
142
|
}
|
143
|
+
/**
|
144
|
+
* Returns type.
|
145
|
+
*
|
146
|
+
* @returns type.
|
147
|
+
*/
|
148
|
+
get type() {
|
149
|
+
return this.hasAttributeNS(null, 'multiple') ? 'select-multiple' : 'select-one';
|
150
|
+
}
|
128
151
|
/**
|
129
152
|
* Returns value.
|
130
153
|
*
|
131
154
|
* @returns Value.
|
132
155
|
*/
|
133
156
|
get value() {
|
134
|
-
|
157
|
+
if (this.options.selectedIndex === -1) {
|
158
|
+
return '';
|
159
|
+
}
|
160
|
+
const option = this.options[this.options.selectedIndex];
|
161
|
+
return option instanceof HTMLOptionElement_1.default ? option.value : '';
|
135
162
|
}
|
136
163
|
/**
|
137
164
|
* Sets value.
|
@@ -139,11 +166,7 @@ class HTMLSelectElement extends HTMLElement_1.default {
|
|
139
166
|
* @param value Value.
|
140
167
|
*/
|
141
168
|
set value(value) {
|
142
|
-
this.
|
143
|
-
const idx = this.options.findIndex((o) => o.nodeValue === value);
|
144
|
-
if (idx > -1) {
|
145
|
-
this._selectedIndex = idx;
|
146
|
-
}
|
169
|
+
this.options.selectedIndex = this.options.findIndex((o) => o instanceof HTMLOptionElement_1.default && o.value === value);
|
147
170
|
}
|
148
171
|
/**
|
149
172
|
* Returns value.
|
@@ -151,7 +174,7 @@ class HTMLSelectElement extends HTMLElement_1.default {
|
|
151
174
|
* @returns Value.
|
152
175
|
*/
|
153
176
|
get selectedIndex() {
|
154
|
-
return this.
|
177
|
+
return this.options.selectedIndex;
|
155
178
|
}
|
156
179
|
/**
|
157
180
|
* Sets value.
|
@@ -159,10 +182,10 @@ class HTMLSelectElement extends HTMLElement_1.default {
|
|
159
182
|
* @param value Value.
|
160
183
|
*/
|
161
184
|
set selectedIndex(value) {
|
162
|
-
if (value > this.options.length - 1 || value <
|
185
|
+
if (value > this.options.length - 1 || value < -1) {
|
163
186
|
throw new DOMException_1.default('Select elements selected index must be valid', DOMExceptionNameEnum_1.default.indexSizeError);
|
164
187
|
}
|
165
|
-
this.
|
188
|
+
this.options.selectedIndex = value;
|
166
189
|
}
|
167
190
|
/**
|
168
191
|
* Returns the parent form element.
|
@@ -197,21 +220,117 @@ class HTMLSelectElement extends HTMLElement_1.default {
|
|
197
220
|
!this['readOnly']);
|
198
221
|
}
|
199
222
|
/**
|
200
|
-
* Returns options.
|
223
|
+
* Returns item from options collection by index.
|
224
|
+
*
|
225
|
+
* @param index Index.
|
226
|
+
*/
|
227
|
+
item(index) {
|
228
|
+
return this.options.item(index);
|
229
|
+
}
|
230
|
+
/**
|
231
|
+
* Adds new option to options collection.
|
232
|
+
*
|
233
|
+
* @param element HTMLOptionElement or HTMLOptGroupElement to add.
|
234
|
+
* @param before HTMLOptionElement or index number.
|
235
|
+
*/
|
236
|
+
add(element, before) {
|
237
|
+
this.options.add(element, before);
|
238
|
+
}
|
239
|
+
/**
|
240
|
+
* Removes indexed element from collection or the select element.
|
201
241
|
*
|
202
|
-
* @
|
242
|
+
* @param [index] Index.
|
203
243
|
*/
|
204
|
-
|
205
|
-
if (
|
206
|
-
this.
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
244
|
+
remove(index) {
|
245
|
+
if (typeof index === 'number') {
|
246
|
+
this.options.remove(index);
|
247
|
+
}
|
248
|
+
else {
|
249
|
+
super.remove();
|
250
|
+
}
|
251
|
+
}
|
252
|
+
/**
|
253
|
+
* @override
|
254
|
+
*/
|
255
|
+
appendChild(node) {
|
256
|
+
if (node.nodeType === NodeTypeEnum_1.default.elementNode) {
|
257
|
+
const element = node;
|
258
|
+
const previousLength = this.options.length;
|
259
|
+
if (element.tagName === 'OPTION' || element.tagName === 'OPTGROUP') {
|
260
|
+
this.options.push(element);
|
261
|
+
}
|
262
|
+
this._updateIndexProperties(previousLength, this.options.length);
|
263
|
+
}
|
264
|
+
return super.appendChild(node);
|
265
|
+
}
|
266
|
+
/**
|
267
|
+
* @override
|
268
|
+
*/
|
269
|
+
insertBefore(newNode, referenceNode) {
|
270
|
+
const returnValue = super.insertBefore(newNode, referenceNode);
|
271
|
+
if (newNode.nodeType === NodeTypeEnum_1.default.elementNode &&
|
272
|
+
referenceNode?.nodeType === NodeTypeEnum_1.default.elementNode) {
|
273
|
+
const newElement = newNode;
|
274
|
+
const previousLength = this.options.length;
|
275
|
+
if (newElement.tagName === 'OPTION' || newElement.tagName === 'OPTGROUP') {
|
276
|
+
const referenceElement = referenceNode;
|
277
|
+
if (referenceElement &&
|
278
|
+
(referenceElement.tagName === 'OPTION' || referenceElement.tagName === 'OPTGROUP')) {
|
279
|
+
const referenceIndex = this.options.indexOf(referenceElement);
|
280
|
+
if (referenceIndex !== -1) {
|
281
|
+
this.options.splice(referenceIndex, 0, newElement);
|
282
|
+
}
|
283
|
+
}
|
284
|
+
else {
|
285
|
+
this.options.push(newElement);
|
286
|
+
}
|
287
|
+
}
|
288
|
+
this._updateIndexProperties(previousLength, this.options.length);
|
289
|
+
}
|
290
|
+
return returnValue;
|
291
|
+
}
|
292
|
+
/**
|
293
|
+
* @override
|
294
|
+
*/
|
295
|
+
removeChild(node) {
|
296
|
+
if (node.nodeType === NodeTypeEnum_1.default.elementNode) {
|
297
|
+
const element = node;
|
298
|
+
const previousLength = this.options.length;
|
299
|
+
if (element.tagName === 'OPTION' || element.tagName === 'OPTION') {
|
300
|
+
const index = this.options.indexOf(node);
|
301
|
+
if (index !== -1) {
|
302
|
+
this.options.splice(index, 1);
|
303
|
+
}
|
304
|
+
}
|
305
|
+
this._updateIndexProperties(previousLength, this.options.length);
|
306
|
+
}
|
307
|
+
return super.removeChild(node);
|
308
|
+
}
|
309
|
+
/**
|
310
|
+
* Updates index properties.
|
311
|
+
*
|
312
|
+
* @param previousLength Length before the update.
|
313
|
+
* @param newLength Length after the update.
|
314
|
+
*/
|
315
|
+
_updateIndexProperties(previousLength, newLength) {
|
316
|
+
if (previousLength > newLength) {
|
317
|
+
for (let i = newLength; i < previousLength; i++) {
|
318
|
+
if (this.hasOwnProperty(String(i))) {
|
319
|
+
delete this[String(i)];
|
211
320
|
}
|
212
321
|
}
|
213
322
|
}
|
214
|
-
|
323
|
+
else if (previousLength < newLength) {
|
324
|
+
for (let i = previousLength; i < newLength; i++) {
|
325
|
+
Object.defineProperty(this, String(i), {
|
326
|
+
get: () => {
|
327
|
+
return this.options[i];
|
328
|
+
},
|
329
|
+
enumerable: true,
|
330
|
+
configurable: true
|
331
|
+
});
|
332
|
+
}
|
333
|
+
}
|
215
334
|
}
|
216
335
|
}
|
217
336
|
exports.default = HTMLSelectElement;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"HTMLSelectElement.js","sourceRoot":"","sources":["../../../src/nodes/html-select-element/HTMLSelectElement.ts"],"names":[],"mappings":";;;;;AAAA,gFAAwD;AACxD,gGAAwE;AACxE,8EAAsD;AAGtD,oFAA4D;
|
1
|
+
{"version":3,"file":"HTMLSelectElement.js","sourceRoot":"","sources":["../../../src/nodes/html-select-element/HTMLSelectElement.ts"],"names":[],"mappings":"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"}
|
@@ -5,6 +5,8 @@ import INodeList from '../node/INodeList';
|
|
5
5
|
import IHTMLOptionsCollection from '../html-option-element/IHTMLOptionsCollection';
|
6
6
|
import ValidityState from '../validity-state/ValidityState';
|
7
7
|
import Event from '../../event/Event';
|
8
|
+
import IHTMLOptionElement from '../html-option-element/IHTMLOptionElement';
|
9
|
+
import IHTMLOptGroupElement from '../html-opt-group-element/IHTMLOptGroupElement';
|
8
10
|
/**
|
9
11
|
* HTML Select Element.
|
10
12
|
*
|
@@ -14,16 +16,36 @@ import Event from '../../event/Event';
|
|
14
16
|
export default interface IHTMLSelectElement extends IHTMLElement {
|
15
17
|
readonly form: IHTMLFormElement;
|
16
18
|
readonly labels: INodeList<IHTMLLabelElement>;
|
17
|
-
|
19
|
+
readonly options: IHTMLOptionsCollection;
|
20
|
+
readonly type: string;
|
21
|
+
readonly validity: ValidityState;
|
22
|
+
readonly willValidate: boolean;
|
18
23
|
autofocus: boolean;
|
19
24
|
disabled: boolean;
|
20
|
-
|
25
|
+
length: number;
|
21
26
|
selectedIndex: number;
|
22
|
-
validity: ValidityState;
|
23
27
|
value: string;
|
24
|
-
willValidate: boolean;
|
25
28
|
name: string;
|
26
29
|
multiple: boolean;
|
27
30
|
onchange: (event: Event) => void | null;
|
28
31
|
oninput: (event: Event) => void | null;
|
32
|
+
/**
|
33
|
+
* Adds new option to collection.
|
34
|
+
*
|
35
|
+
* @param element HTMLOptionElement or HTMLOptGroupElement to add.
|
36
|
+
* @param before HTMLOptionElement or index number.
|
37
|
+
*/
|
38
|
+
add(element: IHTMLOptionElement | IHTMLOptGroupElement, before?: number | IHTMLOptionElement | IHTMLOptGroupElement): void;
|
39
|
+
/**
|
40
|
+
* Returns option element by index.
|
41
|
+
*
|
42
|
+
* @param index Index.
|
43
|
+
*/
|
44
|
+
item(index: number): IHTMLOptionElement | IHTMLOptGroupElement;
|
45
|
+
/**
|
46
|
+
* Removes option element from the collection.
|
47
|
+
*
|
48
|
+
* @param index Index.
|
49
|
+
*/
|
50
|
+
remove(index?: number): void;
|
29
51
|
}
|
package/lib/nodes/node/Node.d.ts
CHANGED
@@ -179,7 +179,7 @@ export default class Node extends EventTarget implements INode {
|
|
179
179
|
* Inserts a node before another.
|
180
180
|
*
|
181
181
|
* @param newNode Node to insert.
|
182
|
-
* @param
|
182
|
+
* @param referenceNode Node to insert before.
|
183
183
|
* @returns Inserted node.
|
184
184
|
*/
|
185
185
|
insertBefore(newNode: INode, referenceNode: INode | null): INode;
|
package/lib/nodes/node/Node.js
CHANGED
@@ -310,7 +310,7 @@ class Node extends EventTarget_1.default {
|
|
310
310
|
* Inserts a node before another.
|
311
311
|
*
|
312
312
|
* @param newNode Node to insert.
|
313
|
-
* @param
|
313
|
+
* @param referenceNode Node to insert before.
|
314
314
|
* @returns Inserted node.
|
315
315
|
*/
|
316
316
|
insertBefore(newNode, referenceNode) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "happy-dom",
|
3
|
-
"version": "7.5.
|
3
|
+
"version": "7.5.11",
|
4
4
|
"license": "MIT",
|
5
5
|
"homepage": "https://github.com/capricorn86/happy-dom",
|
6
6
|
"repository": "https://github.com/capricorn86/happy-dom",
|
@@ -75,5 +75,5 @@
|
|
75
75
|
"ts-jest": "^27.1.3",
|
76
76
|
"typescript": "^4.6.2"
|
77
77
|
},
|
78
|
-
"gitHead": "
|
78
|
+
"gitHead": "0bc3e37434cb2c78af887cecad60b3dff874b0c0"
|
79
79
|
}
|
@@ -365,13 +365,9 @@ export default class Element extends Node implements IElement {
|
|
365
365
|
}
|
366
366
|
|
367
367
|
/**
|
368
|
-
* Append a child node to childNodes.
|
369
|
-
*
|
370
368
|
* @override
|
371
|
-
* @param node Node to append.
|
372
|
-
* @returns Appended node.
|
373
369
|
*/
|
374
|
-
public appendChild(node: INode): INode {
|
370
|
+
public override appendChild(node: INode): INode {
|
375
371
|
// If the type is DocumentFragment, then the child nodes of if it should be moved instead of the actual node.
|
376
372
|
// See: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment
|
377
373
|
if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
|
@@ -391,12 +387,9 @@ export default class Element extends Node implements IElement {
|
|
391
387
|
}
|
392
388
|
|
393
389
|
/**
|
394
|
-
* Remove Child element from childNodes array.
|
395
|
-
*
|
396
390
|
* @override
|
397
|
-
* @param node Node to remove.
|
398
391
|
*/
|
399
|
-
public removeChild(node: INode): INode {
|
392
|
+
public override removeChild(node: INode): INode {
|
400
393
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
401
394
|
const index = this.children.indexOf(<IElement>node);
|
402
395
|
if (index !== -1) {
|
@@ -415,14 +408,9 @@ export default class Element extends Node implements IElement {
|
|
415
408
|
}
|
416
409
|
|
417
410
|
/**
|
418
|
-
* Inserts a node before another.
|
419
|
-
*
|
420
411
|
* @override
|
421
|
-
* @param newNode Node to insert.
|
422
|
-
* @param [referenceNode] Node to insert before.
|
423
|
-
* @returns Inserted node.
|
424
412
|
*/
|
425
|
-
public insertBefore(newNode: INode, referenceNode
|
413
|
+
public override insertBefore(newNode: INode, referenceNode: INode | null): INode {
|
426
414
|
const returnValue = super.insertBefore(newNode, referenceNode);
|
427
415
|
|
428
416
|
// If the type is DocumentFragment, then the child nodes of if it should be moved instead of the actual node.
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import HTMLElement from '../html-element/HTMLElement';
|
2
2
|
import IHTMLElement from '../html-element/IHTMLElement';
|
3
3
|
import IHTMLFormElement from '../html-form-element/IHTMLFormElement';
|
4
|
-
import HTMLOptionElementValueSanitizer from './HTMLOptionElementValueSanitizer';
|
5
4
|
import IHTMLOptionElement from './IHTMLOptionElement';
|
6
5
|
|
6
|
+
const NEW_LINES_REGEXP = /[\n\r]/gm;
|
7
|
+
|
7
8
|
/**
|
8
9
|
* HTML Option Element.
|
9
10
|
*
|
@@ -112,6 +113,6 @@ export default class HTMLOptionElement extends HTMLElement implements IHTMLOptio
|
|
112
113
|
* @param value Value.
|
113
114
|
*/
|
114
115
|
public set value(value: string) {
|
115
|
-
this.setAttributeNS(null, 'value',
|
116
|
+
this.setAttributeNS(null, 'value', String(value).trim().replace(NEW_LINES_REGEXP, ''));
|
116
117
|
}
|
117
118
|
}
|
@@ -1,7 +1,9 @@
|
|
1
1
|
import DOMException from '../../exception/DOMException';
|
2
2
|
import HTMLCollection from '../element/HTMLCollection';
|
3
|
-
import
|
3
|
+
import IHTMLOptGroupElement from '../html-opt-group-element/IHTMLOptGroupElement';
|
4
|
+
import IHTMLSelectElement from '../html-select-element/IHTMLSelectElement';
|
4
5
|
import HTMLOptionElement from './HTMLOptionElement';
|
6
|
+
import IHTMLOptionElement from './IHTMLOptionElement';
|
5
7
|
import IHTMLOptionsCollection from './IHTMLOptionsCollection';
|
6
8
|
|
7
9
|
/**
|
@@ -14,7 +16,17 @@ export default class HTMLOptionsCollection
|
|
14
16
|
extends HTMLCollection
|
15
17
|
implements IHTMLOptionsCollection
|
16
18
|
{
|
17
|
-
|
19
|
+
private _selectElement: IHTMLSelectElement;
|
20
|
+
|
21
|
+
/**
|
22
|
+
*
|
23
|
+
* @param selectElement
|
24
|
+
*/
|
25
|
+
constructor(selectElement: IHTMLSelectElement) {
|
26
|
+
super();
|
27
|
+
|
28
|
+
this._selectElement = selectElement;
|
29
|
+
}
|
18
30
|
|
19
31
|
/**
|
20
32
|
* Returns selectedIndex.
|
@@ -22,7 +34,14 @@ export default class HTMLOptionsCollection
|
|
22
34
|
* @returns SelectedIndex.
|
23
35
|
*/
|
24
36
|
public get selectedIndex(): number {
|
25
|
-
|
37
|
+
for (let i = 0; i < this.length; i++) {
|
38
|
+
const item = this[i];
|
39
|
+
if (item instanceof HTMLOptionElement && item.selected) {
|
40
|
+
return i;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
return -1;
|
26
45
|
}
|
27
46
|
|
28
47
|
/**
|
@@ -31,7 +50,12 @@ export default class HTMLOptionsCollection
|
|
31
50
|
* @param selectedIndex SelectedIndex.
|
32
51
|
*/
|
33
52
|
public set selectedIndex(selectedIndex: number) {
|
34
|
-
this.
|
53
|
+
for (let i = 0; i < this.length; i++) {
|
54
|
+
const item = this[i];
|
55
|
+
if (item instanceof HTMLOptionElement) {
|
56
|
+
this[i].selected = i === selectedIndex;
|
57
|
+
}
|
58
|
+
}
|
35
59
|
}
|
36
60
|
|
37
61
|
/**
|
@@ -39,7 +63,7 @@ export default class HTMLOptionsCollection
|
|
39
63
|
*
|
40
64
|
* @param index Index.
|
41
65
|
*/
|
42
|
-
public item(index: number):
|
66
|
+
public item(index: number): IHTMLOptionElement | IHTMLOptGroupElement {
|
43
67
|
return this[index];
|
44
68
|
}
|
45
69
|
|
@@ -49,11 +73,11 @@ export default class HTMLOptionsCollection
|
|
49
73
|
* @param before
|
50
74
|
*/
|
51
75
|
public add(
|
52
|
-
element:
|
53
|
-
before?: number |
|
76
|
+
element: IHTMLOptionElement | IHTMLOptGroupElement,
|
77
|
+
before?: number | IHTMLOptionElement | IHTMLOptGroupElement
|
54
78
|
): void {
|
55
79
|
if (!before && before !== 0) {
|
56
|
-
this.
|
80
|
+
this._selectElement.appendChild(element);
|
57
81
|
return;
|
58
82
|
}
|
59
83
|
|
@@ -62,18 +86,19 @@ export default class HTMLOptionsCollection
|
|
62
86
|
return;
|
63
87
|
}
|
64
88
|
|
65
|
-
this.
|
89
|
+
this._selectElement.insertBefore(element, this[<number>before]);
|
66
90
|
return;
|
67
91
|
}
|
68
92
|
|
69
|
-
const
|
70
|
-
|
93
|
+
const index = this.indexOf(before);
|
94
|
+
|
95
|
+
if (index === -1) {
|
71
96
|
throw new DOMException(
|
72
97
|
"Failed to execute 'add' on 'DOMException': The node before which the new node is to be inserted is not a child of this node."
|
73
98
|
);
|
74
99
|
}
|
75
100
|
|
76
|
-
this.
|
101
|
+
this._selectElement.insertBefore(element, this[index]);
|
77
102
|
}
|
78
103
|
|
79
104
|
/**
|
@@ -82,13 +107,8 @@ export default class HTMLOptionsCollection
|
|
82
107
|
* @param index Index.
|
83
108
|
*/
|
84
109
|
public remove(index: number): void {
|
85
|
-
this
|
86
|
-
|
87
|
-
if (this.length) {
|
88
|
-
this.selectedIndex = 0;
|
89
|
-
} else {
|
90
|
-
this.selectedIndex = -1;
|
91
|
-
}
|
110
|
+
if (this[index]) {
|
111
|
+
this._selectElement.removeChild(<IHTMLOptionElement>this[index]);
|
92
112
|
}
|
93
113
|
}
|
94
114
|
}
|
@@ -24,6 +24,13 @@ export default interface IHTMLOptionsCollection
|
|
24
24
|
before?: number | IHTMLOptionElement | IHTMLOptGroupElement
|
25
25
|
): void;
|
26
26
|
|
27
|
+
/**
|
28
|
+
* Returns option element by index.
|
29
|
+
*
|
30
|
+
* @param index Index.
|
31
|
+
*/
|
32
|
+
item(index: number): IHTMLOptionElement | IHTMLOptGroupElement;
|
33
|
+
|
27
34
|
/**
|
28
35
|
* Removes option element from the collection.
|
29
36
|
*
|