From 60215672f9db956c1c0befb43ec68891e99ade5e Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sun, 25 Jun 2017 16:07:15 +0200 Subject: [PATCH] build: add stylelint rule to prevent nested mixins Adds a Stylelint rule that will prevent uses of nested mixins. This will help prevent issues like #5232 in the future. --- stylelint-config.json | 4 ++- tools/stylelint/no-nested-mixin/index.js | 35 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tools/stylelint/no-nested-mixin/index.js diff --git a/stylelint-config.json b/stylelint-config.json index 10315a50cf70..b53b06be1078 100644 --- a/stylelint-config.json +++ b/stylelint-config.json @@ -2,11 +2,13 @@ "plugins": [ "./tools/stylelint/no-prefixes/no-prefixes.js", "./tools/stylelint/selector-nested-pattern-scoped/index.js", - "./tools/stylelint/selector-no-deep/index.js" + "./tools/stylelint/selector-no-deep/index.js", + "./tools/stylelint/no-nested-mixin/index.js" ], "rules": { "material/no-prefixes": [["last 2 versions", "not ie <= 10", "not ie_mob <= 10"]], "material/selector-no-deep": true, + "material/no-nested-mixin": true, "material/selector-nested-pattern-scoped": [".*[^&]$", { "message": "The & operator is not allowed at the end of theme selectors.", "filePattern": "-theme\\.scss$" diff --git a/tools/stylelint/no-nested-mixin/index.js b/tools/stylelint/no-nested-mixin/index.js new file mode 100644 index 000000000000..ec4baf9ee282 --- /dev/null +++ b/tools/stylelint/no-nested-mixin/index.js @@ -0,0 +1,35 @@ +const stylelint = require('stylelint'); + +const ruleName = 'material/no-nested-mixin'; +const messages = stylelint.utils.ruleMessages(ruleName, { + expected: () => 'Nested mixins are not allowed.', +}); + + +/** + * Stylelint plugin that prevents nesting SASS mixins. + */ +const plugin = stylelint.createPlugin(ruleName, isEnabled => { + return (root, result) => { + if (!isEnabled) return; + + root.walkAtRules(rule => { + if (rule.name !== 'mixin') return; + + rule.walkAtRules(childRule => { + if (childRule.name !== 'mixin') return; + + stylelint.utils.report({ + result, + ruleName, + message: messages.expected(), + node: childRule + }); + }); + }); + }; +}); + +plugin.ruleName = ruleName; +plugin.messages = messages; +module.exports = plugin;