From 8804caf3f52f7382fe760a93b7ea80056772e3eb Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 1 Jun 2017 01:18:58 +0200 Subject: [PATCH] build: add stylelint rule to prevent usage of /deep/ (#4841) * build: add stylelint rule to prevent usage of /deep/ Adds a custom Stylelint rule to prevent usages of `/deep/` inside selectors. Relates #4726. * fix: address feedback --- stylelint-config.json | 4 ++- tools/stylelint/selector-no-deep/index.js | 37 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tools/stylelint/selector-no-deep/index.js diff --git a/stylelint-config.json b/stylelint-config.json index 55e160bd08a..10315a50cf7 100644 --- a/stylelint-config.json +++ b/stylelint-config.json @@ -1,10 +1,12 @@ { "plugins": [ "./tools/stylelint/no-prefixes/no-prefixes.js", - "./tools/stylelint/selector-nested-pattern-scoped/index.js" + "./tools/stylelint/selector-nested-pattern-scoped/index.js", + "./tools/stylelint/selector-no-deep/index.js" ], "rules": { "material/no-prefixes": [["last 2 versions", "not ie <= 10", "not ie_mob <= 10"]], + "material/selector-no-deep": 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/selector-no-deep/index.js b/tools/stylelint/selector-no-deep/index.js new file mode 100644 index 00000000000..093e229e359 --- /dev/null +++ b/tools/stylelint/selector-no-deep/index.js @@ -0,0 +1,37 @@ +const stylelint = require('stylelint'); +const isStandardSyntaxRule = require('stylelint/lib/utils/isStandardSyntaxRule'); +const isStandardSyntaxSelector = require('stylelint/lib/utils/isStandardSyntaxSelector'); + +const ruleName = 'material/selector-no-deep'; +const messages = stylelint.utils.ruleMessages(ruleName, { + expected: selector => `Usage of the /deep/ in "${selector}" is not allowed`, +}); + + +/** + * Stylelint plugin that prevents uses of /deep/ in selectors. + */ +const plugin = stylelint.createPlugin(ruleName, isEnabled => { + return (root, result) => { + if (!isEnabled) return; + + root.walkRules(rule => { + if (rule.parent.type === 'rule' && + isStandardSyntaxRule(rule) && + isStandardSyntaxSelector(rule.selector) && + rule.selector.includes('/deep/')) { + + stylelint.utils.report({ + result, + ruleName, + message: messages.expected(rule.selector), + node: rule + }); + } + }); + }; +}); + +plugin.ruleName = ruleName; +plugin.messages = messages; +module.exports = plugin;