Skip to content

Commit

Permalink
prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
MillerSvt committed May 3, 2024
1 parent a5508ca commit b1219a8
Show file tree
Hide file tree
Showing 15 changed files with 388 additions and 345 deletions.
6 changes: 2 additions & 4 deletions examples/.stylelintrc
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"plugins": [
"stylelint-no-px"
],
"plugins": ["stylelint-no-px"],
"rules": {
"meowtec/no-px": [true],
"meowtec/no-px": [true]
}
}
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./lib/')
export {default} from './lib/index.js';
4 changes: 2 additions & 2 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import jestPreset from 'jest-preset-stylelint';
import stylelint from 'stylelint';
import jestPreset from "jest-preset-stylelint";
import stylelint from "stylelint";
import plugin from "./lib/index.js";

const { getTestRule, getTestRuleConfigs } = jestPreset;
Expand Down
124 changes: 84 additions & 40 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import stylelint from "stylelint";
import valueParser from "postcss-value-parser";

export const ruleName = 'meowtec/no-px';
export const ruleName = "meowtec/no-px";

export const meta = {
fixable: true,
Expand All @@ -17,62 +17,85 @@ export const messages = stylelint.utils.ruleMessages(ruleName, {
});

const defaultSecondaryOptions = {
ignore: ['1px'],
ignore: ["1px"],
remSize: null,
};

function convertPxToRem(pxValue, baseSize) {
const numericValue = parseFloat(pxValue.replace('px', ''));
return `${(numericValue / baseSize).toFixed(5).replace(/\.?0+$/, '')}rem`;
const numericValue = parseFloat(pxValue.replace("px", ""));
return `${(numericValue / baseSize).toFixed(5).replace(/\.?0+$/, "")}rem`;
}

function propInIgnoreList(prop, list) {
return prop && list.some(item => {
return prop.indexOf(item) > -1;
});
return (
prop &&
list.some((item) => {
return prop.indexOf(item) > -1;
})
);
}

function propAddXpxInIgnoreList(prop, list, px) {
const reg = new RegExp('\\s' + px);
return prop && list.some(item => {
return reg.test(item) && prop.indexOf(item.replace(reg, '')) > -1;
});
const reg = new RegExp("\\s" + px);
return (
prop &&
list.some((item) => {
return reg.test(item) && prop.indexOf(item.replace(reg, "")) > -1;
})
);
}

function hasForbiddenPX(node, {ignore = defaultSecondaryOptions.ignore, remSize = null, ignoreFunctions = []}) {
function hasForbiddenPX(
node,
{
ignore = defaultSecondaryOptions.ignore,
remSize = null,
ignoreFunctions = [],
},
) {
const type = node.type;
const value = type === 'decl' ? node.value : node.params;
const prop = type === 'decl' ? node.prop : null;
const value = type === "decl" ? node.value : node.params;
const prop = type === "decl" ? node.prop : null;

const parsed = valueParser(value);
let hasPX = false;

if (type === 'atrule' && node.name === 'media') return;
if (type === 'decl' && propInIgnoreList(node.prop, ignore)) return;
if (type === "atrule" && node.name === "media") return;
if (type === "decl" && propInIgnoreList(node.prop, ignore)) return;

for (const valueNode of parsed.nodes) {
if (
valueNode.type === 'function' &&
(valueNode.value === 'url' || ignoreFunctions.indexOf(valueNode.value) > -1)
valueNode.type === "function" &&
(valueNode.value === "url" ||
ignoreFunctions.indexOf(valueNode.value) > -1)
) {
return false;
}

let matched;
if (valueNode.type === 'word' && (matched = valueNode.value.match(/^([-,+]?\d+(\.\d+)?px)$/))) {
if (
valueNode.type === "word" &&
(matched = valueNode.value.match(/^([-,+]?\d+(\.\d+)?px)$/))
) {
const px = matched[1];

if (px === '0px') {
if (px === "0px") {
return;
}

if (!propAddXpxInIgnoreList(prop, ignore, px) && ignore.indexOf(px) === -1) {
if (
!propAddXpxInIgnoreList(prop, ignore, px) &&
ignore.indexOf(px) === -1
) {
if (remSize) {
valueNode.value = convertPxToRem(px, remSize);
}
hasPX = true;
}
} else if (valueNode.type === 'string' && /(@\{[\w-]+\})px\b/.test(valueNode.value)) {
} else if (
valueNode.type === "string" &&
/(@\{[\w-]+\})px\b/.test(valueNode.value)
) {
if (remSize) {
valueNode.value = convertPxToRem(valueNode.value, remSize);
}
Expand All @@ -89,31 +112,41 @@ function processValueNodes(nodes, prop, options) {
let hasPx = false;

for (const valueNode of nodes) {
if (
valueNode.type === 'function'
) {
if (valueNode.value === 'url' || options.ignoreFunctions.indexOf(valueNode.value) > -1) {
if (valueNode.type === "function") {
if (
valueNode.value === "url" ||
options.ignoreFunctions.indexOf(valueNode.value) > -1
) {
continue;
}

hasPx ||= processValueNodes(valueNode.nodes, prop, options);
}

let matched;
if (valueNode.type === 'word' && (matched = valueNode.value.match(/^([-,+]?\d+(\.\d+)?px)$/))) {
if (
valueNode.type === "word" &&
(matched = valueNode.value.match(/^([-,+]?\d+(\.\d+)?px)$/))
) {
const px = matched[1];

if (px === '0px') {
if (px === "0px") {
continue;
}

if (!propAddXpxInIgnoreList(prop, options.ignore, px) && options.ignore.indexOf(px) === -1) {
if (
!propAddXpxInIgnoreList(prop, options.ignore, px) &&
options.ignore.indexOf(px) === -1
) {
if (options.remSize) {
valueNode.value = convertPxToRem(px, options.remSize);
}
hasPx = true;
}
} else if (valueNode.type === 'string' && /(@\{[\w-]+\})px\b/.test(valueNode.value)) {
} else if (
valueNode.type === "string" &&
/(@\{[\w-]+\})px\b/.test(valueNode.value)
) {
if (options.remSize) {
valueNode.value = convertPxToRem(valueNode.value, options.remSize);
}
Expand All @@ -139,37 +172,48 @@ function processDeclaration(declaration, options) {
return;
}

const {newValue, hasPx} = processValue(declaration.value, declaration.prop, options);
const { newValue, hasPx } = processValue(
declaration.value,
declaration.prop,
options,
);

declaration.value = newValue;

return hasPx;
}

function processAtRule(atRule, options) {
if (atRule.type === 'atrule' && atRule.name === 'media') {
if (atRule.type === "atrule" && atRule.name === "media") {
return;
}

const {newValue, hasPx} = processValue(atRule.params, null, options);
const { newValue, hasPx } = processValue(atRule.params, null, options);

atRule.params = newValue;

return hasPx;
}

function ruleFunction(primaryOption, secondaryOptionObject, context) {
primaryOption = primaryOption || '';
primaryOption = primaryOption || "";

return (root, result) => {
if (!primaryOption) return;

const {ignore = defaultSecondaryOptions.ignore, remSize = null, ignoreFunctions = []} = secondaryOptionObject || defaultSecondaryOptions;
const {
ignore = defaultSecondaryOptions.ignore,
remSize = null,
ignoreFunctions = [],
} = secondaryOptionObject || defaultSecondaryOptions;

secondaryOptionObject = {ignore, remSize, ignoreFunctions};
secondaryOptionObject = { ignore, remSize, ignoreFunctions };

root.walkDecls(declaration => {
if (processDeclaration(declaration, secondaryOptionObject) && !context.fix) {
root.walkDecls((declaration) => {
if (
processDeclaration(declaration, secondaryOptionObject) &&
!context.fix
) {
stylelint.utils.report({
ruleName: ruleName,
result: result,
Expand All @@ -179,7 +223,7 @@ function ruleFunction(primaryOption, secondaryOptionObject, context) {
}
});

root.walkAtRules(atRule => {
root.walkAtRules((atRule) => {
if (processAtRule(atRule, secondaryOptionObject) && !context.fix) {
stylelint.utils.report({
ruleName: ruleName,
Expand All @@ -189,7 +233,7 @@ function ruleFunction(primaryOption, secondaryOptionObject, context) {
});
}
});
}
};
}

ruleFunction.ruleName = ruleName;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"devDependencies": {
"jest": "^29.7.0",
"jest-preset-stylelint": "^7.0.0",
"prettier": "^3.2.5",
"stylelint": "^16.0.0"
},
"dependencies": {
Expand Down
60 changes: 30 additions & 30 deletions test/all.spec.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
import {ruleName, messages} from "../lib/index.js";
import { ruleName, messages } from "../lib/index.js";

testRule({
ruleName,
config: [true, {ignore: []}],
ruleName,
config: [true, { ignore: [] }],

accept: [],
accept: [],

reject: [
{
code: '.foo { border-left: 1px solid #333; }',
message: messages.rem(null),
line: 1,
column: 8,
endLine: 1,
endColumn: 36,
},
{
code: '@width: 1;\n.foo { border-width: ~\'@{width}px solid #333\'; }',
message: messages.rem(null),
line: 2,
column: 8,
endLine: 2,
endColumn: 47,
},
{
code: '@width: 10px;\n.foo { border-width: @width * 2 solid #333; }',
message: messages.rem(null),
line: 1,
column: 1,
endLine: 1,
endColumn: 14,
},
],
reject: [
{
code: ".foo { border-left: 1px solid #333; }",
message: messages.rem(null),
line: 1,
column: 8,
endLine: 1,
endColumn: 36,
},
{
code: "@width: 1;\n.foo { border-width: ~'@{width}px solid #333'; }",
message: messages.rem(null),
line: 2,
column: 8,
endLine: 2,
endColumn: 47,
},
{
code: "@width: 10px;\n.foo { border-width: @width * 2 solid #333; }",
message: messages.rem(null),
line: 1,
column: 1,
endLine: 1,
endColumn: 14,
},
],
});
37 changes: 18 additions & 19 deletions test/always-ignore-media-query.spec.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import {ruleName, messages} from "../lib/index.js";
import { ruleName, messages } from "../lib/index.js";

testRule({
ruleName,
config: [true, {ignore: []}],
ruleName,
config: [true, { ignore: [] }],

accept: [
{
code: '.a { @media screen and (max-width: 370px) {} }',
},
],
accept: [
{
code: ".a { @media screen and (max-width: 370px) {} }",
},
],

reject: [
{
code: '.a { \n@media screen and (max-width: 370px) { \npadding: 10px; } }',
message: messages.rem(null),
line: 3,
column: 1,
endLine: 3,
endColumn: 15,
},
],
reject: [
{
code: ".a { \n@media screen and (max-width: 370px) { \npadding: 10px; } }",
message: messages.rem(null),
line: 3,
column: 1,
endLine: 3,
endColumn: 15,
},
],
});

Loading

0 comments on commit b1219a8

Please sign in to comment.