diff --git a/src/rules/require-baseline.js b/src/rules/require-baseline.js index 6b9d90b..5c53c7d 100644 --- a/src/rules/require-baseline.js +++ b/src/rules/require-baseline.js @@ -15,6 +15,7 @@ import { atRules, mediaConditions, types, + selectors, } from "../data/baseline-data.js"; import { namedColors } from "../data/colors.js"; @@ -347,6 +348,8 @@ export default { "Type '{{type}}' is not a {{availability}} available baseline feature.", notBaselineMediaCondition: "Media condition '{{condition}}' is not a {{availability}} available baseline feature.", + notBaselineSelector: + "Selector '{{selector}}' is not a {{availability}} available baseline feature.", }, }, @@ -625,6 +628,48 @@ export default { }); } }, + + Selector(node) { + for (const child of node.children) { + const selector = child.name; + + if (!selectors.has(selector)) { + continue; + } + + const ruleLevel = selectors.get(selector); + + if (ruleLevel < baselineLevel) { + const loc = child.loc; + + // some selectors are prefixed with the : or :: symbols + let prefixSymbolLength = 0; + if (child.type === "PseudoClassSelector") { + prefixSymbolLength = 1; + } else if (child.type === "PseudoElementSelector") { + prefixSymbolLength = 2; + } + + context.report({ + loc: { + start: loc.start, + end: { + line: loc.start.line, + column: + loc.start.column + + selector.length + + prefixSymbolLength, + }, + }, + messageId: "notBaselineSelector", + data: { + selector, + availability, + }, + }); + } + } + }, }; }, }; diff --git a/tests/rules/require-baseline.test.js b/tests/rules/require-baseline.test.js index 2147367..26d6db8 100644 --- a/tests/rules/require-baseline.test.js +++ b/tests/rules/require-baseline.test.js @@ -340,5 +340,37 @@ ruleTester.run("require-baseline", rule, { }, ], }, + { + code: "h1:has(+ h2) { margin: 0 0 0.25rem 0; }", + errors: [ + { + messageId: "notBaselineSelector", + data: { + selector: "has", + availability: "widely", + }, + line: 1, + column: 3, + endLine: 1, + endColumn: 7, + }, + ], + }, + { + code: "details::details-content { background-color: #a29bfe; }", + errors: [ + { + messageId: "notBaselineSelector", + data: { + selector: "details-content", + availability: "widely", + }, + line: 1, + column: 8, + endLine: 1, + endColumn: 25, + }, + ], + }, ], });