happy-dom 9.9.2 → 9.10.1

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 (43) hide show
  1. package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.js +1 -1
  2. package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.js.map +1 -1
  3. package/lib/nodes/element/Element.d.ts.map +1 -1
  4. package/lib/nodes/element/Element.js +2 -15
  5. package/lib/nodes/element/Element.js.map +1 -1
  6. package/lib/nodes/node/Node.d.ts +0 -8
  7. package/lib/nodes/node/Node.d.ts.map +1 -1
  8. package/lib/nodes/node/Node.js +1 -23
  9. package/lib/nodes/node/Node.js.map +1 -1
  10. package/lib/query-selector/ISelectorAttribute.d.ts +6 -0
  11. package/lib/query-selector/ISelectorAttribute.d.ts.map +1 -0
  12. package/lib/query-selector/ISelectorAttribute.js +3 -0
  13. package/lib/query-selector/ISelectorAttribute.js.map +1 -0
  14. package/lib/query-selector/ISelectorMatch.d.ts +4 -0
  15. package/lib/query-selector/ISelectorMatch.d.ts.map +1 -0
  16. package/lib/query-selector/ISelectorMatch.js +3 -0
  17. package/lib/query-selector/ISelectorMatch.js.map +1 -0
  18. package/lib/query-selector/QuerySelector.d.ts +21 -31
  19. package/lib/query-selector/QuerySelector.d.ts.map +1 -1
  20. package/lib/query-selector/QuerySelector.js +123 -131
  21. package/lib/query-selector/QuerySelector.js.map +1 -1
  22. package/lib/query-selector/SelectorCombinatorEnum.d.ts +7 -0
  23. package/lib/query-selector/SelectorCombinatorEnum.d.ts.map +1 -0
  24. package/lib/query-selector/SelectorCombinatorEnum.js +10 -0
  25. package/lib/query-selector/SelectorCombinatorEnum.js.map +1 -0
  26. package/lib/query-selector/SelectorItem.d.ts +41 -56
  27. package/lib/query-selector/SelectorItem.d.ts.map +1 -1
  28. package/lib/query-selector/SelectorItem.js +194 -220
  29. package/lib/query-selector/SelectorItem.js.map +1 -1
  30. package/lib/query-selector/SelectorParser.d.ts +21 -0
  31. package/lib/query-selector/SelectorParser.d.ts.map +1 -0
  32. package/lib/query-selector/SelectorParser.js +154 -0
  33. package/lib/query-selector/SelectorParser.js.map +1 -0
  34. package/package.json +1 -1
  35. package/src/css/declaration/utilities/CSSStyleDeclarationElementStyle.ts +2 -2
  36. package/src/nodes/element/Element.ts +3 -17
  37. package/src/nodes/node/Node.ts +1 -25
  38. package/src/query-selector/ISelectorAttribute.ts +5 -0
  39. package/src/query-selector/ISelectorMatch.ts +3 -0
  40. package/src/query-selector/QuerySelector.ts +187 -170
  41. package/src/query-selector/SelectorCombinatorEnum.ts +7 -0
  42. package/src/query-selector/SelectorItem.ts +238 -264
  43. package/src/query-selector/SelectorParser.ts +148 -0
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const SelectorItem_1 = __importDefault(require("./SelectorItem"));
7
+ const SelectorCombinatorEnum_1 = __importDefault(require("./SelectorCombinatorEnum"));
8
+ const DOMException_1 = __importDefault(require("../exception/DOMException"));
9
+ /**
10
+ * Selector RegExp.
11
+ *
12
+ * Group 1: All (e.g. "*")
13
+ * Group 2: Tag name (e.g. "div")
14
+ * Group 3: ID (e.g. "#id")
15
+ * Group 4: Class (e.g. ".class")
16
+ * Group 5: Attribute name when no value (e.g. "attr1")
17
+ * Group 6: Attribute name when there is a value (e.g. "attr1")
18
+ * Group 7: Attribute operator (e.g. "~")
19
+ * Group 8: Attribute value (e.g. "value1")
20
+ * Group 9: Pseudo (e.g. "nth-child")
21
+ * Group 10: Arguments of pseudo (e.g. "2n + 1")
22
+ * Group 11: Combinator.
23
+ */
24
+ const SELECTOR_REGEXP = /(\*)|([a-zA-Z0-9-]+)|#((?:[a-zA-Z0-9-_]|\\.)+)|\.((?:[a-zA-Z0-9-_]|\\.)+)|\[([a-zA-Z0-9-_]+)\]|\[([a-zA-Z0-9-_]+)([~|^$*]{0,1}) *= *["']{0,1}([^"']+)["']{0,1}\]|:([a-zA-Z-:]+)|\(([^)]+)\)|([ ,+>]*)/g;
25
+ /**
26
+ * Escaped Character RegExp.
27
+ */
28
+ const CLASS_ESCAPED_CHARACTER_REGEXP = /\\/g;
29
+ /**
30
+ * Simple Selector RegExp.
31
+ *
32
+ * Group 1: Tag name (e.g. "div")
33
+ * Group 2: Class (e.g. ".classA.classB")
34
+ * Group 3: ID (e.g. "#id")
35
+ */
36
+ const SIMPLE_SELECTOR_REGEXP = /(^[a-zA-Z0-9-]+$)|(^\.[a-zA-Z0-9-_.]+$)|(^#[a-zA-Z0-9-_]+$)/;
37
+ /**
38
+ * Utility for parsing a selection string.
39
+ */
40
+ class SelectorParser {
41
+ /**
42
+ * Parses a selector string and returns an instance of SelectorItem.
43
+ *
44
+ * @param selector Selector.
45
+ * @returns Selector itme.
46
+ */
47
+ static getSelectorItem(selector) {
48
+ return this.getSelectorGroups(selector)[0][0];
49
+ }
50
+ /**
51
+ * Parses a selector string and returns groups with SelectorItem instances.
52
+ *
53
+ * @param selector Selector.
54
+ * @returns Selector groups.
55
+ */
56
+ static getSelectorGroups(selector) {
57
+ const simpleMatch = selector.match(SIMPLE_SELECTOR_REGEXP);
58
+ if (simpleMatch) {
59
+ if (simpleMatch[1]) {
60
+ return [[new SelectorItem_1.default({ tagName: selector.toUpperCase() })]];
61
+ }
62
+ else if (simpleMatch[2]) {
63
+ return [[new SelectorItem_1.default({ classNames: selector.replace('.', '').split('.') })]];
64
+ }
65
+ else if (simpleMatch[3]) {
66
+ return [[new SelectorItem_1.default({ id: selector.replace('#', '') })]];
67
+ }
68
+ }
69
+ const regexp = new RegExp(SELECTOR_REGEXP);
70
+ let currentSelectorItem = new SelectorItem_1.default({
71
+ combinator: SelectorCombinatorEnum_1.default.descendant
72
+ });
73
+ let currentGroup = [currentSelectorItem];
74
+ const groups = [currentGroup];
75
+ let isValid = false;
76
+ let match;
77
+ while ((match = regexp.exec(selector))) {
78
+ if (match[0]) {
79
+ isValid = true;
80
+ if (match[1]) {
81
+ currentSelectorItem.all = '*';
82
+ }
83
+ else if (match[2]) {
84
+ currentSelectorItem.tagName = match[2].toUpperCase();
85
+ }
86
+ else if (match[3]) {
87
+ currentSelectorItem.id = match[3].replace(CLASS_ESCAPED_CHARACTER_REGEXP, '');
88
+ }
89
+ else if (match[4]) {
90
+ currentSelectorItem.classNames = currentSelectorItem.classNames || [];
91
+ currentSelectorItem.classNames.push(match[4].replace(CLASS_ESCAPED_CHARACTER_REGEXP, ''));
92
+ }
93
+ else if (match[5]) {
94
+ currentSelectorItem.attributes = currentSelectorItem.attributes || [];
95
+ currentSelectorItem.attributes.push({
96
+ name: match[5].toLowerCase(),
97
+ operator: null,
98
+ value: null
99
+ });
100
+ }
101
+ else if (match[6] && match[8]) {
102
+ currentSelectorItem.attributes = currentSelectorItem.attributes || [];
103
+ currentSelectorItem.attributes.push({
104
+ name: match[6].toLowerCase(),
105
+ operator: match[7] || null,
106
+ value: match[8]
107
+ });
108
+ }
109
+ else if (match[9]) {
110
+ currentSelectorItem.pseudoClass = match[9].toLowerCase();
111
+ }
112
+ else if (match[10]) {
113
+ currentSelectorItem.pseudoArguments = match[10];
114
+ }
115
+ else if (match[11]) {
116
+ switch (match[11].trim()) {
117
+ case ',':
118
+ currentSelectorItem = new SelectorItem_1.default({
119
+ combinator: SelectorCombinatorEnum_1.default.descendant
120
+ });
121
+ currentGroup = [currentSelectorItem];
122
+ groups.push(currentGroup);
123
+ break;
124
+ case '>':
125
+ currentSelectorItem = new SelectorItem_1.default({ combinator: SelectorCombinatorEnum_1.default.child });
126
+ currentGroup.push(currentSelectorItem);
127
+ break;
128
+ case '+':
129
+ currentSelectorItem = new SelectorItem_1.default({
130
+ combinator: SelectorCombinatorEnum_1.default.adjacentSibling
131
+ });
132
+ currentGroup.push(currentSelectorItem);
133
+ break;
134
+ case '':
135
+ currentSelectorItem = new SelectorItem_1.default({
136
+ combinator: SelectorCombinatorEnum_1.default.descendant
137
+ });
138
+ currentGroup.push(currentSelectorItem);
139
+ break;
140
+ }
141
+ }
142
+ }
143
+ else {
144
+ break;
145
+ }
146
+ }
147
+ if (!isValid) {
148
+ throw new DOMException_1.default(`Invalid selector: "${selector}"`);
149
+ }
150
+ return groups;
151
+ }
152
+ }
153
+ exports.default = SelectorParser;
154
+ //# sourceMappingURL=SelectorParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectorParser.js","sourceRoot":"","sources":["../../src/query-selector/SelectorParser.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-dom",
3
- "version": "9.9.2",
3
+ "version": "9.10.1",
4
4
  "license": "MIT",
5
5
  "homepage": "https://github.com/capricorn86/happy-dom",
6
6
  "repository": "https://github.com/capricorn86/happy-dom",
@@ -289,8 +289,8 @@ export default class CSSStyleDeclarationElementStyle {
289
289
  }
290
290
  } else {
291
291
  for (const element of options.elements) {
292
- const matchResult = QuerySelector.match(element.element, selectorText);
293
- if (matchResult.matches) {
292
+ const matchResult = QuerySelector.match(<IElement>element.element, selectorText);
293
+ if (matchResult) {
294
294
  element.cssTexts.push({
295
295
  cssText: (<CSSStyleRule>rule)._cssText,
296
296
  priorityWeight: matchResult.priorityWeight
@@ -723,7 +723,7 @@ export default class Element extends Node implements IElement {
723
723
  * @returns "true" if matching.
724
724
  */
725
725
  public matches(selector: string): boolean {
726
- return QuerySelector.match(this, selector).matches;
726
+ return !!QuerySelector.match(this, selector);
727
727
  }
728
728
 
729
729
  /**
@@ -733,30 +733,16 @@ export default class Element extends Node implements IElement {
733
733
  * @returns Closest matching element.
734
734
  */
735
735
  public closest(selector: string): IElement {
736
- let rootElement: IElement = this.ownerDocument.documentElement;
737
- if (!this.isConnected) {
738
- rootElement = this;
739
- while (rootElement.parentNode) {
740
- rootElement = <IElement>rootElement.parentNode;
741
- }
742
- }
743
- const elements = rootElement.querySelectorAll(selector);
744
-
745
736
  // eslint-disable-next-line
746
737
  let parent: IElement = this;
738
+
747
739
  while (parent) {
748
- if (elements.includes(parent)) {
740
+ if (QuerySelector.match(parent, selector)) {
749
741
  return parent;
750
742
  }
751
743
  parent = parent.parentElement;
752
744
  }
753
745
 
754
- // QuerySelectorAll() will not match the element it is looking in when searched for
755
- // Therefore we need to check if it matches the root
756
- if (rootElement.matches(selector)) {
757
- return rootElement;
758
- }
759
-
760
746
  return null;
761
747
  }
762
748
 
@@ -11,17 +11,6 @@ import IAttr from '../attr/IAttr';
11
11
  import NodeList from './NodeList';
12
12
  import INodeList from './INodeList';
13
13
 
14
- const JSON_CIRCULAR_PROPERTIES = [
15
- 'ownerDocument',
16
- 'parentNode',
17
- 'ownerElement',
18
- 'defaultView',
19
- '_rootNode',
20
- '_formNode',
21
- '_selectNode',
22
- '_textAreaNode'
23
- ];
24
-
25
14
  /**
26
15
  * Node.
27
16
  */
@@ -198,7 +187,7 @@ export default class Node extends EventTarget implements INode {
198
187
  */
199
188
  public get parentElement(): IElement {
200
189
  let parent = this.parentNode;
201
- while (parent && parent.nodeType !== Node.ELEMENT_NODE) {
190
+ while (parent && parent.nodeType !== NodeTypeEnum.elementNode) {
202
191
  parent = parent.parentNode;
203
192
  }
204
193
  return <IElement>parent;
@@ -648,17 +637,4 @@ export default class Node extends EventTarget implements INode {
648
637
  child = child.nextSibling;
649
638
  }
650
639
  }
651
-
652
- /**
653
- * This will be called by JSON.stringify() when serializing this node.
654
- *
655
- * @returns Object without circular references.
656
- */
657
- public toJSON(): { [key: string]: unknown } {
658
- const result = {};
659
- for (const key of Object.keys(this)) {
660
- result[key] = !JSON_CIRCULAR_PROPERTIES.includes(key) ? this[key] : null;
661
- }
662
- return result;
663
- }
664
640
  }
@@ -0,0 +1,5 @@
1
+ export default interface ISelectorAttribute {
2
+ name: string;
3
+ operator: string | null;
4
+ value: string | null;
5
+ }
@@ -0,0 +1,3 @@
1
+ export default interface ISelectorMatch {
2
+ priorityWeight: number;
3
+ }