/* * This is set of mixins to help generating * CSS classes according to the Block__Element--Modifier pattern. * It also helps nesting those classes in any fashion imaganible * and still produces clean BEM CSS */ @import './_laneHandling' _css-prefix = 'RV' _global_scope = { _selector_blocks_to_generate: {} _element-modifier: () _additional-element-modifier-blocks: () _last_element_name: null _blocks_to_generate: () _element_modifier_block_stack: () _element_block_stack: () _element_modifier_stack: {} } _block_building_lane = () _element_building_lange = () _work_lane(lane, callback) l = length(lane) for _ in (0..l) piece = pop(lane) callback(piece) /* * Gets the selector of the parent class */ _get_parent_selector() return split(' ', selector())[-1] /* * Gets the selector of the current block */ _get_block_selector() return unquote(split('__', _get_parent_selector())[0]) _get_element_selector() element--modifier = split('__', _get_parent_selector())[1] return unquote(split('--', element--modifier)[0]) /* * Generates a CSS class for an * Block according to BEM */ RV-Block(block_name) b = @block{ {block} & .{block_name}{ for element_block in _pop_stack('elements_to_generate'){ {element_block} } } &.{block_name}{ for modifier_block in _pop_stack('block_modifiers_to_generate'){ {modifier_block} } } for modifier_block in _pop_stack('after_element_modifiers_to_generate'){ {modifier_block} } _reset_last_name('RV-Element') _reset_last_name('RV-Element__Modifier') _reset_last_name('RV-Block_Modifier') } if 'RV-Block' in called-from {b} else .{block_name} {b} /* * Generates a CSS class for an block modifier * according to BEM. */ RV-Block__Modifier(block_modifier_name) _push_onto_stack(block) //Detect if the selector will be generated //by an earlier call of RV-Block__Modifier if not 'RV-Block__Modifier' in called-from // Saving accumulated modifiers and blocks if 'RV-Block' in called-from elements = _pop_stack('block_modifier_elements_to_generate') modifier_block = @block{ &--{block_modifier_name}{ for sub_block in _pop_stack(){ {sub_block} } & ^[-2..-2]{ for element in elements{ {element} } } } } _push_onto_stack(modifier_block, 'block_modifiers_to_generate') /* * Generates an CSS class for an element * according to BEM. Also minds the element modifiers * For more see RV-Element___Modifier */ RV-Element(element_name) _push_onto_stack(block) //Detect if the selector will be generated //by an earlier call of RV-Element if not 'RV-Element' in called-from // Saving accumulated modifiers and blocks stack_name = 'elements_to_generate' if 'RV-Block__Modifier' in called-from stack_name = 'block_modifier_elements_to_generate' element_block = @block{ &__{element_name}{ for sub_block in _pop_stack(){ {sub_block} } &^[-3..-3]__{element_name}{ for modifier_block in _pop_stack('element_modifiers_to_generate'){ {modifier_block} } } } } _push_onto_stack(element_block, stack_name) _set_last_name(element_name) /* * Generates a CSS class for an element modifier * according to BEM. These are ment to be part of the * content block of an element and since child-mixins * are called first there is no way of knowing what the * current element is named. To solve this, we store * a callback for the modifier and add the element name * from RV-Element */ RV-Element__Modifier(element_modifier_name) _push_onto_stack(block) //Is this modifier beeing included by another modifier if not 'RV-Element__Modifier' in called-from //No, store all blocks under the give name //Is this modifier beeing called in in- or postfix if 'RV-Element' in called-from //Infix, store for handling by element modifier_block = @block{ &--{element_modifier_name}{ for current_block in _pop_stack(){ {current_block} } } } _push_onto_stack(modifier_block, 'element_modifiers_to_generate') else //Postfix, append to existing element last_element_name = _get_last_name('RV-Element') modifier_block = @block { & .{block_name}__{last_element_name}.{block_name}__{last_element_name}--{element_modifier_name}{ for current_block in _pop_stack(){ {current_block} } } } _push_onto_stack(modifier_block, 'after_element_modifiers_to_generate')