Files
LearnNode/node-course/node_modules/@eslint/css/dist/rules/no-invalid-at-rule-placement.js
T
2026-08-06 12:00:39 +10:00

84 lines
3.3 KiB
JavaScript

/**
* @fileoverview Rule to enforce correct placement of at-rules.
* @author thecalamiity
*/
//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------
/**
* @import { CSSRuleDefinition } from "../types.js"
* @typedef {"invalidCharsetPlacement" | "invalidImportPlacement" | "invalidNamespacePlacement"} NoInvalidAtRulePlacementMessageIds
* @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoInvalidAtRulePlacementMessageIds }>} NoInvalidAtRulePlacementRuleDefinition
*/
//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------
export default /** @satisfies {NoInvalidAtRulePlacementRuleDefinition} */ ({
meta: {
type: "problem",
docs: {
description: "Disallow invalid placement of at-rules",
recommended: true,
url: "https://github.com/eslint/css/blob/main/docs/rules/no-invalid-at-rule-placement.md",
},
messages: {
invalidCharsetPlacement: "@charset must be placed at the very beginning of the stylesheet, before any rules, comments, or whitespace.",
invalidImportPlacement: "@import must be placed before all other rules, except @charset and @layer statements.",
invalidNamespacePlacement: "@namespace must be placed before all other rules, except @charset and @import.",
},
},
create(context) {
let hasSeenNonImportRule = false;
let hasSeenLayerBlock = false;
let hasSeenLayer = false;
let hasSeenNamespace = false;
return {
Atrule(node) {
const name = node.name.toLowerCase();
if (name === "charset") {
if (node.loc.start.line !== 1 ||
node.loc.start.column !== 1) {
context.report({
node,
messageId: "invalidCharsetPlacement",
});
}
return;
}
if (name === "layer") {
if (node.block) {
hasSeenLayerBlock = true;
}
hasSeenLayer = true;
return;
}
if (name === "namespace") {
if (hasSeenNonImportRule || hasSeenLayer) {
context.report({
node,
messageId: "invalidNamespacePlacement",
});
}
hasSeenNamespace = true;
return;
}
if (name === "import") {
if (hasSeenNonImportRule ||
hasSeenNamespace ||
hasSeenLayerBlock) {
context.report({
node,
messageId: "invalidImportPlacement",
});
}
return;
}
hasSeenNonImportRule = true;
},
Rule() {
hasSeenNonImportRule = true;
},
};
},
});