UNPKG

stylelint-scss

Version:

A collection of SCSS-specific rules for Stylelint

115 lines (94 loc) 2.95 kB
"use strict"; const nodeJsPath = require("path"); const { utils } = require("stylelint"); const atRuleParamIndex = require("../../utils/atRuleParamIndex"); const namespace = require("../../utils/namespace"); const ruleUrl = require("../../utils/ruleUrl"); const ruleName = namespace("at-import-partial-extension"); const messages = utils.ruleMessages(ruleName, { expected: "Expected @import to have an extension", rejected: ext => `Unexpected extension ".${ext}" in @import` }); const meta = { url: ruleUrl(ruleName) }; // https://drafts.csswg.org/mediaqueries/#media-types const mediaQueryTypes = [ "all", "print", "screen", "speech", "tv", "tty", "projection", "handheld", "braille", "embossed", "aural" ]; const mediaQueryTypesRE = new RegExp(`(${mediaQueryTypes.join("|")})$`, "i"); const stripPath = path => path.replace(/^\s*(["'])\s*/, "").replace(/\s*(["'])\s*$/, ""); function rule(expectation, _, context) { return (root, result) => { const validOptions = utils.validateOptions(result, ruleName, { actual: expectation, possible: ["always", "never"] }); if (!validOptions) { return; } root.walkAtRules("import", atRule => { const paths = atRule.params .split(/["']\s*,/) .filter(path => !mediaQueryTypesRE.test(path.trim())); // Processing comma-separated lists of import paths paths.forEach(path => { // Stripping trailing quotes and whitespaces, if any const pathStripped = stripPath(path); // Skipping importing CSS: url(), ".css", URI with a protocol if ( pathStripped.slice(0, 4) === "url(" || pathStripped.slice(-4) === ".css" || pathStripped.search("//") !== -1 ) { return; } const extension = nodeJsPath.extname(pathStripped).slice(1); if (!extension && expectation === "always") { utils.report({ message: messages.expected, node: atRule, result, ruleName, word: pathStripped }); return; } const isScssPartial = extension === "scss"; if (extension && isScssPartial && expectation === "never") { if (context.fix) { const extPattern = new RegExp(`\\.${extension}(['" ]*)$`, "g"); atRule.params = atRule.params.replace(extPattern, "$1"); return; } const dotExt = `.${extension}`; const index = atRuleParamIndex(atRule) + atRule.params.lastIndexOf(dotExt); utils.report({ message: messages.rejected(extension), node: atRule, index, endIndex: index + dotExt.length, result, ruleName }); } }); }); }; } rule.ruleName = ruleName; rule.messages = messages; rule.meta = meta; module.exports = rule;