File: /var/www/vhost/disk-apps/pwa.sports-crowd.com/node_modules/cssauron/index.js
module.exports = language
var tokenizer = require('./tokenizer')
function language(lookups, matchComparison) {
return function(selector) {
return parse(selector, remap(lookups),
matchComparison || caseSensitiveComparison)
}
}
function remap(opts) {
for(var key in opts) if(opt_okay(opts, key)) {
opts[key] = Function(
'return function(node, attr) { return node.' + opts[key] + ' }'
)
opts[key] = opts[key]()
}
return opts
}
function opt_okay(opts, key) {
return opts.hasOwnProperty(key) && typeof opts[key] === 'string'
}
function parse(selector, options, matchComparison) {
var stream = tokenizer()
, default_subj = true
, selectors = [[]]
, traversal
, bits
bits = selectors[0]
traversal = {
'': any_parents
, '>': direct_parent
, '+': direct_sibling
, '~': any_sibling
}
stream
.on('data', group)
.end(selector)
function group(token) {
var crnt
if(token.type === 'comma') {
selectors.unshift(bits = [])
return
}
if(token.type === 'op' || token.type === 'any-child') {
bits.unshift(traversal[token.data])
bits.unshift(check())
return
}
bits[0] = bits[0] || check()
crnt = bits[0]
if(token.type === '!') {
crnt.subject =
selectors[0].subject = true
return
}
crnt.push(
token.type === 'class' ? listContains(token.type, token.data) :
token.type === 'attr' ? attr(token) :
token.type === ':' || token.type === '::' ? pseudo(token) :
token.type === '*' ? Boolean :
matches(token.type, token.data, matchComparison)
)
}
return selector_fn
function selector_fn(node, as_boolean) {
var current
, length
, orig
, subj
, set
orig = node
set = []
for(var i = 0, len = selectors.length; i < len; ++i) {
bits = selectors[i]
current = entry
length = bits.length
node = orig
subj = []
for(var j = 0; j < length; j += 2) {
node = current(node, bits[j], subj)
if(!node) {
break
}
current = bits[j + 1]
}
if(j >= length) {
if(as_boolean) {
return true
}
add(!bits.subject ? [orig] : subj)
}
}
if(as_boolean) {
return false
}
return !set.length ? false :
set.length === 1 ? set[0] :
set
function add(items) {
var next
while(items.length) {
next = items.shift()
if(set.indexOf(next) === -1) {
set.push(next)
}
}
}
}
function check() {
_check.bits = []
_check.subject = false
_check.push = function(token) {
_check.bits.push(token)
}
return _check
function _check(node, subj) {
for(var i = 0, len = _check.bits.length; i < len; ++i) {
if(!_check.bits[i](node)) {
return false
}
}
if(_check.subject) {
subj.push(node)
}
return true
}
}
function listContains(type, data) {
return function(node) {
var val = options[type](node)
val =
Array.isArray(val) ? val :
val ? val.toString().split(/\s+/) :
[]
return val.indexOf(data) >= 0
}
}
function attr(token) {
return token.data.lhs ?
valid_attr(
options.attr
, token.data.lhs
, token.data.cmp
, token.data.rhs
) :
valid_attr(options.attr, token.data)
}
function matches(type, data, matchComparison) {
return function(node) {
return matchComparison(type, options[type](node), data);
}
}
function any_parents(node, next, subj) {
do {
node = options.parent(node)
} while(node && !next(node, subj))
return node
}
function direct_parent(node, next, subj) {
node = options.parent(node)
return node && next(node, subj) ? node : null
}
function direct_sibling(node, next, subj) {
var parent = options.parent(node)
, idx = 0
, children
children = options.children(parent)
for(var i = 0, len = children.length; i < len; ++i) {
if(children[i] === node) {
idx = i
break
}
}
return children[idx - 1] && next(children[idx - 1], subj) ?
children[idx - 1] :
null
}
function any_sibling(node, next, subj) {
var parent = options.parent(node)
, children
children = options.children(parent)
for(var i = 0, len = children.length; i < len; ++i) {
if(children[i] === node) {
return null
}
if(next(children[i], subj)) {
return children[i]
}
}
return null
}
function pseudo(token) {
return valid_pseudo(options, token.data, matchComparison)
}
}
function entry(node, next, subj) {
return next(node, subj) ? node : null
}
function valid_pseudo(options, match, matchComparison) {
switch(match) {
case 'empty': return valid_empty(options)
case 'first-child': return valid_first_child(options)
case 'last-child': return valid_last_child(options)
case 'root': return valid_root(options)
}
if(match.indexOf('contains') === 0) {
return valid_contains(options, match.slice(9, -1))
}
if(match.indexOf('any') === 0) {
return valid_any_match(options, match.slice(4, -1), matchComparison)
}
if(match.indexOf('not') === 0) {
return valid_not_match(options, match.slice(4, -1), matchComparison)
}
if(match.indexOf('nth-child') === 0) {
return valid_nth_child(options, match.slice(10, -1))
}
return function() {
return false
}
}
function valid_not_match(options, selector, matchComparison) {
var fn = parse(selector, options, matchComparison)
return not_function
function not_function(node) {
return !fn(node, true)
}
}
function valid_any_match(options, selector, matchComparison) {
var fn = parse(selector, options, matchComparison)
return fn
}
function valid_attr(fn, lhs, cmp, rhs) {
return function(node) {
var attr = fn(node, lhs)
if(!cmp) {
return !!attr
}
if(cmp.length === 1) {
return attr == rhs
}
if(attr === void 0 || attr === null) {
return false
}
return checkattr[cmp.charAt(0)](attr, rhs)
}
}
function valid_first_child(options) {
return function(node) {
return options.children(options.parent(node))[0] === node
}
}
function valid_last_child(options) {
return function(node) {
var children = options.children(options.parent(node))
return children[children.length - 1] === node
}
}
function valid_empty(options) {
return function(node) {
return options.children(node).length === 0
}
}
function valid_root(options) {
return function(node) {
return !options.parent(node)
}
}
function valid_contains(options, contents) {
return function(node) {
return options.contents(node).indexOf(contents) !== -1
}
}
function valid_nth_child(options, nth) {
var test = function(){ return false }
if (nth == 'odd') {
nth = '2n+1'
} else if (nth == 'even') {
nth = '2n'
}
var regexp = /( ?([-|\+])?(\d*)n)? ?((\+|-)? ?(\d+))? ?/
var matches = nth.match(regexp)
if (matches) {
var growth = 0;
if (matches[1]) {
var positiveGrowth = (matches[2] != '-')
growth = parseInt(matches[3] == '' ? 1 : matches[3])
growth = growth * (positiveGrowth ? 1 : -1)
}
var offset = 0
if (matches[4]) {
offset = parseInt(matches[6])
var positiveOffset = (matches[5] != '-')
offset = offset * (positiveOffset ? 1 : -1)
}
if (growth == 0) {
if (offset != 0) {
test = function(children, node) {
return children[offset - 1] === node
}
}
} else {
test = function(children, node) {
var validPositions = []
var len = children.length
for (var position=1; position <= len; position++) {
var divisible = ((position - offset) % growth) == 0;
if (divisible) {
if (growth > 0) {
validPositions.push(position);
} else {
if ((position - offset) / growth >= 0) {
validPositions.push(position);
}
}
}
}
for(var i=0; i < validPositions.length; i++) {
if (children[validPositions[i] - 1] === node) {
return true
}
}
return false
}
}
}
return function(node) {
var children = options.children(options.parent(node))
return test(children, node)
}
}
var checkattr = {
'$': check_end
, '^': check_beg
, '*': check_any
, '~': check_spc
, '|': check_dsh
}
function check_end(l, r) {
return l.slice(l.length - r.length) === r
}
function check_beg(l, r) {
return l.slice(0, r.length) === r
}
function check_any(l, r) {
return l.indexOf(r) > -1
}
function check_spc(l, r) {
return l.split(/\s+/).indexOf(r) > -1
}
function check_dsh(l, r) {
return l.split('-').indexOf(r) > -1
}
function caseSensitiveComparison(type, pattern, data) {
return pattern === data;
}