Last active
March 10, 2016 06:33
-
-
Save ryanjames/8498772759b86aa2bd96 to your computer and use it in GitHub Desktop.
BEV Selector Parsing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// BEVM Selector Processing | |
// Quick string replace function | |
@function str-replace($string, $search, $replace: '') { | |
$index: str-index($string, $search); | |
@if $index { | |
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); | |
} | |
@return $string; | |
} | |
// Check if a chunk has any variations | |
@function hasVariation($chunk) { | |
$output: str-index($chunk, '--'); | |
@return $output; | |
} | |
// Check if a chunk has any elements | |
@function hasElement($chunk) { | |
$output: str-index($chunk, '__'); | |
@return $output; | |
} | |
@function stripSelectorType($chunk) { | |
$output: str-replace($chunk,'%',''); | |
$output: str-replace($output,'.',''); | |
@return $output; | |
} | |
// If the BEVM isn't assuming any parents, we parse it alone. | |
@function parseParentlessBEVM($chunk) { | |
$block: $chunk; | |
$variation: null; | |
@if hasVariation($chunk) { | |
$variationIndex: str-index($chunk, '--'); | |
$variation: str-slice($chunk, $variationIndex, -1); | |
@if hasElement($variation) { | |
$variation: null; | |
} | |
@else { | |
$block: str-slice($chunk, 1, $variationIndex - 1); | |
@if hasVariation($variation) { | |
$variationIndex: str-index($variation, '--'); | |
$block: #{$block}#{str-slice($variation, 1, $variationIndex - 1)}; | |
$variation: str-slice($variation, $variationIndex, -1); | |
} | |
} | |
} | |
@return ( | |
type: mixed, | |
block: $block, | |
variation: $variation, | |
modifier: null | |
); | |
} | |
@function parseBEVMSelector($selector) { | |
// Default BEVM model | |
$BEVM: ( | |
block: $selector, | |
variation: null, | |
modifier: null, | |
type: basic | |
); | |
@if str-index($selector, '-') == 1 and str-index($selector, '--') != 1 { | |
// If the selector is a -modifier of its parent | |
$block: stripSelectorType('#{&}'); | |
$BEVM: map-merge($BEVM, ( | |
block: '#{$block} .#{$selector}', | |
variation: null, | |
modifier: #{$selector}, | |
type: modifier | |
)); | |
} | |
@else if str-index($selector, '--') == 1 { | |
// If the selector is a --variation requiring its parent as part of the class name | |
$variation: $selector; | |
$block: stripSelectorType('#{&}'); | |
// If there's an element declared after the variation delimiter, it's just a variation. | |
@if hasElement($variation) { | |
$block: #{$block}#{$selector}; | |
$variation: null; | |
} | |
$BEVM: map-merge($BEVM, ( | |
block: $block, | |
variation: $variation, | |
modifier: null, | |
type: variation | |
)); | |
} | |
@else { | |
@if str-index($selector, '__') == 1 { | |
// If the selector is an __element requiring its parent as part of the class name | |
$block: stripSelectorType('#{&}'); | |
$BEVM: map-merge($BEVM, ( | |
block: #{$block}#{$selector}, | |
variation: null, | |
type: element | |
)); | |
} | |
// If the selector is not assuming any parents | |
@else { | |
$BEVM: parseParentlessBEVM($selector); | |
} | |
} | |
@return $BEVM; | |
} | |
@mixin _($selector, $buildClass: null) { | |
$BEVM: parseBEVMSelector($selector); | |
$type: map-get($BEVM, type); | |
$block: map-get($BEVM, block); | |
$variation: map-get($BEVM, variation); | |
$modifier: map-get($BEVM, modifier); | |
@at-root { | |
// Every new model gets a placeholder. | |
%#{$block}#{$variation} { | |
@if $variation { | |
@extend %#{$block}; | |
}; | |
@content; | |
} | |
// If we want to build a class. | |
@if $buildClass or $modifier { | |
.#{$block}#{$variation} { | |
@if $variation { | |
@extend %#{$block}; | |
}; | |
@content; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment