stylelint
Version:
A mighty CSS linter that helps you avoid errors and enforce conventions.
144 lines (127 loc) • 3.91 kB
JavaScript
import { isRegExp, isString } from '../../utils/validateTypes.mjs';
import isStandardSyntaxDeclaration from '../../utils/isStandardSyntaxDeclaration.mjs';
import optionsMatches from '../../utils/optionsMatches.mjs';
import report from '../../utils/report.mjs';
import ruleMessages from '../../utils/ruleMessages.mjs';
import validateOptions from '../../utils/validateOptions.mjs';
const ruleName = 'property-no-deprecated';
const messages = ruleMessages(ruleName, {
expected: (unfixed, fixed) => `Expected "${unfixed}" to be "${fixed}"`,
rejected: (property) => `Unexpected deprecated property "${property}"`,
});
const meta = {
url: 'https://stylelint.io/user-guide/rules/property-no-deprecated',
fixable: true,
};
/** @type {Record<string, string | null>} */
const DEPRECATED_PROPS_REMAP = {
'-khtml-box-align': 'align-items',
'-khtml-box-direction': null,
'-khtml-box-flex': 'flex-grow',
'-khtml-box-lines': null,
'-khtml-box-ordinal-group': 'order',
'-khtml-box-orient': null,
'-khtml-box-pack': null,
'-khtml-user-modify': null,
'-moz-box-align': 'align-items',
'-moz-box-direction': null,
'-moz-box-flex': 'flex-grow',
'-moz-box-lines': null,
'-moz-box-ordinal-group': 'order',
'-moz-box-orient': null,
'-moz-box-pack': null,
'-moz-user-modify': null,
'-ms-box-align': 'align-items',
'-ms-box-direction': null,
'-ms-box-flex': 'flex-grow',
'-ms-box-lines': null,
'-ms-box-ordinal-group': 'order',
'-ms-box-orient': null,
'-ms-box-pack': null,
'-webkit-box-align': 'align-items',
'-webkit-box-direction': null,
'-webkit-box-flex': 'flex-grow',
'-webkit-box-lines': null,
'-webkit-box-ordinal-group': 'order',
'-webkit-box-orient': null, // Allowed when the value is `vertical`
'-webkit-box-pack': null,
'-webkit-user-modify': null,
'grid-column-gap': 'column-gap',
'grid-gap': 'gap',
'grid-row-gap': 'row-gap',
'ime-mode': null,
'page-break-after': 'break-after',
'page-break-before': 'break-before',
'page-break-inside': 'break-inside',
'position-try-options': 'position-try-fallbacks',
'scroll-snap-coordinate': null,
'scroll-snap-destination': null,
'scroll-snap-margin-bottom': 'scroll-margin-bottom',
'scroll-snap-margin-left': 'scroll-margin-left',
'scroll-snap-margin-right': 'scroll-margin-right',
'scroll-snap-margin-top': 'scroll-margin-top',
'scroll-snap-margin': 'scroll-margin',
'scroll-snap-points-x': null,
'scroll-snap-points-y': null,
'scroll-snap-type-x': null,
'scroll-snap-type-y': null,
'word-wrap': 'overflow-wrap',
clip: null,
};
/** @type {import('stylelint').CoreRules[ruleName]} */
const rule = (primary, secondaryOptions) => {
return (root, result) => {
const validOptions = validateOptions(
result,
ruleName,
{ actual: primary },
{
actual: secondaryOptions,
possible: {
ignoreProperties: [isString, isRegExp],
},
optional: true,
},
);
if (!validOptions) return;
root.walkDecls((decl) => {
if (!isStandardSyntaxDeclaration(decl)) return;
const { prop, value } = decl;
if (optionsMatches(secondaryOptions, 'ignoreProperties', prop)) return;
const normalizedProp = prop.toLowerCase();
const mappedProp = DEPRECATED_PROPS_REMAP[normalizedProp];
if (typeof mappedProp === 'undefined') return;
if (normalizedProp === '-webkit-box-orient' && value.toLowerCase() === 'vertical') return;
let fix;
let message;
let messageArgs = [];
if (mappedProp) {
message = messages.expected;
messageArgs = [prop, mappedProp];
fix = () => {
decl.prop = mappedProp;
};
} else {
message = messages.rejected;
messageArgs = [prop];
}
report({
message,
messageArgs,
node: decl,
index: 0,
endIndex: prop.length,
result,
ruleName,
fix: {
apply: fix,
node: decl,
},
});
});
};
};
rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = meta;
export default rule;