Files
LearnNode/node-course/node_modules/@eslint/css/dist/rules/no-duplicate-keyframe-selectors.js
T
2026-08-06 12:00:39 +10:00

71 lines
2.7 KiB
JavaScript

/**
* @fileoverview Rule to disallow duplicate selectors within keyframe blocks.
* @author Nitin Kumar
*/
//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------
/**
* @import { CSSRuleDefinition } from "../types.js"
* @typedef {"duplicateKeyframeSelector"} DuplicateKeyframeSelectorMessageIds
* @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: DuplicateKeyframeSelectorMessageIds }>} DuplicateKeyframeSelectorRuleDefinition
*/
//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------
export default /** @satisfies {DuplicateKeyframeSelectorRuleDefinition} */ ({
meta: {
type: "problem",
docs: {
description: "Disallow duplicate selectors within keyframe blocks",
recommended: true,
url: "https://github.com/eslint/css/blob/main/docs/rules/no-duplicate-keyframe-selectors.md",
},
messages: {
duplicateKeyframeSelector: "Unexpected duplicate selector '{{selector}}' found within keyframe block.",
},
},
create(context) {
let insideKeyframes = false;
const seen = new Map();
return {
"Atrule[name=/^(-(o|moz|webkit)-)?keyframes$/i]"() {
insideKeyframes = true;
seen.clear();
},
"Atrule[name=/^(-(o|moz|webkit)-)?keyframes$/i]:exit"() {
insideKeyframes = false;
},
Rule(node) {
if (!insideKeyframes) {
return;
}
// @ts-ignore - children is a valid property for prelude
const selector = node.prelude.children[0].children[0];
let value;
if (selector.type === "Percentage") {
value = `${selector.value}%`;
}
else if (selector.type === "TypeSelector") {
value = selector.name.toLowerCase();
}
else {
value = selector.value;
}
if (seen.has(value)) {
context.report({
loc: selector.loc,
messageId: "duplicateKeyframeSelector",
data: {
selector: value,
},
});
}
else {
seen.set(value, true);
}
},
};
},
});