I think i finally got it
This commit is contained in:
		@@ -4,6 +4,7 @@
 | 
			
		||||
 * It also helps nesting those classes in any fashion imaganible
 | 
			
		||||
 * and still produces clean BEM CSS
 | 
			
		||||
 */
 | 
			
		||||
@import './_laneHandling'
 | 
			
		||||
 | 
			
		||||
_css-prefix = 'RV'
 | 
			
		||||
_global_scope = {
 | 
			
		||||
@@ -49,56 +50,98 @@ _get_element_selector()
 | 
			
		||||
 * Generates a CSS class for an
 | 
			
		||||
 * Block according to BEM
 | 
			
		||||
 */
 | 
			
		||||
RV-Block(name)
 | 
			
		||||
	.{name}
 | 
			
		||||
RV-Block(block_name)
 | 
			
		||||
	b = @block{
 | 
			
		||||
		{block}
 | 
			
		||||
		& .{block_name}{
 | 
			
		||||
			for element_block in _pop_stack('elements_to_generate'){
 | 
			
		||||
				{element_block}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		for element_name, element in _global_scope['_selector_blocks_to_generate']
 | 
			
		||||
			& .{name}__{element_name}
 | 
			
		||||
				for current_block in element.block_list
 | 
			
		||||
					{current_block}
 | 
			
		||||
				for modifier_name, modifier_block_list in element.modifier_list
 | 
			
		||||
					&--{modifier_name}
 | 
			
		||||
						for current_block in modifier_block_list
 | 
			
		||||
							{current_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(name)
 | 
			
		||||
	if 'RV-Block__Modifier' in called-from
 | 
			
		||||
		{block}
 | 
			
		||||
	else
 | 
			
		||||
		&{_get_block_selector()}--{name}
 | 
			
		||||
			{block}
 | 
			
		||||
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(name)
 | 
			
		||||
	push(_global_scope['_element_block_stack'], block)
 | 
			
		||||
	
 | 
			
		||||
	current_block = _block_building_lane[-1]
 | 
			
		||||
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
 | 
			
		||||
		element = {}
 | 
			
		||||
		element['block_list'] = _global_scope['_element_block_stack']
 | 
			
		||||
		element['modifier_list'] = _global_scope['_element_modifier_stack']
 | 
			
		||||
		stack_name = 'elements_to_generate'
 | 
			
		||||
		if 'RV-Block__Modifier' in called-from
 | 
			
		||||
			stack_name = 'block_modifier_elements_to_generate'
 | 
			
		||||
		prefix = '.'
 | 
			
		||||
		if block_name == '^[-2..-2]'
 | 
			
		||||
			p('wurst')
 | 
			
		||||
			prefix = ''
 | 
			
		||||
		element_block = @block{
 | 
			
		||||
			&__{element_name}{
 | 
			
		||||
				for sub_block in _pop_stack(){
 | 
			
		||||
					{sub_block}
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				for modifier_block in _pop_stack('element_modifiers_to_generate'){
 | 
			
		||||
					{modifier_block}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		//Reseting
 | 
			
		||||
		_global_scope['_element_block_stack'] = ()
 | 
			
		||||
		_global_scope['_element_modifier_stack'] = {}
 | 
			
		||||
		
 | 
			
		||||
		//Saving element
 | 
			
		||||
		_global_scope['_selector_blocks_to_generate'][name] = element
 | 
			
		||||
		_global_scope['_last_element_name'] = name
 | 
			
		||||
		_push_onto_stack(element_block, stack_name)
 | 
			
		||||
		_set_last_name(element_name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Generates a CSS class for an element modifier
 | 
			
		||||
@@ -109,35 +152,32 @@ RV-Element(name)
 | 
			
		||||
 * a callback for the modifier and add the element name
 | 
			
		||||
 * from RV-Element
 | 
			
		||||
 */
 | 
			
		||||
RV-Element__Modifier(name)
 | 
			
		||||
	counter = 0
 | 
			
		||||
	for fn in called-from
 | 
			
		||||
		if fn is 'RV-Element'
 | 
			
		||||
			counter += 1
 | 
			
		||||
					
 | 
			
		||||
	if counter <= 1
 | 
			
		||||
		element_modifier_block_stack = _global_scope['_element_modifier_block_stack']
 | 
			
		||||
		append(element_modifier_block_stack, block)
 | 
			
		||||
		_global_scope['_element_modifier_block_stack'] = element_modifier_block_stack
 | 
			
		||||
		
 | 
			
		||||
		//Is this modifier beeing included by another modifier
 | 
			
		||||
		if not 'RV-Element__Modifier' in called-from
 | 
			
		||||
			//No
 | 
			
		||||
			//Is this modifier beeing called in in- or postfix
 | 
			
		||||
			if not 'RV-Element' in called-from
 | 
			
		||||
				//Yes
 | 
			
		||||
				last_element_name = _global_scope['_last_element_name']
 | 
			
		||||
				
 | 
			
		||||
				//Accesing the last generated element and appending the modifier
 | 
			
		||||
				element = _global_scope['_selector_blocks_to_generate'][last_element_name]
 | 
			
		||||
				modifier_list = element['modifier_list']
 | 
			
		||||
				modifier_list[name] = _global_scope['_element_modifier_block_stack']
 | 
			
		||||
				element['modifier_list'] = modifier_list
 | 
			
		||||
 | 
			
		||||
				_global_scope['_selector_blocks_to_generate'][last_element_name] = element
 | 
			
		||||
			else
 | 
			
		||||
				//No
 | 
			
		||||
				_global_scope['_element_modifier_stack'][name] = _global_scope['_element_modifier_block_stack']
 | 
			
		||||
				
 | 
			
		||||
			_global_scope['_element_modifier_block_stack'] = ()
 | 
			
		||||
		
 | 
			
		||||
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_name}--{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 {
 | 
			
		||||
				& .__{last_element_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')
 | 
			
		||||
			
 | 
			
		||||
@@ -1,50 +1,36 @@
 | 
			
		||||
_lanes = {}
 | 
			
		||||
_stacks = {}
 | 
			
		||||
_last_name = {}
 | 
			
		||||
_being_towed = {}
 | 
			
		||||
 | 
			
		||||
_reset_last_name(block_type=null)
 | 
			
		||||
_block_type(block_type)
 | 
			
		||||
	
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	return block_type
 | 
			
		||||
 | 
			
		||||
_reset_last_name(block_type=null)
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	if block_type in _last_name
 | 
			
		||||
		remove(_last_name, block_type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_set_last_name(name, block_type=null)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	_last_name[block_type] = name
 | 
			
		||||
 | 
			
		||||
_get_last_name(block_type)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	if block_type in _last_name
 | 
			
		||||
		return _last_name[block_type]
 | 
			
		||||
	else 
 | 
			
		||||
		return null
 | 
			
		||||
 | 
			
		||||
_current_block_type()
 | 
			
		||||
	return called-from[1]
 | 
			
		||||
 | 
			
		||||
_call_stack_till_first(block_type)
 | 
			
		||||
	striped = slice(called-from, 2)
 | 
			
		||||
	block_index = (index(striped, block_type))
 | 
			
		||||
	if block_index == null
 | 
			
		||||
		if length(striped) <= 1
 | 
			
		||||
			return (striped ())
 | 
			
		||||
		return slice(striped, 1)
 | 
			
		||||
	stack = ()
 | 
			
		||||
	for i in (0..block_index)
 | 
			
		||||
		push(stack, striped[i])
 | 
			
		||||
	return stack
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_push_onto_stack(block, block_type=null)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	if block_type in _stacks
 | 
			
		||||
		stack = _stacks[block_type]
 | 
			
		||||
@@ -55,8 +41,7 @@ _push_onto_stack(block, block_type=null)
 | 
			
		||||
	_stacks[block_type] = stack
 | 
			
		||||
 | 
			
		||||
_pop_from_stack(block_type=null)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	if block_type in _stacks
 | 
			
		||||
		stack = _stacks[block_type]
 | 
			
		||||
@@ -69,8 +54,7 @@ _pop_from_stack(block_type=null)
 | 
			
		||||
	return null
 | 
			
		||||
 | 
			
		||||
_pop_stack(block_type=null)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	if block_type in _stacks
 | 
			
		||||
		stack = _stacks[block_type]
 | 
			
		||||
@@ -78,28 +62,44 @@ _pop_stack(block_type=null)
 | 
			
		||||
		return stack
 | 
			
		||||
	else
 | 
			
		||||
		return ()
 | 
			
		||||
		
 | 
			
		||||
_last_element_of_stack(block_type=null)
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
	
 | 
			
		||||
	if block_type in _stacks
 | 
			
		||||
		stack = _stacks[block_type]
 | 
			
		||||
		return stack[-1]
 | 
			
		||||
	else
 | 
			
		||||
		return null
 | 
			
		||||
 | 
			
		||||
_add_to_lane(key, value, block_type=null)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
_set_lane(lane_name, value, block_type=null)
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	if block_type in _lanes
 | 
			
		||||
		lane = _lanes[block_type]
 | 
			
		||||
	else
 | 
			
		||||
		lane = {}
 | 
			
		||||
 | 
			
		||||
	if key in lane
 | 
			
		||||
		stack = lane[key]
 | 
			
		||||
	if lane_name in lane
 | 
			
		||||
		stack = lane[lane_name]
 | 
			
		||||
	else
 | 
			
		||||
		stack = ()
 | 
			
		||||
 | 
			
		||||
	push(stack, value)
 | 
			
		||||
	lane[key] = stack
 | 
			
		||||
	lane[lane_name] = stack
 | 
			
		||||
	_lanes[block_type] = lane
 | 
			
		||||
	
 | 
			
		||||
_get_lane(block_type)
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
		
 | 
			
		||||
	if block_type in _lanes
 | 
			
		||||
		return _lanes[block_type]
 | 
			
		||||
	else
 | 
			
		||||
		return {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_put_into_lane(key, value, block_type=null)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
 | 
			
		||||
	if block_type in _lanes
 | 
			
		||||
		lane = _lanes[block_type]
 | 
			
		||||
@@ -110,8 +110,7 @@ _put_into_lane(key, value, block_type=null)
 | 
			
		||||
	_lanes[block_type] = lane
 | 
			
		||||
 | 
			
		||||
_pop_lane(block_type=null)
 | 
			
		||||
	if block_type == null
 | 
			
		||||
		block_type = called-from[1]
 | 
			
		||||
	block_type = _block_type(block_type)
 | 
			
		||||
	
 | 
			
		||||
	if block_type in _lanes
 | 
			
		||||
		lane = _lanes[block_type]
 | 
			
		||||
@@ -119,38 +118,3 @@ _pop_lane(block_type=null)
 | 
			
		||||
		return lane
 | 
			
		||||
	else
 | 
			
		||||
		return {}
 | 
			
		||||
 | 
			
		||||
attach(parent_type, suffix, block)
 | 
			
		||||
	_being_towed[_current_block_type()] = true
 | 
			
		||||
	call_stack = _call_stack_till_first(parent_type)
 | 
			
		||||
	if parent_type in call_stack
 | 
			
		||||
		// We are called inside a block
 | 
			
		||||
		_push_onto_stack(block)
 | 
			
		||||
		//Detect if the selector will be generated
 | 
			
		||||
		//by an earlier call of RV-Element
 | 
			
		||||
		if not _current_block_type() in (call_stack)
 | 
			
		||||
			block_list = _pop_stack()
 | 
			
		||||
			_put_into_lane(suffix, block_list, parent_type)
 | 
			
		||||
	else
 | 
			
		||||
		// We are not called inside a block
 | 
			
		||||
		// Is there a block to attach to
 | 
			
		||||
		_last_parent_name = _get_last_name(parent_type)
 | 
			
		||||
		if _last_parent_name != null
 | 
			
		||||
			& .{_last_parent_name} .{_last_parent_name}{suffix}
 | 
			
		||||
				{block}
 | 
			
		||||
 | 
			
		||||
tow(name, block, block_type=null)
 | 
			
		||||
	if block_type == null	// Determining if we are inside a block or after a block
 | 
			
		||||
		block_type = called-from[0]
 | 
			
		||||
 | 
			
		||||
	.{name}
 | 
			
		||||
		{block}
 | 
			
		||||
		if block_type in _lanes
 | 
			
		||||
			for suffix, block_list in _pop_lane(block_type)
 | 
			
		||||
				p(name suffix selector())
 | 
			
		||||
				&{name}{suffix}
 | 
			
		||||
					for current_block in block_list
 | 
			
		||||
						{current_block}
 | 
			
		||||
 | 
			
		||||
	_set_last_name(name, block_type)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user