3 const _ = require("lodash");
4 const atRuleParamIndex = require("../../utils/atRuleParamIndex");
5 const functionArgumentsSearch = require("../../utils/functionArgumentsSearch");
6 const isStandardSyntaxUrl = require("../../utils/isStandardSyntaxUrl");
7 const optionsMatches = require("../../utils/optionsMatches");
8 const report = require("../../utils/report");
9 const ruleMessages = require("../../utils/ruleMessages");
10 const validateOptions = require("../../utils/validateOptions");
12 const ruleName = "function-url-quotes";
14 const messages = ruleMessages(ruleName, {
15 expected: () => "Expected quotes",
16 rejected: () => "Unexpected quotes"
19 const rule = function(expectation, options) {
20 return (root, result) => {
21 const validOptions = validateOptions(
26 possible: ["always", "never"]
40 root.walkAtRules(checkStatement);
41 root.walkRules(checkStatement);
43 function checkStatement(statement) {
44 if (statement.type === "atrule") {
45 checkAtRuleParams(statement);
48 statement.walkDecls(function(decl) {
49 functionArgumentsSearch(
50 decl.toString().toLowerCase(),
53 checkArgs(args, decl, index, "url");
59 function checkAtRuleParams(atRule) {
60 const atRuleParamsLowerCase = atRule.params.toLowerCase();
61 functionArgumentsSearch(atRuleParamsLowerCase, "url", (args, index) => {
62 checkArgs(args, atRule, index + atRuleParamIndex(atRule), "url");
64 functionArgumentsSearch(
65 atRuleParamsLowerCase,
71 index + atRuleParamIndex(atRule),
76 functionArgumentsSearch(
77 atRuleParamsLowerCase,
80 checkArgs(args, atRule, index + atRuleParamIndex(atRule), "domain");
85 function checkArgs(args, node, index, functionName) {
86 let shouldHasQuotes = expectation === "always";
88 const leftTrimmedArgs = args.trimLeft();
89 if (!isStandardSyntaxUrl(leftTrimmedArgs)) {
92 const complaintIndex = index + args.length - leftTrimmedArgs.length;
94 leftTrimmedArgs[0] === "'" || leftTrimmedArgs[0] === '"';
96 const trimmedArg = args.trim();
97 const isEmptyArgument = _.includes(["", "''", '""'], trimmedArg);
98 if (optionsMatches(options, "except", "empty") && isEmptyArgument) {
99 shouldHasQuotes = !shouldHasQuotes;
102 if (shouldHasQuotes) {
106 complain(messages.expected(functionName), node, complaintIndex);
111 complain(messages.rejected(functionName), node, complaintIndex);
115 function complain(message, node, index) {
127 rule.ruleName = ruleName;
128 rule.messages = messages;
129 module.exports = rule;