"use strict" const functionArgumentsSearch = require("../../utils/functionArgumentsSearch") const report = require("../../utils/report") const ruleMessages = require("../../utils/ruleMessages") const validateOptions = require("../../utils/validateOptions") const postcss = require("postcss") 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 } const rule = function (actual) { return (root, result) => { const validOptions = validateOptions(result, ruleName, { actual }) if (!validOptions) { return } root.walkDecls(decl => { functionArgumentsSearch(decl.toString().toLowerCase(), "linear-gradient", (expression, expressionIndex) => { const firstArg = expression.split(",")[0].trim() // 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(decl.value) if (!isStandardDirection(firstArg, withToPrefix)) { complain() return } function complain() { report({ message: messages.rejected, node: decl, index: expressionIndex, result, ruleName, }) } }) }) } } rule.ruleName = ruleName rule.messages = messages module.exports = rule