Skip to content

Commit

Permalink
[fix] Make BEM more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
xymopen committed Nov 19, 2019
1 parent a83ced2 commit 4419428
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 96 deletions.
55 changes: 23 additions & 32 deletions src/mixins/function.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,34 @@

/* BEM support Func
-------------------------- */
@function selectorToString($selector) {
$selector: inspect($selector);
$selector: str-slice($selector, 2, -2);

@return $selector;
}

@function containsModifier($selector) {
$selector: selectorToString($selector);

@if str-index($selector, $modifier-separator) {
@return true;
} @else {
@return false;
}
}
/// See [Combinators](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors#Combinators "CSS selectors")
$_selector-combinators: ("+", "~", ">", "||");

@function containWhenFlag($selector) {
$selector: selectorToString($selector);
@function bem-extend($selectors, $extendee, $extender) {
$returns: ();

@if str-index($selector, '.' + $state-prefix) {
@return true;
} @else {
@return false;
@if null == $selectors {
$selectors: selector-parse("");
}
}

@function containPseudoClass($selector) {
$selector: selectorToString($selector);

@if str-index($selector, ':') {
@return true;
} @else {
@return false;
@each $selector in $selectors {
$len: length($selector);

@if nth($selector, $len) == $extendee {
@if $len >= 2 {
@if index($_selector-combinators, nth($selector, $len - 1)) == null {
$returns: append($returns, set-nth($selector, $len, $extender), "comma");
} @else {
$returns: append($returns, append($selector, $extender), "comma");
}
} @else {
$returns: append($returns, ($extender), "comma");
}
} @else {
$returns: append($returns, append($selector, $extender), "comma");
}
}
}

@function hitAllSpecialNestRule($selector) {
@return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector);
@return $returns;
}
132 changes: 68 additions & 64 deletions src/mixins/mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,98 +67,102 @@

/* BEM
-------------------------- */

$_BEM: (null, null, null);

@mixin b($block) {
$B: $namespace+'-'+$block !global;
$lastBEM: $_BEM;
$_BEM: ($block, null, null) !global;

.#{$B} {
.#{$namespace}-#{$block} {
@content;
}

$_BEM: $lastBEM !global;
}

@mixin e($element) {
$E: $element !global;
$selector: &;
$currentSelector: "";
@each $unit in $element {
$currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
}
@mixin e($elements) {
$block: nth($_BEM, 1);

@if hitAllSpecialNestRule($selector) {
@at-root {
#{$selector} {
#{$currentSelector} {
@content;
}
}
}
@if null == $block {
@error "Base-level rules cannot contain an element mixin";
} @else {
@at-root {
#{$currentSelector} {
@content;
}
}
}
}
$selects: &;

@mixin m($modifier) {
$selector: &;
$currentSelector: "";
@each $unit in $modifier {
$currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
}
@if (null != nth($_BEM, 2)) {
$selects: ();

@at-root {
#{$currentSelector} {
@content;
@each $old-select in & {
$selects: append($selects, set-nth($old-select, length($old-select), ".#{$namespace}-#{$block}"), "comma")
}
}
}
}

@mixin configurable-m($modifier, $E-flag: false) {
$selector: &;
$interpolation: '';
$lastBEM: $_BEM;
$_BEM: ($block, $elements, null) !global;

@if $E-flag {
$interpolation: $element-separator + $E-flag;
}
$parent: ".#{$namespace}-#{$block}";
$current: ();

@at-root {
#{$selector} {
.#{$B+$interpolation+$modifier-separator+$modifier} {
@each $element in $elements {
$current: append(
$current,
bem-extend($selects, $parent, "#{$parent}#{$element-separator}#{$element}"),
"comma",
);
}

@at-root {
#{$current} {
@content;
}
}

$_BEM: $lastBEM !global;
}
}

@mixin spec-selector($specSelector: '', $element: $E, $modifier: false, $block: $B) {
$modifierCombo: '';
@mixin m($modifiers) {
$block: nth($_BEM, 1);

@if $modifier {
$modifierCombo: $modifier-separator + $modifier;
}
@if null == $block {
@error "Base-level rules cannot contain a modifier mixin";
} @else if null != nth($_BEM, 3) {
@error "Modifier-level rules cannot contain another modifier mixin";
} @else {
$elements: nth($_BEM, 2);

@at-root {
#{&}#{$specSelector}.#{$block+$element-separator+$element+$modifierCombo} {
@content;
@if (null == $elements) {
$elements: (null);
}
}
}

@mixin meb($modifier: false, $element: $E, $block: $B) {
$selector: &;
$modifierCombo: '';
$lastBEM: $_BEM;
$_BEM: ($block, $elements, $modifiers) !global;

@if $modifier {
$modifierCombo: $modifier-separator + $modifier;
}
@each $element in $elements {
$parent: ".#{$namespace}-#{$block}";

@at-root {
#{$selector} {
.#{$block+$element-separator+$element+$modifierCombo} {
@content;
@if (null != $element) {
$parent: "#{$parent}#{$element-separator}#{$element}";
}

$current: ();

@each $modifier in $modifiers {
$current: append(
$current,
bem-extend(&, $parent, "#{$parent}#{$modifier-separator}#{$modifier}"),
"comma",
);
}

@at-root {
#{$current} {
@content;
}
}
}

$_BEM: $lastBEM !global;
}
}

Expand Down

0 comments on commit 4419428

Please sign in to comment.