Repository: capricorn86/happy-dom
Pull request #919 (2023-05-13 11:21:49)

#914@patch: Fixes issue where attribute query selectors using "~" or …
…"|" as operators for finding attributes containing a word did not match when there was only one word.


Patch:
diff --git a/packages/happy-dom/src/query-selector/SelectorParser.ts b/packages/happy-dom/src/query-selector/SelectorParser.ts
index 5195c0d7..a7465c9e 100644
--- a/packages/happy-dom/src/query-selector/SelectorParser.ts
+++ b/packages/happy-dom/src/query-selector/SelectorParser.ts
@@ -212,10 +212,13 @@ export default class SelectorParser {
 		switch (attribute.operator) {
 			// [attribute~="value"] - Contains a specified word.
 			case '~':
-				return new RegExp(`[- ]${attribute.value}|${attribute.value}[- ]`, modifier);
+				return new RegExp(
+					`[- ]${attribute.value}|${attribute.value}[- ]|^${attribute.value}$`,
+					modifier
+				);
 			// [attribute|="value"] - Starts with the specified word.
 			case '|':
-				return new RegExp(`^${attribute.value}[- ]`, modifier);
+				return new RegExp(`^${attribute.value}[- ]|^${attribute.value}$`, modifier);
 			// [attribute^="value"] - Begins with a specified value.
 			case '^':
 				return new RegExp(`^${attribute.value}`, modifier);


Test patch:
diff --git a/packages/happy-dom/test/query-selector/QuerySelector.test.ts b/packages/happy-dom/test/query-selector/QuerySelector.test.ts
index 59b99272..b4f07af5 100644
--- a/packages/happy-dom/test/query-selector/QuerySelector.test.ts
+++ b/packages/happy-dom/test/query-selector/QuerySelector.test.ts
@@ -427,6 +427,16 @@ describe('QuerySelector', () => {
 			expect(elements[4] === container.children[0].children[1].children[2]).toBe(true);
 		});
 
+		it('Returns all elements with an attribute value containing a specified word using "[attr1~="value1"]" (which doesn\'t include spaces).', () => {
+			const container = document.createElement('div');
+			container.innerHTML = QuerySelectorHTML;
+			const elements = container.querySelectorAll('[attr1~="value1"]');
+
+			expect(elements.length).toBe(2);
+			expect(elements[0] === container.children[0].children[1].children[0]).toBe(true);
+			expect(elements[1] === container.children[0].children[1].children[1]).toBe(true);
+		});
+
 		it('Returns all elements with an attribute value starting with the specified word using "[class|="class1"]".', () => {
 			const container = document.createElement('div');
 			container.innerHTML = QuerySelectorHTML;
@@ -440,6 +450,16 @@ describe('QuerySelector', () => {
 			expect(elements[4] === container.children[0].children[1].children[2]).toBe(true);
 		});
 
+		it('Returns all elements with an attribute value containing a specified word using "[attr1|="value1"]" (which doesn\'t include spaces).', () => {
+			const container = document.createElement('div');
+			container.innerHTML = QuerySelectorHTML;
+			const elements = container.querySelectorAll('[attr1|="value1"]');
+
+			expect(elements.length).toBe(2);
+			expect(elements[0] === container.children[0].children[1].children[0]).toBe(true);
+			expect(elements[1] === container.children[0].children[1].children[1]).toBe(true);
+		});
+
 		it('Returns all elements with an attribute value that begins with a specified value using "[class^="cl"]".', () => {
 			const container = document.createElement('div');
 			container.innerHTML = QuerySelectorHTML;