From d04f4c888c3ff8e355ec3c2ea0cda4d3c60b2bf7 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Thu, 1 Oct 2026 11:47:06 +0200 Subject: [PATCH 1/2] chore: add tests for `::part()` and `::highlight()` --- test/index.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/index.js b/test/index.js index 6d32d1f..fbf2adc 100644 --- a/test/index.js +++ b/test/index.js @@ -77,6 +77,24 @@ describe('CALCULATE', () => { it('::first-letter', () => { deepEqual(Specificity.calculate('::first-letter')[0].toObject(), { a: 0, b: 0, c: 1 }); }); + it('::part(my-ident)', () => { + deepEqual(Specificity.calculate('::part(my-ident)')[0].toObject(), { a: 0, b: 0, c: 1 }); + }); + it('::part(first-ident second-ident)', () => { + deepEqual(Specificity.calculate('::part(first-ident second-ident)')[0].toObject(), { a: 0, b: 0, c: 1 }); + }); + it('::highlight & do not crash', () => { + deepEqual(Specificity.calculate('::highlight')[0].toObject(), { a: 0, b: 0, c: 1 }); + }); + it('::highlight() & do not crash', () => { + deepEqual(Specificity.calculate('::highlight')[0].toObject(), { a: 0, b: 0, c: 1 }); + }); + it('::highlight(my-ident)', () => { + deepEqual(Specificity.calculate('::highlight(my-ident)')[0].toObject(), { a: 0, b: 0, c: 1 }); + }); + it('::highlight(*)', () => { + deepEqual(Specificity.calculate('::highlight(*)')[0].toObject(), { a: 0, b: 0, c: 1 }); + }); }); describe('Pseudo-Element Selector ::slotted', () => { From 139c19b084b47a1b8a00fefca91a5637aaa28a73 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Mon, 5 Oct 2026 11:27:03 +0200 Subject: [PATCH 2/2] fix specificity of `::highlight`, `::highlight(*)` and `::highlight(my-ident)` --- src/core/calculate.js | 12 ++++++++++++ test/index.js | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/core/calculate.js b/src/core/calculate.js index f05b1ae..70510e5 100644 --- a/src/core/calculate.js +++ b/src/core/calculate.js @@ -161,6 +161,18 @@ const calculateForAST = (selectorAST) => { c += 1; break; + case 'highlight': + if (child.children?.size > 0) { + // The specificity of a ::highlight() selector with a * argument is zero. + if (child.children.first?.value === '*') { + break; + } + // The specificity of a ::highlight() selector with a argument + // is equivalent to a type selector. + c += 1; + } + break; + default: c += 1; break; diff --git a/test/index.js b/test/index.js index fbf2adc..57ec6bb 100644 --- a/test/index.js +++ b/test/index.js @@ -84,16 +84,16 @@ describe('CALCULATE', () => { deepEqual(Specificity.calculate('::part(first-ident second-ident)')[0].toObject(), { a: 0, b: 0, c: 1 }); }); it('::highlight & do not crash', () => { - deepEqual(Specificity.calculate('::highlight')[0].toObject(), { a: 0, b: 0, c: 1 }); + deepEqual(Specificity.calculate('::highlight')[0].toObject(), { a: 0, b: 0, c: 0 }); }); it('::highlight() & do not crash', () => { - deepEqual(Specificity.calculate('::highlight')[0].toObject(), { a: 0, b: 0, c: 1 }); + deepEqual(Specificity.calculate('::highlight')[0].toObject(), { a: 0, b: 0, c: 0 }); }); it('::highlight(my-ident)', () => { deepEqual(Specificity.calculate('::highlight(my-ident)')[0].toObject(), { a: 0, b: 0, c: 1 }); }); it('::highlight(*)', () => { - deepEqual(Specificity.calculate('::highlight(*)')[0].toObject(), { a: 0, b: 0, c: 1 }); + deepEqual(Specificity.calculate('::highlight(*)')[0].toObject(), { a: 0, b: 0, c: 0 }); }); });