@ec0lint/plugin-css
Version:
ec0lint plugin that provides rules to verify CSS definition objects
133 lines (132 loc) • 5.64 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils");
const postcss_value_parser_1 = __importDefault(require("postcss-value-parser"));
const regexp_1 = require("../utils/regexp");
const resource_1 = require("../utils/resource");
const css_utils_1 = require("../utils/css-utils");
exports.default = (0, utils_1.createRule)("no-unknown-unit", {
meta: {
docs: {
description: "disallow unknown units",
category: "Possible Errors",
recommended: true,
stylelint: "unit-no-unknown",
},
schema: [
{
type: "object",
properties: {
ignoreFunctions: {
type: "array",
items: {
type: "string",
},
uniqueItems: true,
minItems: 1,
},
ignoreUnits: {
type: "array",
items: {
type: "string",
},
uniqueItems: true,
minItems: 1,
},
},
additionalProperties: false,
},
],
messages: {
unknown: "Unexpected unknown unit '{{unit}}'.",
},
type: "problem",
},
create(context) {
var _a, _b, _c, _d;
const ignoreFunctions = [
...((_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.ignoreFunctions) !== null && _b !== void 0 ? _b : []),
].map(regexp_1.toRegExp);
const ignoreUnits = [...((_d = (_c = context.options[0]) === null || _c === void 0 ? void 0 : _c.ignoreUnits) !== null && _d !== void 0 ? _d : [])].map(regexp_1.toRegExp);
function createVisitor(_cssContext) {
return {
onProperty(property) {
const value = property.getValue();
if (!value) {
return;
}
const parsedValue = (0, postcss_value_parser_1.default)(String(value.value).replace(/\*/gu, ","));
parsedValue.walk((node) => {
var _a;
if (node.type === "function" &&
(node.value.toLowerCase() === "url" ||
ignoreFunctions.some((r) => r.test(node.value))))
return false;
const unit = getUnitFromValueNode(node);
if (!unit || ignoreUnits.some((r) => r.test(unit))) {
return undefined;
}
if (resource_1.UNITS.has(unit) && unit !== "x") {
return undefined;
}
if (unit === "x") {
if (((_a = property.getName()) === null || _a === void 0 ? void 0 : _a.name.toLowerCase()) ===
"image-resolution") {
return undefined;
}
const imageSet = parsedValue.nodes.find((n) => n.type === "function" &&
(0, css_utils_1.stripVendorPrefix)(n.value) === "image-set");
if (imageSet) {
const imageSetLastNode = imageSet.nodes[imageSet.nodes.length - 1];
if (imageSetLastNode.sourceIndex >=
node.sourceIndex) {
return undefined;
}
}
}
const sourceCode = context.getSourceCode();
const startIndex = value.expression.range[0] +
node.sourceIndex +
1;
const endIndex = startIndex + node.value.length;
const loc = value.directExpression
? {
start: sourceCode.getLocFromIndex(startIndex),
end: sourceCode.getLocFromIndex(endIndex),
}
: undefined;
context.report({
node: value.expression,
loc,
messageId: "unknown",
data: {
unit,
},
});
return undefined;
});
},
};
}
return (0, utils_1.defineCSSVisitor)(context, {
createVisitor,
});
},
});
function getUnitFromValueNode(node) {
if (!node.value) {
return null;
}
if (node.type !== "word" ||
node.value.startsWith("#")) {
return null;
}
const parsedUnit = postcss_value_parser_1.default.unit(node.value);
if (!parsedUnit) {
return null;
}
return parsedUnit.unit.toLowerCase();
}