scss-library/components/00_Tools/_bemGenerator.styl

256 lines
5.5 KiB
Stylus

_bem_context = {
_alias_map: {}
_alias_stacks: {
},
known_names: {}
}
bem_debug = false
work_stack(stack, callback)
while length(stack) > 0
entry = pop(stack)
if entry != ()
callback(entry)
set_alias(alias, name)
if name != null && alias != null
_bem_context._alias_map[alias] = name
lookup_alias(name)
if name in _bem_context._alias_map
return _bem_context._alias_map[name]
else
return name
store_alias(alias)
level_name = called-from[1]
if not level_name in _bem_context._alias_stacks
_bem_context._alias_stacks[level_name] = () ()
if alias != null
push(_bem_context._alias_stacks[level_name], alias)
pop_last_alias()
level_name = called-from[1]
if not level_name in _bem_context._alias_stacks
return null
return pop(_bem_context._alias_stacks[level_name])
apply_alias_stack(name, level_name=null)
if level_name == null
level_name = called-from[1]
if level_name in _bem_context._alias_stacks
work_stack(_bem_context._alias_stacks[level_name], @(element){
set_alias(element, name)
})
auto_name(delimiter, caller)
if delimiter == null
return caller
return split(delimiter, caller)[-1]
is_nested(mixin_name=null)
_free_hits = 0
if mixin_name == null
shift(called-from)
mixin_name = shift(called-from)
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_list=null)
if parent_list == null
return false
for parent in parent_list
if parent in called-from
return true
return false
not_nested_in(parent_name)
return !(parent_name in called-from)
is_any_parent_nested()
//RV-Level RV-Element--modifier RV-Element RV-Block--modifier RV-BreakPoint--horizontal RV-Block--modifier RV-Fan--horizontal RV-Block
for i in (length(called-from)...0)
i = i - 1
if i != index(called-from, called-from[i])
return true
return false
string_contains(smaller, greater)
if smaller == null || greater == null
return true
if length(smaller) > length(greater)
return false
for i in range(0, length(smaller) - 1)
//p(i substr(smaller, i, 1) substr(greater, i, 1))
if substr(smaller, i, 1) != substr(greater, i, 1)
return false
return true
contigious_index(call_stack)
for i in range(0, length(call_stack) - 1)
if !string_contains(call_stack[i+1], call_stack[i])
return i
return -1
filter(list, value_list)
filtered = ()
for element in list
if not (element in value_list)
push(filtered, element)
return filtered
RV-Level(name_delimiter, selector_callback, name=null)
call_stack = split(' ', ''+called-from)
call_stack = filter(call_stack, ('RV-Level' 'RV-Block' 'RV-Block--modifier' 'RV-Element' 'RV-Element--modifier' 'RV-Modifier'))
mixin_name = call_stack[0]
if name == null
name = auto_name(name_delimiter, mixin_name)
cindex = contigious_index(call_stack)
if bem_debug
--attempt mixin_name
--cindex cindex
--nested_in_super_parents nested_in_super_parents
// TODO Clear up this logic
if cindex != 0
if name == null
name = pop_last_alias()
name = lookup_alias(name)
apply_alias_stack(name)
selector_name = selector_callback(name)
if name == ''
selector_name = split(name_delimiter, selector_name)[0]
if cindex > 0 && !(name in _bem_context.known_names)
return
else
_bem_context.known_names[name] = name
define('current_selector', selector_name, true)
{selector_name}
{block}
if bem_debug
--mixin_name mixin_name
--name name
else
store_alias(name)
{block}
if bem_debug
--mixin_name mixin_name
--name name
RV-Block(name=null)
+RV-Level(null, @(name){
return '.'+name
}, name)
{block}
_bem_context._alias_map = {}
_bem_context._alias_stacks = {}
_bem_context.known_names = {}
RV-Block--shorthand(name)
+RV-Block(name)
{block}
RV-Element(name=null)
+RV-Level('__', @(name){
return '& ^[0]__'+name
}, name)
{block}
RV-Element--modifier(name=null)
+RV-Level('--', @(name){
return '&--'+name
}, name, ('RV-Block--modifier'))
{block}
RV-Block--modifier(name=null)
+RV-Level('--', @(name){
return '&--'+name
}, name)
{block}
RV-Squash()
{block}
_level_types = {
'': {
name: 'block',
selector: @(mixin_name, level_name){return '.'+level_name}
},
'__': {
name: 'element',
selector: @(mixin_name, level_name){return '&__'+level_name}
},
'--': {
name: 'modifier',
selector: @(mixin_name, level_name){return '&--'+level_name}
},
}
get_first_level_name(mixin_name)
shortest_split = null
for delimiter, level_type in _level_types
if length(delimiter) > 0
current_split = split(delimiter, mixin_name)[0]
if shortest_split == null || length(current_split) <= length(shortest_split)
shortest_split = current_split
return shortest_split
generate_selector(mixin_name)
candidate = null
candidate_level = null
// This is why humanity is doomed
mixin_name = split('äöü', mixin_name)[0]
for delimiter, level in _level_types
if length(delimiter) <= 0
splited_level = mixin_name
else
splited_level = split(delimiter, mixin_name)[-1]
if candidate == null || length(candidate) > length(splited_level)
candidate = splited_level
candidate_level = level
fn = candidate_level.selector
return fn(mixin_name, candidate)
//generate_selector(mixin_name)
// block_name = get_first_level_name(mixin_name)
// level_info = determine_level_type(mixin_name)
// return '&%s%s' % (level_info[2] level_info[0])
RV-BEM()
call_stack = split(' ', ''+called-from)
if is_contigious(call_stack)
{generate_selector(call_stack[0])}
{block}
else
{block}