// Storing the currents block properties and attributes // to generate the block afterwards /* * A method for iterating throug a * list/array safely since this language sucks * realy bad https://github.com/stylus/stylus/issues/1440 */ foreach(list, callback) for entry in list if entry != () callback(entry) create_list() return () () _block = {} reset_block() _block.elements = create_list() _block.block_modifiers = create_list() _block.alias = { 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 /* * 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 = 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 = split(' ', called-from)[0] if level_type+':'+name in _block.alias.map return _block.alias.map[level_type+':'+name] else return name render_element_modifier(modifier) &--{resolve_alias(modifier.name)} foreach(modifier.blocks, @(block){ {block} }) render_element(element) &__{resolve_alias(element.name)} foreach(element.blocks, @(block){ {block} }) foreach(element.modifiers, @(modifier){ render_element_modifier(modifier) }) render_block_modifier(modifier) &--{resolve_alias(modifier.name)} foreach(modifier.blocks, @(block){ {block} }) & ^[-2..-2]{ foreach(modifier.elements, @(element){ render_element(element) }) } /* * Stashing the given block under the given * name to be aliased by a late level * (See generate_aliases) */ RV-Element--name(name) push(_block.alias.stash.RV-Element, { name: name block: block }) RV-Element__Modifier--name(name) push(_block.alias.stash.RV-Element__Modifier, { name: name block: block }) RV-Block__Modifier--name(name) push(_block.alias.stash.RV-Block__Modifier, { name: name block: block }) RV-Block(block_name) & .{block_name} {block} foreach(_block.block_modifiers, @(modifier){ render_block_modifier(modifier) }) foreach(_block.elements, @(element){ render_element(element) }) RV-Block__Modifier(modifier_name=null) modifier_name = resolve_alias(modifier_name) 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) element_name = resolve_alias(element_name) 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) modifier_name = resolve_alias(modifier_name) 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)