diff --git a/src/material/badge/_badge-theme.scss b/src/material/badge/_badge-theme.scss index 8807326d67b8..228afcd1171a 100644 --- a/src/material/badge/_badge-theme.scss +++ b/src/material/badge/_badge-theme.scss @@ -18,6 +18,8 @@ $large-size: $default-size + 6; // Mixin for building offset given different sizes @mixin _badge-size($size) { + // This mixin isn't used in the context of a theme so we can disable the ampersand check. + // stylelint-disable material/no-ampersand-beyond-selector-start .mat-badge-content { width: $size; height: $size; @@ -89,6 +91,7 @@ $large-size: $default-size + 6; } } } + // stylelint-enable } @mixin color($config-or-theme) { diff --git a/tools/stylelint/no-ampersand-beyond-selector-start.ts b/tools/stylelint/no-ampersand-beyond-selector-start.ts index 553adcbc3533..3d163777fa38 100644 --- a/tools/stylelint/no-ampersand-beyond-selector-start.ts +++ b/tools/stylelint/no-ampersand-beyond-selector-start.ts @@ -1,6 +1,5 @@ import {createPlugin, utils} from 'stylelint'; import {basename} from 'path'; -import {Node} from './stylelint-postcss-types'; const isStandardSyntaxRule = require('stylelint/lib/utils/isStandardSyntaxRule'); const isStandardSyntaxSelector = require('stylelint/lib/utils/isStandardSyntaxSelector'); @@ -37,44 +36,25 @@ const plugin = createPlugin(ruleName, (isEnabled: boolean, _options?) => { } root.walkRules(rule => { - if ( - rule.parent.type === 'rule' && - isStandardSyntaxRule(rule) && - isStandardSyntaxSelector(rule.selector) && - // Using the ampersand at the beginning is fine, anything else can cause issues in themes. - rule.selector.indexOf('&') > 0) { - - const mixinName = getClosestMixinName(rule); - - // Skip rules inside private mixins. - if (!mixinName || !mixinName.startsWith('_')) { - utils.report({ - result, - ruleName, - message: messages.expected(), - node: rule - }); - } + if (rule.parent.type === 'rule' && + isStandardSyntaxRule(rule) && + isStandardSyntaxSelector(rule.selector) && + hasInvalidAmpersandUsage(rule.selector)) { + utils.report({ + result, + ruleName, + message: messages.expected(), + node: rule + }); } }); }; - - /** Walks up the AST and finds the name of the closest mixin. */ - function getClosestMixinName(node: Node): string | undefined { - let parent = node.parent; - - while (parent) { - if (parent.type === 'atrule' && parent.name === 'mixin') { - return parent.params; - } - - parent = parent.parent; - } - - return undefined; - } }); +function hasInvalidAmpersandUsage(selector: string): boolean { + return selector.split(',').some(part => part.trim().indexOf('&', 1) > -1); +} + plugin.ruleName = ruleName; plugin.messages = messages; export default plugin;