New bemGenerator
This commit is contained in:
		@@ -1,249 +1,115 @@
 | 
				
			|||||||
// Storing the currents block properties and attributes
 | 
					_alias_map = {}
 | 
				
			||||||
// to generate the block afterwards
 | 
					_alias_stack = () ()
 | 
				
			||||||
/*
 | 
								
 | 
				
			||||||
 * A method for iterating throug a 
 | 
					work_stack(stack, callback)
 | 
				
			||||||
 * list/array safely since this language sucks
 | 
						while length(stack) > 0
 | 
				
			||||||
 * realy bad https://github.com/stylus/stylus/issues/1440
 | 
							entry = pop(_alias_stack)
 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
foreach(list, callback)
 | 
					 | 
				
			||||||
	for entry in list
 | 
					 | 
				
			||||||
		if entry != ()
 | 
							if entry != ()
 | 
				
			||||||
			callback(entry)
 | 
								callback(entry)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
create_list()
 | 
					set_alias(alias, name)
 | 
				
			||||||
	return () ()
 | 
						if name != null && alias != null
 | 
				
			||||||
 | 
							_alias_map[alias] = name
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
_block = {}
 | 
					lookup_alias(name)
 | 
				
			||||||
reset_block()
 | 
						if not _alias_map
 | 
				
			||||||
	_block.elements = create_list()
 | 
							return name
 | 
				
			||||||
	_block.block_modifiers = create_list()
 | 
						if name in _alias_map
 | 
				
			||||||
	_block.alias = {
 | 
							return _alias_map[name]
 | 
				
			||||||
		map: {}
 | 
					 | 
				
			||||||
		stash: {
 | 
					 | 
				
			||||||
			RV-Element: create_list()
 | 
					 | 
				
			||||||
			RV-Element__Modifier: create_list()
 | 
					 | 
				
			||||||
			RV-Block__Modifier: create_list()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_block.modifier_stash = create_list()
 | 
					 | 
				
			||||||
	_block.element_stash = create_list()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Calling the function to initiate the block
 | 
					 | 
				
			||||||
// for first use
 | 
					 | 
				
			||||||
reset_block()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_bem_mixins = 'RV-Block','RV-Element','RV-Modifier','RV-Element__Modifier','RV-Block__Modifier'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Checks if the caller of this funcion is a direct
 | 
					 | 
				
			||||||
 * descendant of RV-Block. Checks for BEM-Mixins only.
 | 
					 | 
				
			||||||
 * If any other function or mixin is between the last 
 | 
					 | 
				
			||||||
 * block and the caller, it will still count as an direct
 | 
					 | 
				
			||||||
 * descendant of RV-Block
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
is_direct_descendant_of_block()
 | 
					 | 
				
			||||||
	block_index = index(called-from, 'RV-Block') - 1
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if block_index <= 0
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	for i in (1..block_index)
 | 
					 | 
				
			||||||
		if called-from[i] in _bem_mixins
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Checks if we are called inside a block
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
is_in_block()
 | 
					 | 
				
			||||||
	return 'RV-Block' in called-from
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 
 | 
					 | 
				
			||||||
 * Taking the currently stashed names, mapping
 | 
					 | 
				
			||||||
 * them to the given name under the called parent
 | 
					 | 
				
			||||||
 * (using called-from) and returning the stashed blocks
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
generate_aliases(actual_name, level_type=null)
 | 
					 | 
				
			||||||
	if level_type == null
 | 
					 | 
				
			||||||
		level_type = split(' ', called-from)[0]
 | 
					 | 
				
			||||||
	if actual_name == null
 | 
					 | 
				
			||||||
		if length(_block.alias.stash[level_type]) > 2
 | 
					 | 
				
			||||||
			actual_name = _block.alias.stash[level_type][-1].name
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			warn('No name found for '+called-from)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	blocks = ()
 | 
					 | 
				
			||||||
	foreach(_block.alias.stash[level_type], @(alias){
 | 
					 | 
				
			||||||
		_block.alias.map[level_type+':'+alias.name] = actual_name
 | 
					 | 
				
			||||||
		push(blocks, alias.block)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	_block.alias.stash[level_type] = create_list()
 | 
					 | 
				
			||||||
	return {
 | 
					 | 
				
			||||||
		name: actual_name
 | 
					 | 
				
			||||||
		blocks: blocks
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Resolving the alias according to the level type
 | 
					 | 
				
			||||||
 * (using called-from). Returning the given name
 | 
					 | 
				
			||||||
 * when no alias is found
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
resolve_alias(name, level_type=null)
 | 
					 | 
				
			||||||
	if level_type == null
 | 
					 | 
				
			||||||
		level_type = split(' ', called-from)[0]
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if level_type+':'+name in _block.alias.map
 | 
					 | 
				
			||||||
		return _block.alias.map[level_type+':'+name]
 | 
					 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		return name
 | 
							return name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					store_alias(alias)
 | 
				
			||||||
 * Renders an element modifier
 | 
						if alias != null
 | 
				
			||||||
 */
 | 
							push(_alias_stack, alias)
 | 
				
			||||||
