Skip to content

Commit

Permalink
feat: [#990] Add support for multiple selectors in ":not" pseudo-class (
Browse files Browse the repository at this point in the history
#1751)

Co-authored-by: David Ortner <david@ortner.se>
  • Loading branch information
karpiuMG and capricorn86 authored Mar 4, 2025
1 parent 6dae379 commit 6f7057d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
7 changes: 6 additions & 1 deletion packages/happy-dom/src/query-selector/SelectorItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,12 @@ export default class SelectorItem {
case 'root':
return element[PropertySymbol.tagName] === 'HTML' ? { priorityWeight: 10 } : null;
case 'not':
return !pseudo.selectorItems[0].match(element) ? { priorityWeight: 10 } : null;
for (const selectorItem of pseudo.selectorItems) {
if (selectorItem.match(element)) {
return null;
}
}
return { priorityWeight: 10 };
case 'nth-child':
let nthChildIndex = -1;
if (pseudo.selectorItems[0] && !pseudo.selectorItems[0].match(element)) {
Expand Down
6 changes: 5 additions & 1 deletion packages/happy-dom/src/query-selector/SelectorParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,14 @@ export default class SelectorParser {
nthFunction: this.getPseudoNthFunction(args)
};
case 'not':
const notSelectorItems = [];
for (const group of this.getSelectorGroups(args, options)) {
notSelectorItems.push(group[0]);
}
return {
name: lowerName,
arguments: args,
selectorItems: [this.getSelectorItem(args, options)],
selectorItems: notSelectorItems,
nthFunction: null
};
case 'is':
Expand Down
14 changes: 14 additions & 0 deletions packages/happy-dom/test/query-selector/QuerySelector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,20 @@ describe('QuerySelector', () => {
expect(elements[0] === container.children[1]).toBe(true);
});

it('Supports :not with multiple selectors within', () => {
const container = document.createElement('div');
container.innerHTML = `<ul class="list">
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="other-item"></li>
<li></li>
</ul>`;

const lastItem = container.querySelectorAll('ul > li:not(.list-item, .other-item)');
expect(lastItem.length).toBe(1);
});

it('Returns all elements matching ".bar:not(.foo)".', () => {
const container = document.createElement('div');
container.innerHTML = `
Expand Down

0 comments on commit 6f7057d

Please sign in to comment.