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.

Files changed (31) hide show
  1. package/lib/nodes/element/Element.d.ts +1 -13
  2. package/lib/nodes/element/Element.js +0 -12
  3. package/lib/nodes/element/Element.js.map +1 -1
  4. package/lib/nodes/html-option-element/HTMLOptionElement.js +2 -2
  5. package/lib/nodes/html-option-element/HTMLOptionElement.js.map +1 -1
  6. package/lib/nodes/html-option-element/HTMLOptionsCollection.d.ts +11 -5
  7. package/lib/nodes/html-option-element/HTMLOptionsCollection.js +29 -15
  8. package/lib/nodes/html-option-element/HTMLOptionsCollection.js.map +1 -1
  9. package/lib/nodes/html-option-element/IHTMLOptionsCollection.d.ts +6 -0
  10. package/lib/nodes/html-select-element/HTMLSelectElement.d.ts +58 -8
  11. package/lib/nodes/html-select-element/HTMLSelectElement.js +142 -23
  12. package/lib/nodes/html-select-element/HTMLSelectElement.js.map +1 -1
  13. package/lib/nodes/html-select-element/IHTMLSelectElement.d.ts +26 -4
  14. package/lib/nodes/node/Node.d.ts +1 -1
  15. package/lib/nodes/node/Node.js +1 -1
  16. package/package.json +2 -2
  17. package/src/nodes/element/Element.ts +3 -15
  18. package/src/nodes/html-option-element/HTMLOptionElement.ts +3 -2
  19. package/src/nodes/html-option-element/HTMLOptionsCollection.ts +39 -19
  20. package/src/nodes/html-option-element/IHTMLOptionsCollection.ts +7 -0
  21. package/src/nodes/html-select-element/HTMLSelectElement.ts +178 -28
  22. package/src/nodes/html-select-element/IHTMLSelectElement.ts +32 -4
  23. package/src/nodes/node/Node.ts +1 -1
  24. package/lib/nodes/html-option-element/HTMLOptionElementValueSanitizer.d.ts +0 -11
  25. package/lib/nodes/html-option-element/HTMLOptionElementValueSanitizer.js +0 -18
  26. package/lib/nodes/html-option-element/HTMLOptionElementValueSanitizer.js.map +0 -1
  27. package/lib/nodes/html-select-element/HTMLSelectElementValueSanitizer.d.ts +0 -11
  28. package/lib/nodes/html-select-element/HTMLSelectElementValueSanitizer.js +0 -18
  29. package/lib/nodes/html-select-element/HTMLSelectElementValueSanitizer.js.map +0 -1
  30. package/src/nodes/html-option-element/HTMLOptionElementValueSanitizer.ts +0 -15
  31. 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 HTMLSelectElementValueSanitizer_1 = __importDefault(require("./HTMLSelectElementValueSanitizer"));
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
- return this._value;
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._value = HTMLSelectElementValueSanitizer_1.default.sanitize(value);
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._options ? this._options.selectedIndex : -1;
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 < 0) {
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._options.selectedIndex = value;
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
- * @returns Options.
242
+ * @param [index] Index.
203
243
  */
204
- get options() {
205
- if (this._options === null) {
206
- this._options = new HTMLOptionsCollection_1.default();
207
- const childs = this.childNodes;
208
- for (const child of childs) {
209
- if (child.tagName === 'OPTION') {
210
- this._options.add(child);
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
- return this._options;
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":"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"}
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
- type: string;
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
- options: IHTMLOptionsCollection;
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
  }
@@ -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 [referenceNode] Node to insert before.
182
+ * @param referenceNode Node to insert before.
183
183
  * @returns Inserted node.
184
184
  */
185
185
  insertBefore(newNode: INode, referenceNode: INode | null): INode;
@@ -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 [referenceNode] Node to insert before.
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.10",
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": "8a08a695bec1fffd16bbdfa1040579377ebfbebf"
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?: INode): INode {
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', HTMLOptionElementValueSanitizer.sanitize(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 HTMLOptGroupElement from '../html-opt-group-element/HTMLOptGroupElement';
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
- public _selectedIndex: number;
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
- return this._selectedIndex;
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._selectedIndex = selectedIndex;
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): HTMLOptionElement | HTMLOptGroupElement {
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: HTMLOptionElement | HTMLOptGroupElement,
53
- before?: number | HTMLOptionElement | HTMLOptGroupElement
76
+ element: IHTMLOptionElement | IHTMLOptGroupElement,
77
+ before?: number | IHTMLOptionElement | IHTMLOptGroupElement
54
78
  ): void {
55
79
  if (!before && before !== 0) {
56
- this.push(element);
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.splice(<number>before, 0, element);
89
+ this._selectElement.insertBefore(element, this[<number>before]);
66
90
  return;
67
91
  }
68
92
 
69
- const idx = this.findIndex((element) => element === before);
70
- if (idx === -1) {
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.splice(idx, 0, element);
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.splice(index, 1);
86
- if (index === this.selectedIndex) {
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
  *