diff --git a/packages/happy-dom/src/query-selector/SelectorParser.ts b/packages/happy-dom/src/query-selector/SelectorParser.ts index 95c3e3e73..7c490d44b 100644 --- a/packages/happy-dom/src/query-selector/SelectorParser.ts +++ b/packages/happy-dom/src/query-selector/SelectorParser.ts @@ -27,7 +27,7 @@ import DocumentFragment from '../nodes/document-fragment/DocumentFragment.js'; * Group 17: Combinator. */ const SELECTOR_REGEXP = - /(\*)|([a-zA-Z0-9-]+)|#((?:[a-zA-Z0-9-_«»]|\\.)+)|\.((?:[a-zA-Z0-9-_«»]|\\.)+)|\[([a-zA-Z0-9-_\\:]+)\]|\[([a-zA-Z0-9-_\\:]+)\s*([~|^$*]{0,1})\s*=\s*["']{1}([^"']*)["']{1}\s*(s|i){0,1}\]|\[([a-zA-Z0-9-_]+)\s*([~|^$*]{0,1})\s*=\s*([^\]]*)\]|:([a-zA-Z-]+)\s*\(((?:[^()]|\[[^\]]*\]|\([^()]*\))*)\){0,1}|:([a-zA-Z-]+)|::([a-zA-Z-]+)|([\s,+>~]*)/gm; + /(\*)|([a-zA-Z0-9-]+)|#((?:[a-zA-Z0-9-_«»]|\\.)+)|\.((?:[a-zA-Z0-9-_«»]|\\.)+)|\[([a-zA-Z0-9-_\\:]+)\]|\[([a-zA-Z0-9-_\\:]+)\s*([~|^$*]{0,1})\s*=\s*["']((?<=")[^"]*(?=")|(?<=')[^']*(?='))["']\s*(s|i){0,1}\]|\[([a-zA-Z0-9-_]+)\s*([~|^$*]{0,1})\s*=\s*([^\]]*)\]|:([a-zA-Z-]+)\s*\(((?:[^()]|\[[^\]]*\]|\([^()]*\))*)\){0,1}|:([a-zA-Z-]+)|::([a-zA-Z-]+)|([\s,+>~]*)/gm; /** * Escaped Character RegExp. diff --git a/packages/happy-dom/test/query-selector/QuerySelector.test.ts b/packages/happy-dom/test/query-selector/QuerySelector.test.ts index 05be773cf..b8b87b1a4 100644 --- a/packages/happy-dom/test/query-selector/QuerySelector.test.ts +++ b/packages/happy-dom/test/query-selector/QuerySelector.test.ts @@ -502,6 +502,24 @@ describe('QuerySelector', () => { expect(elements[1] === container.children[0].children[1].children[1]).toBe(true); }); + it('Returns elements with attribute values containing apostrophes using double quotes as delimiter.', () => { + const container = document.createElement('div'); + container.innerHTML = `
Content
`; + + const elements = container.querySelectorAll('[data-value="it\'s a test"]'); + expect(elements.length).toBe(1); + expect(elements[0] === container.children[0]).toBe(true); + }); + + it('Returns elements with attribute values containing double quotes using apostrophes as delimiter.', () => { + const container = document.createElement('div'); + container.innerHTML = `
Content
`; + + const elements = container.querySelectorAll('[data-value=\'say "hello"\']'); + expect(elements.length).toBe(1); + expect(elements[0] === container.children[0]).toBe(true); + }); + it('Returns all elements with tag name and matching attributes using "span[_attr1]".', () => { const container = document.createElement('div'); container.innerHTML = QuerySelectorHTML.replace(/ attr1/gm, '_attr1');