Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix function-linear-gradient-no-nonstandard-direction performance #6924

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/popular-cougars-build.md
@@ -0,0 +1,5 @@
---
"stylelint": patch
---

Fixed: `function-linear-gradient-no-nonstandard-direction` performance
Expand Up @@ -19,14 +19,23 @@ const meta = {
url: 'https://stylelint.io/user-guide/rules/function-linear-gradient-no-nonstandard-direction',
};

const LINEAR_GRADIENT_FUNCTION = '(?:-webkit-|-moz-|-o-|-ms-)?linear-gradient';
const LINEAR_GRADIENT_FUNCTION_CALL = new RegExp(`${LINEAR_GRADIENT_FUNCTION}\\(`, 'i');
const LINEAR_GRADIENT_FUNCTION_NAME = new RegExp(`^${LINEAR_GRADIENT_FUNCTION}$`, 'i');

const DIRECTION = /top|left|bottom|right/i;
const DIRECTION_WITH_TO = new RegExp(`^to (${DIRECTION.source})(?: (${DIRECTION.source}))?$`, 'i');
const DIRECTION_WITHOUT_TO = new RegExp(`^(${DIRECTION.source})(?: (${DIRECTION.source}))?$`, 'i');

const DIGIT = /[\d.]/;
const ANGLE = /^[\d.]+(?:deg|grad|rad|turn)$/;

/**
* @param {string} source
* @param {boolean} withToPrefix
*/
function isStandardDirection(source, withToPrefix) {
const regexp = withToPrefix
? /^to (top|left|bottom|right)(?: (top|left|bottom|right))?$/
: /^(top|left|bottom|right)(?: (top|left|bottom|right))?$/;
const regexp = withToPrefix ? DIRECTION_WITH_TO : DIRECTION_WITHOUT_TO;

const matches = source.match(regexp);

Expand Down Expand Up @@ -56,14 +65,16 @@ const rule = (primary) => {
}

root.walkDecls((decl) => {
if (!LINEAR_GRADIENT_FUNCTION_CALL.test(decl.value)) return;

valueParser(decl.value).walk((valueNode) => {
if (valueNode.type !== 'function') {
return;
}

functionArgumentsSearch(
valueParser.stringify(valueNode).toLowerCase(),
/^(-webkit-|-moz-|-o-|-ms-)?linear-gradient$/i,
LINEAR_GRADIENT_FUNCTION_NAME,
(expression, expressionIndex) => {
const args = expression.split(',');
const firstArg = (args[0] || '').trim();
Expand All @@ -74,8 +85,8 @@ const rule = (primary) => {
}

// If the first character is a number, we can assume the user intends an angle
if (/[\d.]/.test(firstArg.charAt(0))) {
if (/^[\d.]+(?:deg|grad|rad|turn)$/.test(firstArg)) {
if (DIGIT.test(firstArg.charAt(0))) {
if (ANGLE.test(firstArg)) {
return;
}

Expand All @@ -87,7 +98,7 @@ const rule = (primary) => {
// The first argument may not be a direction: it may be an angle,
// or a color stop (in which case user gets default direction, "to bottom")
// cf. https://drafts.csswg.org/css-images-3/#linear-gradient-syntax
if (!/left|right|top|bottom/.test(firstArg)) {
if (!DIRECTION.test(firstArg)) {
return;
}

Expand Down