From a0246353d554c0f74fbdddbb56e7a3a0733dcc90 Mon Sep 17 00:00:00 2001 From: Astrael1 <33071364+Astrael1@users.noreply.github.com> Date: Tue, 15 Oct 2024 01:17:03 +0200 Subject: [PATCH] Don't apply `properties-alphabetical-order` autofixing if there are no violations. Fixes #59 (#198) --- .../checkChild.js | 55 ++++++++++++++++ .../checkNode.js | 63 +++---------------- rules/properties-alphabetical-order/index.js | 3 +- .../isOrderCorrect.js | 9 +++ .../tests/index.js | 3 + 5 files changed, 79 insertions(+), 54 deletions(-) create mode 100644 rules/properties-alphabetical-order/checkChild.js create mode 100644 rules/properties-alphabetical-order/isOrderCorrect.js diff --git a/rules/properties-alphabetical-order/checkChild.js b/rules/properties-alphabetical-order/checkChild.js new file mode 100644 index 0000000..6a44fd4 --- /dev/null +++ b/rules/properties-alphabetical-order/checkChild.js @@ -0,0 +1,55 @@ +import { isStandardSyntaxProperty } from '../../utils/isStandardSyntaxProperty.js'; +import { isCustomProperty } from '../../utils/isCustomProperty.js'; +import * as vendor from '../../utils/vendor.js'; +import { checkAlphabeticalOrder } from '../checkAlphabeticalOrder.js'; + +export function checkChild(child, allPropData) { + if (child.type !== 'decl') { + return null; + } + + let { prop } = child; + + if (!isStandardSyntaxProperty(prop)) { + return null; + } + + if (isCustomProperty(prop)) { + return null; + } + + let unprefixedPropName = vendor.unprefixed(prop); + + // Hack to allow -moz-osx-font-smoothing to be understood + // just like -webkit-font-smoothing + if (unprefixedPropName.startsWith('osx-')) { + unprefixedPropName = unprefixedPropName.slice(4); + } + + let propData = { + name: prop, + unprefixedName: unprefixedPropName, + index: allPropData.length, + node: child, + }; + + let previousPropData = allPropData[allPropData.length - 1]; // eslint-disable-line unicorn/prefer-at -- Need to support older Node.js + + allPropData.push(propData); + + // Skip first decl + if (!previousPropData) { + return null; + } + + let isCorrectOrder = checkAlphabeticalOrder(previousPropData, propData); + + if (isCorrectOrder) { + return null; + } + + return { + expectedFirst: propData.name, + expectedSecond: previousPropData.name, + }; +} diff --git a/rules/properties-alphabetical-order/checkNode.js b/rules/properties-alphabetical-order/checkNode.js index 9ab9324..ac1caaf 100644 --- a/rules/properties-alphabetical-order/checkNode.js +++ b/rules/properties-alphabetical-order/checkNode.js @@ -1,63 +1,20 @@ import stylelint from 'stylelint'; -import { checkAlphabeticalOrder } from '../checkAlphabeticalOrder.js'; -import { isCustomProperty } from '../../utils/isCustomProperty.js'; -import { isStandardSyntaxProperty } from '../../utils/isStandardSyntaxProperty.js'; -import * as vendor from '../../utils/vendor.js'; +import { checkChild } from './checkChild.js'; // eslint-disable-next-line max-params export function checkNode(node, result, ruleName, messages) { let allPropData = []; node.each(function processEveryNode(child) { - if (child.type !== 'decl') { - return; + const problem = checkChild(child, allPropData); + + if (problem) { + stylelint.utils.report({ + message: messages.expected(problem.expectedFirst, problem.expectedSecond), + node: child, + result, + ruleName, + }); } - - let { prop } = child; - - if (!isStandardSyntaxProperty(prop)) { - return; - } - - if (isCustomProperty(prop)) { - return; - } - - let unprefixedPropName = vendor.unprefixed(prop); - - // Hack to allow -moz-osx-font-smoothing to be understood - // just like -webkit-font-smoothing - if (unprefixedPropName.startsWith('osx-')) { - unprefixedPropName = unprefixedPropName.slice(4); - } - - let propData = { - name: prop, - unprefixedName: unprefixedPropName, - index: allPropData.length, - node: child, - }; - - let previousPropData = allPropData[allPropData.length - 1]; // eslint-disable-line unicorn/prefer-at -- Need to support older Node.js - - allPropData.push(propData); - - // Skip first decl - if (!previousPropData) { - return; - } - - let isCorrectOrder = checkAlphabeticalOrder(previousPropData, propData); - - if (isCorrectOrder) { - return; - } - - stylelint.utils.report({ - message: messages.expected(propData.name, previousPropData.name), - node: child, - result, - ruleName, - }); }); } diff --git a/rules/properties-alphabetical-order/index.js b/rules/properties-alphabetical-order/index.js index 44b1288..ff09c8f 100644 --- a/rules/properties-alphabetical-order/index.js +++ b/rules/properties-alphabetical-order/index.js @@ -4,6 +4,7 @@ import { checkNode } from './checkNode.js'; import { namespace } from '../../utils/namespace.js'; import { getContainingNode } from '../../utils/getContainingNode.js'; import { isRuleWithNodes } from '../../utils/isRuleWithNodes.js'; +import { isOrderCorrect } from './isOrderCorrect.js'; let ruleName = namespace('properties-alphabetical-order'); @@ -35,7 +36,7 @@ export function rule(actual, options, context = {}) { processedParents.push(node); if (isRuleWithNodes(node)) { - if (context.fix) { + if (context.fix && !isOrderCorrect(node)) { sortNodeProperties(node, { order: 'alphabetical' }); // log warnings if any problems weren't fixed diff --git a/rules/properties-alphabetical-order/isOrderCorrect.js b/rules/properties-alphabetical-order/isOrderCorrect.js new file mode 100644 index 0000000..d215d1e --- /dev/null +++ b/rules/properties-alphabetical-order/isOrderCorrect.js @@ -0,0 +1,9 @@ +import { checkChild } from './checkChild.js'; + +export function isOrderCorrect(node) { + const allPropData = []; + + return node.every(function isChildCorrect(child) { + return !checkChild(child, allPropData); + }); +} diff --git a/rules/properties-alphabetical-order/tests/index.js b/rules/properties-alphabetical-order/tests/index.js index 6df8199..e5a2542 100644 --- a/rules/properties-alphabetical-order/tests/index.js +++ b/rules/properties-alphabetical-order/tests/index.js @@ -68,6 +68,9 @@ testRule({ { code: 'a { font-size: 1px; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialised; font-weight: bold; }', }, + { + code: 'a { color: #000; span { bottom: 1em; top: 1em; } width: 25%;}', + }, { // blocked by https://github.com/hudochenkov/stylelint-order/issues/78 skip: true,