UNPKG

@salesforce-ux/eslint-plugin-slds

Version:

ESLint plugin provides custom linting rules specifically built for Salesforce Lightning Design System 2 (SLDS 2 beta)

304 lines (297 loc) 9.3 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/utils/hardcoded-shared-utils.ts var hardcoded_shared_utils_exports = {}; __export(hardcoded_shared_utils_exports, { forEachColorValue: () => forEachColorValue, forEachDensityValue: () => forEachDensityValue, forEachFontValue: () => forEachFontValue, forEachValue: () => forEachValue, handleShorthandAutoFix: () => handleShorthandAutoFix, isKnownFontWeight: () => isKnownFontWeight }); module.exports = __toCommonJS(hardcoded_shared_utils_exports); var import_css_tree2 = require("@eslint/css-tree"); // src/utils/value-utils.ts var ALLOWED_UNITS = ["px", "em", "rem", "%", "ch"]; // src/utils/color-lib-utils.ts var import_chroma_js = __toESM(require("chroma-js")); var import_css_tree = require("@eslint/css-tree"); // src/utils/css-functions.ts var CSS_FUNCTIONS = [ "attr", "calc", "color-mix", "conic-gradient", "counter", "cubic-bezier", "linear-gradient", "max", "min", "radial-gradient", "repeating-conic-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "var" ]; var CSS_MATH_FUNCTIONS = ["calc", "min", "max"]; var RGB_COLOR_FUNCTIONS = ["rgb", "rgba", "hsl", "hsla"]; var cssFunctionsRegex = new RegExp(`(?:${CSS_FUNCTIONS.join("|")})`); var cssFunctionsExactRegex = new RegExp(`^(?:${CSS_FUNCTIONS.join("|")})$`); var cssMathFunctionsRegex = new RegExp(`^(?:${CSS_MATH_FUNCTIONS.join("|")})$`); function isCssFunction(value) { return cssFunctionsExactRegex.test(value); } function isCssColorFunction(value) { return RGB_COLOR_FUNCTIONS.includes(value); } // src/utils/color-lib-utils.ts var isValidColor = (val) => import_chroma_js.default.valid(val); var extractColorValue = (node) => { let colorValue = null; switch (node.type) { case "Hash": colorValue = `#${node.value}`; break; case "Identifier": colorValue = node.name; break; case "Function": if (isCssColorFunction(node.name)) { colorValue = (0, import_css_tree.generate)(node); } break; } return colorValue && isValidColor(colorValue) ? colorValue : null; }; // src/utils/hardcoded-shared-utils.ts var FONT_WEIGHTS = [ "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900" ]; function isKnownFontWeight(value) { const stringValue = value.toString(); return FONT_WEIGHTS.includes(stringValue.toLowerCase()); } function handleShorthandAutoFix(declarationNode, context, valueText, replacements) { const sortedReplacements = replacements.sort((a, b) => a.start - b.start); const hasAnyHooks = sortedReplacements.some((r) => r.hasHook); const canAutoFix = hasAnyHooks; sortedReplacements.forEach(({ start, end, replacement, displayValue, hasHook }) => { const originalValue = valueText.substring(start, end); const valueStartColumn = declarationNode.value.loc.start.column; const valueColumn = valueStartColumn + start; const { loc: { start: locStart, end: locEnd } } = declarationNode.value; const reportNode = { ...declarationNode.value, loc: { ...declarationNode.value.loc, start: { ...locStart, column: valueColumn }, end: { ...locEnd, column: valueColumn + originalValue.length } } }; if (hasHook) { const fix = canAutoFix ? (fixer) => { let newValue = valueText; for (let i = sortedReplacements.length - 1; i >= 0; i--) { const { start: rStart, end: rEnd, replacement: rReplacement } = sortedReplacements[i]; newValue = newValue.substring(0, rStart) + rReplacement + newValue.substring(rEnd); } return fixer.replaceText(declarationNode.value, newValue); } : void 0; context.context.report({ node: reportNode, messageId: "hardcodedValue", data: { oldValue: originalValue, newValue: displayValue }, fix }); } else { context.context.report({ node: reportNode, messageId: "noReplacement", data: { oldValue: originalValue } }); } }); } function forEachValue(valueText, extractValue, shouldSkipNode, callback) { if (!valueText || typeof valueText !== "string") { return; } try { const ast = (0, import_css_tree2.parse)(valueText, { context: "value", positions: true }); (0, import_css_tree2.walk)(ast, { enter(node) { if (shouldSkipNode(node)) { return this.skip; } const value = extractValue(node); if (value !== null) { const positionInfo = { start: node.loc?.start, end: node.loc?.end }; callback(value, positionInfo); } } }); } catch (error) { return; } } function shouldSkipColorNode(node) { return node.type === "Function" && isCssFunction(node.name); } function shouldSkipDimensionNode(node) { return node.type === "Function"; } function extractDimensionValue(valueNode, cssProperty) { if (!valueNode) return null; switch (valueNode.type) { case "Dimension": const numValue = Number(valueNode.value); if (numValue === 0) return null; const unit = valueNode.unit.toLowerCase(); if (!ALLOWED_UNITS.includes(unit)) return null; return { number: numValue, unit }; case "Number": const numberValue = Number(valueNode.value); if (numberValue === 0) return null; return { number: numberValue, unit: null }; case "Percentage": const percentValue = Number(valueNode.value); if (percentValue === 0) return null; return { number: percentValue, unit: "%" }; case "Value": return valueNode.children?.[0] ? extractDimensionValue(valueNode.children[0], cssProperty) : null; } return null; } function forEachColorValue(valueText, callback) { forEachValue(valueText, extractColorValue, shouldSkipColorNode, callback); } function forEachDensityValue(valueText, cssProperty, callback) { forEachValue( valueText, (node) => extractDimensionValue(node, cssProperty), shouldSkipDimensionNode, callback ); } function extractFontValue(node) { if (!node) return null; switch (node.type) { case "Dimension": const numValue = Number(node.value); if (numValue <= 0) return null; const unit = node.unit.toLowerCase(); if (!ALLOWED_UNITS.includes(unit)) return null; return { number: numValue, unit }; case "Number": const numberValue = Number(node.value); if (numberValue <= 0) { return null; } if (!isKnownFontWeight(numberValue)) { return null; } return { number: numberValue, unit: null }; case "Identifier": const namedValue = node.name.toLowerCase(); if (!isKnownFontWeight(namedValue)) { return null; } if (namedValue === "normal") { return { number: 400, unit: null }; } return { number: namedValue, unit: null }; case "Percentage": const percentValue = Number(node.value); if (percentValue === 0) return null; return { number: percentValue, unit: "%" }; case "Value": return node.children?.[0] ? extractFontValue(node.children[0]) : null; } return null; } function shouldSkipFontNode(node) { return node.type === "Function"; } function forEachFontValue(valueText, callback) { forEachValue(valueText, extractFontValue, shouldSkipFontNode, callback); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { forEachColorValue, forEachDensityValue, forEachFontValue, forEachValue, handleShorthandAutoFix, isKnownFontWeight }); //# sourceMappingURL=hardcoded-shared-utils.js.map