UNPKG

stylobate

Version:

Framework for writing really abstract CSS in Stylus

272 lines (219 loc) 10.9 kB
$stylobate_options = { 'warn_on_incorrect_notation': true } $selector_regex = '&|^[\/\.]|ROOT|(^|[^\w])(__|-)\w' $stylobate_extends = {} $stylobate_extends_without_defaults = {} stylobate_extends($what, $target, $defaults = true) $stylobate_extends[''+utilus_ident($what)] = $target if !$defaults $stylobate_extends_without_defaults[''+utilus_ident($what)] = true $stylobate_defaults = {} stylobate_defaults($what, $defaults...) $stylobate_defaults['' + utilus_ident($what)] = $defaults stylobate_params($this, $params) $collected_params = { parent: {}, arguments: clone($params) } prepend($collected_params.arguments, unquote('')) _stylobate_collect_arguments($collected_params) $this['modifiers'] = merge($collected_params.modifiers, $this.modifiers) $this['elements'] = merge($collected_params.elements, $this.elements) return $collected_params stylobate_this() $this = { 'parent': {} 'arguments': () 'params': {} 'modifiers': {} 'elements': {} 'urls': (), 'selector': selector(), 'selectors': () } $null_collected = utilus_collect_by_type(()) for $key in ('strings' 'idents' 'units' 'rgbas' 'booleans' 'functions' 'objects' 'arrays' 'colors') $this[$key] = $null_collected[$key] return $this _stylobate_apply_defaults($this, $defaults) $origin = $this.called_from return false if not $origin $new_args = clone($defaults) $newthis = clone($this) $newthis['called_from'] = $origin + '_' $newthis['defaulted'] = true for $param, $index in $new_args unless $param == null $found_param = utilus_get($this['arguments'], utilus_ident($param[0])) if $found_param or (type($found_param) == 'string' and $found_param == '') $new_args[$index] = '' for $param, $index in $this.arguments $testparam = utilus_ident($param) $testparam = '' unless type($param) in ('ident' 'string' 'function' 'literal') unless match('^[-_]', $testparam) push($new_args, $param) $newthis['arguments'] = clone($new_args) _stylobate('', $origin + '_', $newthis) _stylobate_collect_arguments($this) if length($this.parent) $this['params'] = $this['parent']['params'] $this['modifiers'] = $this['parent']['modifiers'] $this['elements'] = $this['parent']['elements'] $this['urls'] = $this['parent']['urls'] $this['selectors'] = $this['parent']['selectors'] else $this['params'] = {} $this['modifiers'] = {} $this['elements'] = {} $this['urls'] = () $this['selectors'] = () // Remove the item's name from the arguments $this['arguments'][0] = unquote('') // Collect the arguments, first step $collected = utilus_collect_by_type($this['arguments']) for $key in ('strings' 'idents' 'units' 'rgbas' 'booleans' 'functions' 'objects' 'arrays' 'colors') $this[$key] = $collected[$key] // Getting different params and stuff if length($this['strings']) > 0 for $key in $this['strings'] // replace those checks with functions if match('\.(png|jpg|svg|gif)\b|https?:\/\/|^data:', $key) push($this['urls'], $key) else if match($selector_regex, $key) push($this['selectors'], $key) else if $key != '' // workaround for strange clone? bug $workaround = $this['params'] $workaround[$key] = $key if length($this['idents']) > 0 for $key in $this['idents'] // workaround for strange clone? bug $workaround = $this['params'] $workaround['' + utilus_ident($key)] = utilus_ident($key) if match('^(__|-[^\-])', $key) $workaround = $this['elements'] $workaround[replace('^([_-]+)', '', '' + utilus_ident($key))] = '&' else if match('^(_|--)', $key) $workaround = $this['modifiers'] $workaround[replace('^([_-]+)', '', '' + utilus_ident($key))] = '&' if length($this['functions']) > 0 for $key in $this['functions'] // workaround for strange clone? bug $workaround = $this['params'] $workaround['' + utilus_ident($key)] = utilus_ident($key) if match('^(__|-[^\-])', utilus_ident($key)) $workaround = $this['elements'] $workaround[replace('^([_-]+)', '', '' + utilus_ident($key))] = '&' else if match('^(_|--)', utilus_ident($key)) $workaround = $this['modifiers'] $workaround[replace('^([_-]+)', '', '' + utilus_ident($key))] = '&' if length($this['arrays']) > 0 for $index, $array in $this['arrays'] $key = utilus_ident($array[0]) $rest = () for $item, $index in $array $rest = utilus_append($rest, $item) if $index > 0 $workaround = $this['params'] $workaround['' + $key] = $rest if $rest != () if match('^(__|-[^\-])', $key) and $rest != () $workaround = $this['elements'] $workaround[replace('^([_-]+)', '', '' + $key)] = utilus_ident($rest) else if match('^(_|--)', $key) and $rest != () $workaround = $this['modifiers'] $workaround[replace('^([_-]+)', '','' + $key)] = utilus_ident($rest) _stylobate($name, $params, $this = { parent: {}, arguments: clone($params), called_from: $name + $params[0], selector: selector() }) _stylobate_collect_arguments($this) unless $this.defaulted // Check if the called stylobate extends anything, if so, call it first, // and use the extended stylobate for subitems. $skin_name = utilus_ident($params[0]) $extended_name_ending = replace('.*[^-_]+', '', $skin_name) $extended_name = $stylobate_extends[$name + $skin_name] || $stylobate_extends[$name + replace('[_-]+$', '', $skin_name)] $extended_name = utilus_ident($extended_name) + $extended_name_ending if $extended_name if $extended_name $this['is_extended'] = true $skin_name = replace('^' + $name, '', $extended_name) if !utilus_is_function($extended_name) and $extended_name_ending == '' error('No stylobate function “' + $extended_name + '”') stylobate_params($this, $stylobate_defaults[$extended_name]) if $extended_name in $stylobate_defaults and !($name + utilus_ident($params[0]) in $stylobate_extends_without_defaults) {$extended_name}($this) if $extended_name and $extended_name_ending == '' if $extended_name _stylobate_apply_defaults($this, $stylobate_defaults[$extended_name]) if $extended_name in $stylobate_defaults and !($name + utilus_ident($params[0]) in $stylobate_extends_without_defaults) if ($name + join('',$params) != '') and !utilus_is_function($name + utilus_ident($params[0])) and !$extended_name and !match('[_-]$', utilus_ident($params[0])) error('No such “' + $name + '” — “' + utilus_ident($params[0]) + '”') stylobate_params($this, $stylobate_defaults[$name + utilus_ident($params[0])]) if ($name + utilus_ident($params[0])) in $stylobate_defaults {$name + utilus_ident($params[0])}($this) if utilus_is_function($name + utilus_ident($params[0])) _stylobate_apply_defaults($this, $stylobate_defaults[$name + utilus_ident($params[0])]) if ($name + utilus_ident($params[0])) in $stylobate_defaults for $subitem in $this.arguments // There shouldn't be an `if` inside a {$selector}, 'cause // there is a crazy stylus bug. When it would be fixed, // revert this version to 669082fb35 $selector = '' $foundsubitem = '' if is_array($subitem) if type($subitem[0]) in ('ident' 'string' 'function' 'literal') $testsubitem = utilus_ident($subitem[0]) if match('^(\-|_)', $testsubitem) $foundsubitem = $subitem if type($subitem[1]) == 'string' if match($selector_regex, $subitem[1]) $selector = $subitem[1] else $foundsubitem = '' else if type($subitem) in ('ident' 'string' 'function' 'literal') if match('^(\-|_)', utilus_ident($subitem)) $foundsubitem = utilus_ident($subitem) call_subitem() $this_subitem = { parent: $this, arguments: clone($foundsubitem), selector: selector() } _stylobate_collect_arguments($this_subitem) $subitemname_prefix = ($extended_name ? '' : $name) + replace('[_-]+$', '', $extended_name ? $extended_name : $skin_name) $subitemname_connector = replace('^([_-]+)[^_-].*$', '$1', utilus_ident($foundsubitem[0])) $subitemname_connector_substitutes = { '_': '--', '--': '_', '__': '-', '-': '__' } $subitemname_postfix = utilus_ident(replace('^[_-]+', '', utilus_ident($foundsubitem[0]))) $subitemname = $subitemname_prefix + $subitemname_connector + $subitemname_postfix $subitemname = '' unless utilus_is_function($subitemname) if $subitemname == '' $subitemname_connector = $subitemname_connector_substitutes['' + $subitemname_connector] $subitemname = $subitemname_prefix + $subitemname_connector + $subitemname_postfix $subitemname = '' unless utilus_is_function($subitemname) if $stylobate_options.warn_on_incorrect_notation warn('' + 'Incorrect notation for %s, using %s.' % ($subitemname_prefix ($subitemname_connector + $subitemname_postfix))) unless $subitemname == '' // If there is extended subitem function, use it, otherwise $subitemname_extended = '' $subitemname_extended = $name + replace('[_-]+$', '', utilus_ident($params[0])) + utilus_ident($foundsubitem[0]) if $extended_name $subitemname_extended = '' unless utilus_is_function($subitemname_extended) // Push proper `called_from` $this_subitem['called_from'] = $subitemname unless $subitemname_extended or !$subitemname $this_subitem['called_from'] = $subitemname_extended if $subitemname_extended stylobate_params($this, $stylobate_defaults[$subitemname]) if $subitemname in $stylobate_defaults and !$subitemname_extended {$subitemname}($this_subitem) unless $subitemname_extended or !$subitemname _stylobate_apply_defaults($this_subitem, $stylobate_defaults[$subitemname]) if $subitemname in $stylobate_defaults and !$subitemname_extended stylobate_params($this, $stylobate_defaults[$subitemname_extended]) if $subitemname_extended in $stylobate_defaults and $subitemname_extended {$subitemname_extended}($this_subitem) unless !$subitemname_extended _stylobate_apply_defaults($this_subitem, $stylobate_defaults[$subitemname_extended]) if $subitemname_extended in $stylobate_defaults and $subitemname_extended $selector = '' if $selector == '&' {stylobate-selector($this, $selector)} call_subitem() if $foundsubitem != '' and $selector != '' if $selector == '' and $foundsubitem != '' call_subitem() stylobate_property($name, $params) if utilus_is_comma_list($params) for $item in $params _stylobate($name, $item) else _stylobate($name, $params)