Skip to content

Commit 00ce917

Browse files
committed
feat: ignore selectors tested in @supports rules
1 parent 66524b6 commit 00ce917

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

src/rules/require-baseline.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ class SupportsRule {
124124
*/
125125
#properties = new Map();
126126

127+
/**
128+
* The selectors supported by this rule.
129+
* @type {Set<string>}
130+
*/
131+
#selectors = new Set();
132+
127133
/**
128134
* Adds a property to the rule.
129135
* @param {string} property The name of the property.
@@ -219,6 +225,24 @@ class SupportsRule {
219225

220226
return supportedProperty.hasFunctions();
221227
}
228+
229+
/**
230+
* Adds a selector to the rule.
231+
* @param {string} selector The name of the selector.
232+
* @returns {void}
233+
*/
234+
addSelector(selector) {
235+
this.#selectors.add(selector);
236+
}
237+
238+
/**
239+
* Determines if the rule supports a selector.
240+
* @param {string} selector The name of the selector.
241+
* @returns {boolean} `true` if the selector is supported, `false` if not.
242+
*/
243+
hasSelector(selector) {
244+
return this.#selectors.has(selector);
245+
}
222246
}
223247

224248
/**
@@ -304,6 +328,15 @@ class SupportsRules {
304328
hasPropertyFunctions(property) {
305329
return this.#rules.some(rule => rule.hasFunctions(property));
306330
}
331+
332+
/**
333+
* Determines if any rule supports a selector.
334+
* @param {string} selector The name of the selector.
335+
* @returns {boolean} `true` if any rule supports the selector, `false` if not.
336+
*/
337+
hasSelector(selector) {
338+
return this.#rules.some(rule => rule.hasSelector(selector));
339+
}
307340
}
308341

309342
//-----------------------------------------------------------------------------
@@ -462,6 +495,16 @@ export default {
462495

463496
continue;
464497
}
498+
499+
if (
500+
conditionChild.type === "FeatureFunction" &&
501+
conditionChild.feature === "selector"
502+
) {
503+
for (const selectorChild of conditionChild.value
504+
.children) {
505+
supportsRule.addSelector(selectorChild.name);
506+
}
507+
}
465508
}
466509
},
467510

@@ -637,6 +680,11 @@ export default {
637680
continue;
638681
}
639682

683+
// if the selector has been tested in a @supports rule, don't check it
684+
if (supportsRules.hasSelector(selector)) {
685+
continue;
686+
}
687+
640688
const selectorLevel = selectors.get(selector);
641689

642690
if (selectorLevel < baselineLevel) {

tests/rules/require-baseline.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ ruleTester.run("require-baseline", rule, {
5757
`@supports (width: abs(20% - 100px)) {
5858
a { width: abs(20% - 100px); }
5959
}`,
60+
`@supports selector(:has()) {
61+
h1:has(+ h2) { color: red; }
62+
}`,
6063
"div { cursor: pointer; }",
6164
{
6265
code: `@property --foo {
@@ -356,6 +359,28 @@ ruleTester.run("require-baseline", rule, {
356359
},
357360
],
358361
},
362+
{
363+
code: `@supports selector(:has()) {}
364+
365+
@supports (color: red) {
366+
h1:has(+ h2) {
367+
color: red;
368+
}
369+
}`,
370+
errors: [
371+
{
372+
messageId: "notBaselineSelector",
373+
data: {
374+
selector: "has",
375+
availability: "widely",
376+
},
377+
line: 4,
378+
column: 7,
379+
endLine: 4,
380+
endColumn: 11,
381+
},
382+
],
383+
},
359384
{
360385
code: "details::details-content { background-color: #a29bfe; }",
361386
errors: [

0 commit comments

Comments
 (0)