Skip to content

Commit

Permalink
add support for commas
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdickinson committed Jul 15, 2013
1 parent 3c93934 commit 31f9955
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
43 changes: 31 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ function opt_okay(opts, key) {

function parse(selector, options) {
var stream = tokenizer()
, bits = []
, selectors = [[]]
, traversal
, length
, bits

bits = selectors[0]

traversal = {
'': any_parents
Expand All @@ -40,9 +42,12 @@ function parse(selector, options) {
.on('data', group)
.end(selector)

length = bits.length

function group(token) {
if(token.type === 'comma') {
selectors.unshift(bits = [])
return
}

if(token.type === 'op' || token.type === 'any-child') {
bits.unshift(traversal[token.data])
bits.unshift(check())
Expand All @@ -58,19 +63,33 @@ function parse(selector, options) {
}

return function(node) {
var current = entry
var current
, length
, orig

orig = node

for(var i = 0; i < length; i += 2) {
node = current(node, bits[i])
for(var i = 0, len = selectors.length; i < len; ++i) {
bits = selectors[i]
current = entry
length = bits.length
node = orig

if(!node) {
return false
for(var j = 0; j < length; j += 2) {
node = current(node, bits[j])

if(!node) {
break
}

current = bits[j + 1]
}

current = bits[i + 1]
if(j >= length) {
return true
}
}

return true
return false
}

function check() {
Expand Down
4 changes: 4 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ function test_select_multiple() {
parent.parent = root

assert.ok(language('#root-id #one-id')(data))
assert.ok(language('#nope,#root-id #one-id')(data))
assert.ok(!language('#nope, #nada')(data))
assert.ok(!language('#root-id > #one-id')(data))
assert.ok(language('#root-id > #parent-id > #one-id')(data))
assert.ok(language('#parent-id > #one-id,\n#root-id > #parent-id > #one-id')(data))
assert.ok(language('#ok,\n #parent-id > #one-id,\n#root-id > #parent-id > #one-id')(data))
assert.ok(language('.one-class + .two-class')(data2))
assert.ok(!language('.one-class + #one-id')(data))
assert.ok(language('one-tag ~ #three-id')(data3))
Expand Down
9 changes: 9 additions & 0 deletions tokenizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var PSEUDOSTART = 'pseudo-start'
, READY = '(ready)'
, OPERATION = 'op'
, CLASS = 'class'
, COMMA = 'comma'
, ATTR = 'attr'
, TAG = 'tag'
, STAR = '*'
Expand Down Expand Up @@ -73,6 +74,7 @@ function tokenize() {
case ':' === c: state = PSEUDOCLASS; break
case '[' === c: state = ATTR_START; break
case '*' === c: star(); break
case ',' === c: comma(); break
case /[>\+~]/.test(c): state = OPERATION; break
case /\s/.test(c): state = ANY_CHILD; break
case /[\w\d\-_]/.test(c): state = TAG; --idx; break
Expand All @@ -86,6 +88,13 @@ function tokenize() {
state = READY
}

function comma() {
state = COMMA
gathered = [',']
stream.queue(token())
state = READY
}

function state_op() {
if(/[>\+~]/.test(c)) {
return gathered.push(c)
Expand Down

0 comments on commit 31f9955

Please sign in to comment.