happy-dom 7.5.10 → 7.5.12
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 +1 -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 +1 -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
@@ -5,14 +5,16 @@ import IHTMLElement from '../html-element/IHTMLElement';
|
|
5
5
|
import IHTMLFormElement from '../html-form-element/IHTMLFormElement';
|
6
6
|
import ValidityState from '../validity-state/ValidityState';
|
7
7
|
import IHTMLLabelElement from '../html-label-element/IHTMLLabelElement';
|
8
|
-
import HTMLOptGroupElement from '../html-opt-group-element/HTMLOptGroupElement';
|
9
8
|
import HTMLOptionElement from '../html-option-element/HTMLOptionElement';
|
10
9
|
import HTMLOptionsCollection from '../html-option-element/HTMLOptionsCollection';
|
11
|
-
import IHTMLOptionsCollection from '../html-option-element/IHTMLOptionsCollection';
|
12
10
|
import INodeList from '../node/INodeList';
|
13
|
-
import HTMLSelectElementValueSanitizer from './HTMLSelectElementValueSanitizer';
|
14
11
|
import IHTMLSelectElement from './IHTMLSelectElement';
|
15
12
|
import Event from '../../event/Event';
|
13
|
+
import IHTMLOptionElement from '../html-option-element/IHTMLOptionElement';
|
14
|
+
import IHTMLOptGroupElement from '../html-opt-group-element/IHTMLOptGroupElement';
|
15
|
+
import IHTMLOptionsCollection from '../html-option-element/IHTMLOptionsCollection';
|
16
|
+
import INode from '../node/INode';
|
17
|
+
import NodeTypeEnum from '../node/NodeTypeEnum';
|
16
18
|
|
17
19
|
/**
|
18
20
|
* HTML Select Element.
|
@@ -21,17 +23,13 @@ import Event from '../../event/Event';
|
|
21
23
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement.
|
22
24
|
*/
|
23
25
|
export default class HTMLSelectElement extends HTMLElement implements IHTMLSelectElement {
|
24
|
-
public type: string;
|
25
26
|
public labels: INodeList<IHTMLLabelElement>;
|
27
|
+
public readonly options: IHTMLOptionsCollection = new HTMLOptionsCollection(this);
|
26
28
|
|
27
29
|
// Events
|
28
30
|
public onchange: (event: Event) => void | null = null;
|
29
31
|
public oninput: (event: Event) => void | null = null;
|
30
32
|
|
31
|
-
public _value = null;
|
32
|
-
public _selectedIndex = -1;
|
33
|
-
public _options: IHTMLOptionsCollection = null;
|
34
|
-
|
35
33
|
/**
|
36
34
|
* Returns name.
|
37
35
|
*
|
@@ -116,6 +114,24 @@ export default class HTMLSelectElement extends HTMLElement implements IHTMLSelec
|
|
116
114
|
}
|
117
115
|
}
|
118
116
|
|
117
|
+
/**
|
118
|
+
* Returns length.
|
119
|
+
*
|
120
|
+
* @returns length.
|
121
|
+
*/
|
122
|
+
public get length(): number {
|
123
|
+
return this.options.length;
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Sets length.
|
128
|
+
*
|
129
|
+
* @param length Length.
|
130
|
+
*/
|
131
|
+
public set length(length: number) {
|
132
|
+
this.options.length = length;
|
133
|
+
}
|
134
|
+
|
119
135
|
/**
|
120
136
|
* Returns required.
|
121
137
|
*
|
@@ -138,13 +154,28 @@ export default class HTMLSelectElement extends HTMLElement implements IHTMLSelec
|
|
138
154
|
}
|
139
155
|
}
|
140
156
|
|
157
|
+
/**
|
158
|
+
* Returns type.
|
159
|
+
*
|
160
|
+
* @returns type.
|
161
|
+
*/
|
162
|
+
public get type(): string {
|
163
|
+
return this.hasAttributeNS(null, 'multiple') ? 'select-multiple' : 'select-one';
|
164
|
+
}
|
165
|
+
|
141
166
|
/**
|
142
167
|
* Returns value.
|
143
168
|
*
|
144
169
|
* @returns Value.
|
145
170
|
*/
|
146
171
|
public get value(): string {
|
147
|
-
|
172
|
+
if (this.options.selectedIndex === -1) {
|
173
|
+
return '';
|
174
|
+
}
|
175
|
+
|
176
|
+
const option = this.options[this.options.selectedIndex];
|
177
|
+
|
178
|
+
return option instanceof HTMLOptionElement ? option.value : '';
|
148
179
|
}
|
149
180
|
|
150
181
|
/**
|
@@ -153,12 +184,9 @@ export default class HTMLSelectElement extends HTMLElement implements IHTMLSelec
|
|
153
184
|
* @param value Value.
|
154
185
|
*/
|
155
186
|
public set value(value: string) {
|
156
|
-
this.
|
157
|
-
|
158
|
-
|
159
|
-
if (idx > -1) {
|
160
|
-
this._selectedIndex = idx;
|
161
|
-
}
|
187
|
+
this.options.selectedIndex = this.options.findIndex(
|
188
|
+
(o) => o instanceof HTMLOptionElement && o.value === value
|
189
|
+
);
|
162
190
|
}
|
163
191
|
|
164
192
|
/**
|
@@ -167,7 +195,7 @@ export default class HTMLSelectElement extends HTMLElement implements IHTMLSelec
|
|
167
195
|
* @returns Value.
|
168
196
|
*/
|
169
197
|
public get selectedIndex(): number {
|
170
|
-
return this.
|
198
|
+
return this.options.selectedIndex;
|
171
199
|
}
|
172
200
|
|
173
201
|
/**
|
@@ -176,14 +204,14 @@ export default class HTMLSelectElement extends HTMLElement implements IHTMLSelec
|
|
176
204
|
* @param value Value.
|
177
205
|
*/
|
178
206
|
public set selectedIndex(value: number) {
|
179
|
-
if (value > this.options.length - 1 || value <
|
207
|
+
if (value > this.options.length - 1 || value < -1) {
|
180
208
|
throw new DOMException(
|
181
209
|
'Select elements selected index must be valid',
|
182
210
|
DOMExceptionNameEnum.indexSizeError
|
183
211
|
);
|
184
212
|
}
|
185
213
|
|
186
|
-
this.
|
214
|
+
this.options.selectedIndex = value;
|
187
215
|
}
|
188
216
|
|
189
217
|
/**
|
@@ -224,21 +252,143 @@ export default class HTMLSelectElement extends HTMLElement implements IHTMLSelec
|
|
224
252
|
}
|
225
253
|
|
226
254
|
/**
|
227
|
-
* Returns options.
|
255
|
+
* Returns item from options collection by index.
|
256
|
+
*
|
257
|
+
* @param index Index.
|
258
|
+
*/
|
259
|
+
public item(index: number): IHTMLOptionElement | IHTMLOptGroupElement {
|
260
|
+
return this.options.item(index);
|
261
|
+
}
|
262
|
+
|
263
|
+
/**
|
264
|
+
* Adds new option to options collection.
|
228
265
|
*
|
229
|
-
* @
|
266
|
+
* @param element HTMLOptionElement or HTMLOptGroupElement to add.
|
267
|
+
* @param before HTMLOptionElement or index number.
|
268
|
+
*/
|
269
|
+
public add(
|
270
|
+
element: IHTMLOptionElement | IHTMLOptGroupElement,
|
271
|
+
before?: number | IHTMLOptionElement | IHTMLOptGroupElement
|
272
|
+
): void {
|
273
|
+
this.options.add(element, before);
|
274
|
+
}
|
275
|
+
|
276
|
+
/**
|
277
|
+
* Removes indexed element from collection or the select element.
|
278
|
+
*
|
279
|
+
* @param [index] Index.
|
280
|
+
*/
|
281
|
+
public override remove(index?: number): void {
|
282
|
+
if (typeof index === 'number') {
|
283
|
+
this.options.remove(index);
|
284
|
+
} else {
|
285
|
+
super.remove();
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
/**
|
290
|
+
* @override
|
291
|
+
*/
|
292
|
+
public override appendChild(node: INode): INode {
|
293
|
+
if (node.nodeType === NodeTypeEnum.elementNode) {
|
294
|
+
const element = <IHTMLElement>node;
|
295
|
+
const previousLength = this.options.length;
|
296
|
+
|
297
|
+
if (element.tagName === 'OPTION' || element.tagName === 'OPTGROUP') {
|
298
|
+
this.options.push(<IHTMLOptionElement | IHTMLOptGroupElement>element);
|
299
|
+
}
|
300
|
+
|
301
|
+
this._updateIndexProperties(previousLength, this.options.length);
|
302
|
+
}
|
303
|
+
|
304
|
+
return super.appendChild(node);
|
305
|
+
}
|
306
|
+
|
307
|
+
/**
|
308
|
+
* @override
|
309
|
+
*/
|
310
|
+
public override insertBefore(newNode: INode, referenceNode: INode | null): INode {
|
311
|
+
const returnValue = super.insertBefore(newNode, referenceNode);
|
312
|
+
|
313
|
+
if (
|
314
|
+
newNode.nodeType === NodeTypeEnum.elementNode &&
|
315
|
+
referenceNode?.nodeType === NodeTypeEnum.elementNode
|
316
|
+
) {
|
317
|
+
const newElement = <IHTMLElement>newNode;
|
318
|
+
const previousLength = this.options.length;
|
319
|
+
|
320
|
+
if (newElement.tagName === 'OPTION' || newElement.tagName === 'OPTGROUP') {
|
321
|
+
const referenceElement = <IHTMLElement>referenceNode;
|
322
|
+
|
323
|
+
if (
|
324
|
+
referenceElement &&
|
325
|
+
(referenceElement.tagName === 'OPTION' || referenceElement.tagName === 'OPTGROUP')
|
326
|
+
) {
|
327
|
+
const referenceIndex = this.options.indexOf(
|
328
|
+
<IHTMLOptGroupElement | IHTMLOptionElement>referenceElement
|
329
|
+
);
|
330
|
+
if (referenceIndex !== -1) {
|
331
|
+
this.options.splice(
|
332
|
+
referenceIndex,
|
333
|
+
0,
|
334
|
+
<IHTMLOptionElement | IHTMLOptGroupElement>newElement
|
335
|
+
);
|
336
|
+
}
|
337
|
+
} else {
|
338
|
+
this.options.push(<IHTMLOptionElement | IHTMLOptGroupElement>newElement);
|
339
|
+
}
|
340
|
+
}
|
341
|
+
|
342
|
+
this._updateIndexProperties(previousLength, this.options.length);
|
343
|
+
}
|
344
|
+
|
345
|
+
return returnValue;
|
346
|
+
}
|
347
|
+
|
348
|
+
/**
|
349
|
+
* @override
|
230
350
|
*/
|
231
|
-
public
|
232
|
-
if (
|
233
|
-
|
234
|
-
const
|
235
|
-
|
236
|
-
|
237
|
-
|
351
|
+
public override removeChild(node: INode): INode {
|
352
|
+
if (node.nodeType === NodeTypeEnum.elementNode) {
|
353
|
+
const element = <IHTMLElement>node;
|
354
|
+
const previousLength = this.options.length;
|
355
|
+
|
356
|
+
if (element.tagName === 'OPTION' || element.tagName === 'OPTION') {
|
357
|
+
const index = this.options.indexOf(<IHTMLOptionElement | IHTMLOptGroupElement>node);
|
358
|
+
if (index !== -1) {
|
359
|
+
this.options.splice(index, 1);
|
238
360
|
}
|
239
361
|
}
|
362
|
+
|
363
|
+
this._updateIndexProperties(previousLength, this.options.length);
|
240
364
|
}
|
241
365
|
|
242
|
-
return
|
366
|
+
return super.removeChild(node);
|
367
|
+
}
|
368
|
+
|
369
|
+
/**
|
370
|
+
* Updates index properties.
|
371
|
+
*
|
372
|
+
* @param previousLength Length before the update.
|
373
|
+
* @param newLength Length after the update.
|
374
|
+
*/
|
375
|
+
protected _updateIndexProperties(previousLength: number, newLength: number): void {
|
376
|
+
if (previousLength > newLength) {
|
377
|
+
for (let i = newLength; i < previousLength; i++) {
|
378
|
+
if (this.hasOwnProperty(String(i))) {
|
379
|
+
delete this[String(i)];
|
380
|
+
}
|
381
|
+
}
|
382
|
+
} else if (previousLength < newLength) {
|
383
|
+
for (let i = previousLength; i < newLength; i++) {
|
384
|
+
Object.defineProperty(this, String(i), {
|
385
|
+
get: () => {
|
386
|
+
return this.options[i];
|
387
|
+
},
|
388
|
+
enumerable: true,
|
389
|
+
configurable: true
|
390
|
+
});
|
391
|
+
}
|
392
|
+
}
|
243
393
|
}
|
244
394
|
}
|
@@ -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
|
/**
|
10
12
|
* HTML Select Element.
|
@@ -15,18 +17,44 @@ import Event from '../../event/Event';
|
|
15
17
|
export default interface IHTMLSelectElement extends IHTMLElement {
|
16
18
|
readonly form: IHTMLFormElement;
|
17
19
|
readonly labels: INodeList<IHTMLLabelElement>;
|
18
|
-
|
20
|
+
readonly options: IHTMLOptionsCollection;
|
21
|
+
readonly type: string;
|
22
|
+
readonly validity: ValidityState;
|
23
|
+
readonly willValidate: boolean;
|
19
24
|
autofocus: boolean;
|
20
25
|
disabled: boolean;
|
21
|
-
|
26
|
+
length: number;
|
22
27
|
selectedIndex: number;
|
23
|
-
validity: ValidityState;
|
24
28
|
value: string;
|
25
|
-
willValidate: boolean;
|
26
29
|
name: string;
|
27
30
|
multiple: boolean;
|
28
31
|
|
29
32
|
// Events
|
30
33
|
onchange: (event: Event) => void | null;
|
31
34
|
oninput: (event: Event) => void | null;
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Adds new option to collection.
|
38
|
+
*
|
39
|
+
* @param element HTMLOptionElement or HTMLOptGroupElement to add.
|
40
|
+
* @param before HTMLOptionElement or index number.
|
41
|
+
*/
|
42
|
+
add(
|
43
|
+
element: IHTMLOptionElement | IHTMLOptGroupElement,
|
44
|
+
before?: number | IHTMLOptionElement | IHTMLOptGroupElement
|
45
|
+
): void;
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Returns option element by index.
|
49
|
+
*
|
50
|
+
* @param index Index.
|
51
|
+
*/
|
52
|
+
item(index: number): IHTMLOptionElement | IHTMLOptGroupElement;
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Removes option element from the collection.
|
56
|
+
*
|
57
|
+
* @param index Index.
|
58
|
+
*/
|
59
|
+
remove(index?: number): void;
|
32
60
|
}
|
package/src/nodes/node/Node.ts
CHANGED
@@ -388,7 +388,7 @@ export default class Node extends EventTarget implements INode {
|
|
388
388
|
* Inserts a node before another.
|
389
389
|
*
|
390
390
|
* @param newNode Node to insert.
|
391
|
-
* @param
|
391
|
+
* @param referenceNode Node to insert before.
|
392
392
|
* @returns Inserted node.
|
393
393
|
*/
|
394
394
|
public insertBefore(newNode: INode, referenceNode: INode | null): INode {
|
@@ -1,18 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
const NEW_LINES_REGEXP = /[\n\r]/gm;
|
4
|
-
/**
|
5
|
-
* HTML select element value sanitizer.
|
6
|
-
*/
|
7
|
-
class HTMLOptionElementValueSanitizer {
|
8
|
-
/**
|
9
|
-
* Sanitizes a value.
|
10
|
-
*
|
11
|
-
* @param value Value.
|
12
|
-
*/
|
13
|
-
static sanitize(value) {
|
14
|
-
return value.trim().replace(NEW_LINES_REGEXP, '');
|
15
|
-
}
|
16
|
-
}
|
17
|
-
exports.default = HTMLOptionElementValueSanitizer;
|
18
|
-
//# sourceMappingURL=HTMLOptionElementValueSanitizer.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"HTMLOptionElementValueSanitizer.js","sourceRoot":"","sources":["../../../src/nodes/html-option-element/HTMLOptionElementValueSanitizer.ts"],"names":[],"mappings":";;AAAA,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAEpC;;GAEG;AACH,MAAqB,+BAA+B;IACnD;;;;OAIG;IACI,MAAM,CAAC,QAAQ,CAAC,KAAa;QACnC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC;CACD;AATD,kDASC"}
|
@@ -1,18 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
const NEW_LINES_REGEXP = /[\n\r]/gm;
|
4
|
-
/**
|
5
|
-
* HTML select element value sanitizer.
|
6
|
-
*/
|
7
|
-
class HTMLSelectElementValueSanitizer {
|
8
|
-
/**
|
9
|
-
* Sanitizes a value.
|
10
|
-
*
|
11
|
-
* @param value Value.
|
12
|
-
*/
|
13
|
-
static sanitize(value) {
|
14
|
-
return value.replace(NEW_LINES_REGEXP, '');
|
15
|
-
}
|
16
|
-
}
|
17
|
-
exports.default = HTMLSelectElementValueSanitizer;
|
18
|
-
//# sourceMappingURL=HTMLSelectElementValueSanitizer.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"HTMLSelectElementValueSanitizer.js","sourceRoot":"","sources":["../../../src/nodes/html-select-element/HTMLSelectElementValueSanitizer.ts"],"names":[],"mappings":";;AAAA,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAEpC;;GAEG;AACH,MAAqB,+BAA+B;IACnD;;;;OAIG;IACI,MAAM,CAAC,QAAQ,CAAC,KAAa;QACnC,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;CACD;AATD,kDASC"}
|
@@ -1,15 +0,0 @@
|
|
1
|
-
const NEW_LINES_REGEXP = /[\n\r]/gm;
|
2
|
-
|
3
|
-
/**
|
4
|
-
* HTML select element value sanitizer.
|
5
|
-
*/
|
6
|
-
export default class HTMLOptionElementValueSanitizer {
|
7
|
-
/**
|
8
|
-
* Sanitizes a value.
|
9
|
-
*
|
10
|
-
* @param value Value.
|
11
|
-
*/
|
12
|
-
public static sanitize(value: string): string {
|
13
|
-
return value.trim().replace(NEW_LINES_REGEXP, '');
|
14
|
-
}
|
15
|
-
}
|
@@ -1,15 +0,0 @@
|
|
1
|
-
const NEW_LINES_REGEXP = /[\n\r]/gm;
|
2
|
-
|
3
|
-
/**
|
4
|
-
* HTML select element value sanitizer.
|
5
|
-
*/
|
6
|
-
export default class HTMLSelectElementValueSanitizer {
|
7
|
-
/**
|
8
|
-
* Sanitizes a value.
|
9
|
-
*
|
10
|
-
* @param value Value.
|
11
|
-
*/
|
12
|
-
public static sanitize(value: string): string {
|
13
|
-
return value.replace(NEW_LINES_REGEXP, '');
|
14
|
-
}
|
15
|
-
}
|