diff options
Diffstat (limited to 'assets/node_modules/stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction/index.js')
-rw-r--r-- | assets/node_modules/stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction/index.js | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/assets/node_modules/stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction/index.js b/assets/node_modules/stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction/index.js new file mode 100644 index 0000000..affec4d --- /dev/null +++ b/assets/node_modules/stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction/index.js @@ -0,0 +1,108 @@ +'use strict'; + +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const functionArgumentsSearch = require('../../utils/functionArgumentsSearch'); +const isStandardSyntaxValue = require('../../utils/isStandardSyntaxValue'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); +const valueParser = require('postcss-value-parser'); + +const ruleName = 'function-linear-gradient-no-nonstandard-direction'; + +const messages = ruleMessages(ruleName, { + rejected: 'Unexpected nonstandard direction', +}); + +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 matches = source.match(regexp); + + if (!matches) { + return false; + } + + if (matches.length === 2) { + return true; + } + + // Cannot repeat side-or-corner, e.g. "to top top" + if (matches.length === 3 && matches[1] !== matches[2]) { + return true; + } + + return false; +} + +function rule(actual) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { actual }); + + if (!validOptions) { + return; + } + + root.walkDecls((decl) => { + valueParser(decl.value).walk((valueNode) => { + if (valueNode.type !== 'function') { + return; + } + + functionArgumentsSearch( + valueParser.stringify(valueNode).toLowerCase(), + 'linear-gradient', + (expression, expressionIndex) => { + const firstArg = expression.split(',')[0].trim(); + + // If the first arg is not standard, return early + if (!isStandardSyntaxValue(firstArg)) { + return; + } + + // If the first character is a number, we can assume the user intends an angle + if (/[\d.]/.test(firstArg[0])) { + if (/^[\d.]+(?:deg|grad|rad|turn)$/.test(firstArg)) { + return; + } + + complain(); + + return; + } + + // 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)) { + return; + } + + const withToPrefix = !postcss.vendor.prefix(valueNode.value); + + if (!isStandardDirection(firstArg, withToPrefix)) { + complain(); + } + + function complain() { + report({ + message: messages.rejected, + node: decl, + index: declarationValueIndex(decl) + valueNode.sourceIndex + expressionIndex, + result, + ruleName, + }); + } + }, + ); + }); + }); + }; +} + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; |