render_element_modifier(modifier)
 | 
						
 | 
				
			||||||
	&--{resolve_alias(modifier.name, 'RV-Element__Modifier')}
 | 
					pop_last_alias()
 | 
				
			||||||
		foreach(modifier.blocks, @(block){
 | 
						return pop(_alias_stack)
 | 
				
			||||||
			{block}
 | 
						
 | 
				
			||||||
 | 
					apply_alias_stack(name)
 | 
				
			||||||
 | 
						work_stack(_alias_stack, @(element){
 | 
				
			||||||
 | 
							set_alias(element, name)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					auto_name(delimiter)
 | 
				
			||||||
 * Renders an element
 | 
						if length(called-from) < 3
 | 
				
			||||||
 */
 | 
							return null
 | 
				
			||||||
render_element(element)
 | 
						name = split(delimiter, called-from[2])[-1]
 | 
				
			||||||
	&__{resolve_alias(element.name, 'RV-Element')}
 | 
						if name in ('RV-Element' 'RV-Block' 'RV-Element--modifier' 'RV-Block--modifier')
 | 
				
			||||||
		foreach(element.blocks, @(block){
 | 
							return null
 | 
				
			||||||
			{block}
 | 
						return name
 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		foreach(element.modifiers, @(modifier){
 | 
					 | 
				
			||||||
			render_element_modifier(modifier)
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					is_nested(mixin_name=null)
 | 
				
			||||||
 * Renders an block modifier, 
 | 
						_free_hits = 0
 | 
				
			||||||
 */
 | 
						if mixin_name == null
 | 
				
			||||||
render_block_modifier(modifier)
 | 
							shift(called-from)
 | 
				
			||||||
	&--{resolve_alias(modifier.name, 'RV-Block__Modifier')}
 | 
							mixin_name = shift(called-from)
 | 
				
			||||||
		foreach(modifier.blocks, @(block){
 | 
						else 
 | 
				
			||||||
 | 
							_free_hits = 1
 | 
				
			||||||
 | 
						for parent in called-from
 | 
				
			||||||
 | 
							if parent == mixin_name
 | 
				
			||||||
 | 
								if _free_hits == 0
 | 
				
			||||||
 | 
									return true
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									_free_hits = _free_hits - 1
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is_nested_in(parent_name)
 | 
				
			||||||
 | 
						return parent_name in called-from
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					not_nested_in(parent_name)
 | 
				
			||||||
 | 
						return !(parent_name in called-from)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RV-Level(name, name_delimiter, allowed_parent_levels, selector_callback)
 | 
				
			||||||
 | 
						if name == null
 | 
				
			||||||
 | 
							name = auto_name(name_delimiter)
 | 
				
			||||||
 | 
						not_in_parent = true
 | 
				
			||||||
 | 
						for parent_level in allowed_parent_levels
 | 
				
			||||||
 | 
							not_in_parent = not_in_parent && not_nested_in(parent_level)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						if is_nested_in('RV-Squash') || not_in_parent
 | 
				
			||||||
		{block}
 | 
							{block}
 | 
				
			||||||
		})
 | 
						else if is_nested()
 | 
				
			||||||
		& ^[-2..-2]{
 | 
							store_alias(name)
 | 
				
			||||||
			foreach(modifier.elements, @(element){
 | 
							{block}
 | 
				
			||||||
				render_element(element)
 | 
						else
 | 
				
			||||||
			})
 | 
							if name == null
 | 
				
			||||||
 | 
								name = pop_last_alias()
 | 
				
			||||||
 | 
							name = lookup_alias(name)
 | 
				
			||||||
 | 
							apply_alias_stack(name)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							{selector_callback(name)}
 | 
				
			||||||
 | 
								{block}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RV-Block(name)
 | 
				
			||||||
 | 
						.{name}
 | 
				
			||||||
 | 
							+prefix-classes(name)
 | 
				
			||||||
 | 
								{block}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
						define('_alias_map', {}, true)
 | 
				
			||||||
 | 
						define('_alias_stack', () (), true)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					RV-Element(name=null)
 | 
				
			||||||
 | 
						+RV-Level(name, '__', ('RV-Block' 'RV-Block--modifier'), @(name){
 | 
				
			||||||
 | 
							if is_nested_in('RV-Block--modifier') {
 | 
				
			||||||
 | 
								return '& .__' + name
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								return '&__' + name
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
							{block}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 | 
					RV-Element--modifier(name=null)
 | 
				
			||||||
 | 
						+RV-Level(name, '--', ('RV-Element'), @(name){return '&--' + name})
 | 
				
			||||||
 | 
							{block}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					RV-Block--modifier(name=null)
 | 
				
			||||||
 | 
						+RV-Level(name, '--', ('RV-Block'), @(name){return '&--' + name})
 | 
				
			||||||
 | 
							{block}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
RV-Squash()
 | 
					RV-Squash()
 | 
				
			||||||
	{block}
 | 
						{block}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Stashing the given block under the given
 | 
					 | 
				
			||||||
 * name to be aliased by a late level
 | 
					 | 
				
			||||||
 * (See generate_aliases)
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
RV-Element--name(name)
 | 
					 | 
				
			||||||
	if 'RV-Squash' in called-from
 | 
					 | 
				
			||||||
		{block}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		if 'RV-Element' in called-from
 | 
					 | 
				
			||||||
			push(_block.alias.stash.RV-Element, {
 | 
					 | 
				
			||||||
				name: name
 | 
					 | 
				
			||||||
				block: block
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			{block}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RV-Element__Modifier--name(name)
 | 
					 | 
				
			||||||
	if 'RV-Squash' in called-from
 | 
					 | 
				
			||||||
		{block}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		if 'RV-Element__Modifier' in called-from
 | 
					 | 
				
			||||||
			push(_block.alias.stash.RV-Element__Modifier, {
 | 
					 | 
				
			||||||
				name: name
 | 
					 | 
				
			||||||
				block: block
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			{block}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
RV-Block__Modifier--name(name)
 | 
					 | 
				
			||||||
	if 'RV-Squash' in called-from
 | 
					 | 
				
			||||||
		{block}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		if 'RV-Block__Modifier' in called-from
 | 
					 | 
				
			||||||
			push(_block.alias.stash.RV-Block__Modifier, {
 | 
					 | 
				
			||||||
				name: name
 | 
					 | 
				
			||||||
				block: block
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			{block}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RV-Block(block_name)
 | 
					 | 
				
			||||||
	& .{block_name}
 | 
					 | 
				
			||||||
		foreach(_block.elements, @(element){
 | 
					 | 
				
			||||||
			render_element(element)
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		foreach(_block.block_modifiers, @(modifier){
 | 
					 | 
				
			||||||
			render_block_modifier(modifier)
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		{block}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	reset_block()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RV-Block__Modifier(modifier_name=null)
 | 
					 | 
				
			||||||
	if 'RV-Squash' in called-from
 | 
					 | 
				
			||||||
		{block}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		blocks = generate_aliases(modifier_name)
 | 
					 | 
				
			||||||
		modifier_name = blocks.name
 | 
					 | 
				
			||||||
		blocks = blocks.blocks
 | 
					 | 
				
			||||||
		push(blocks, block)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		modifier = {
 | 
					 | 
				
			||||||
			name: modifier_name
 | 
					 | 
				
			||||||
			blocks: blocks
 | 
					 | 
				
			||||||
			elements: _block.element_stash
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_block.element_stash = create_list()
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		push(_block.block_modifiers, modifier)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RV-Element(element_name=null)
 | 
					 | 
				
			||||||
	if 'RV-Squash' in called-from
 | 
					 | 
				
			||||||
		{block}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		blocks = generate_aliases(element_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		element_name = blocks.name
 | 
					 | 
				
			||||||
		blocks = blocks.blocks
 | 
					 | 
				
			||||||
		push(blocks, block)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		element = {
 | 
					 | 
				
			||||||
			name: element_name
 | 
					 | 
				
			||||||
			blocks: blocks
 | 
					 | 
				
			||||||
			modifiers: _block.modifier_stash
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_block.modifier_stash = create_list()
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if is_direct_descendant_of_block()
 | 
					 | 
				
			||||||
			push(_block.elements, element)
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			push(_block.element_stash, element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RV-Element__Modifier(modifier_name=null)
 | 
					 | 
				
			||||||
	if 'RV-Squash' in called-from
 | 
					 | 
				
			||||||
		{block}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		blocks = generate_aliases(modifier_name)
 | 
					 | 
				
			||||||
		modifier_name = blocks.name
 | 
					 | 
				
			||||||
		blocks = blocks.blocks
 | 
					 | 
				
			||||||
		push(blocks, block)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		modifier = {
 | 
					 | 
				
			||||||
			name: modifier_name
 | 
					 | 
				
			||||||
			blocks: blocks
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		push(_block.modifier_stash, modifier)
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user