diff --git a/lib/soupselect.js b/lib/soupselect.js index 1f1142b..d60969d 100644 --- a/lib/soupselect.js +++ b/lib/soupselect.js @@ -19,7 +19,8 @@ var tagRe = /^[a-z0-9]+$/; | Attribute Tag */ -var attrSelectRe = /^(\w+)?\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/; +var attrSelectRe = /^(\w+)?((?:\[(?:[\w:]+)(?:[=~\|\^\$\*]?)=?"?(?:[^\]"]*)"?\])+)$/; +var attrSelectReInt = /^\[([\w:]+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\](.*)/; /** Takes an operator and a value and returns a function which can be used to @@ -47,6 +48,12 @@ function makeValueChecker(operator, value) { } +function combine(f1, f2) { + if (f1 === undefined) return f2; + return function(test_value) {return f1(test_value) && f2(test_value)}; +} + + /** Takes a dom tree or part of one from htmlparser and applies the provided selector against. The returned value is also @@ -64,11 +71,16 @@ exports.select = function(dom, selector) { // Attribute selectors var match = attrSelectRe.exec(tokens[i]); if ( match ) { - var attribute = match[2], operator = match[3], value = match[4]; + // var match_count = (match.length - 1)/3; tag = match[1]; - options = {}; - options[attribute] = makeValueChecker(operator, value); - + var predicates = function(str, options) { + if (str === '') return options; + var matchInt = attrSelectReInt.exec(str); + var attribute = matchInt[1], operator = matchInt[2], value = matchInt[3]; + options[attribute] = combine(options[attribute],makeValueChecker(operator, value)); + return predicates(matchInt[4], options); + }; + options = predicates(match[2], {}); found = []; for (var j = 0; j < currentContext.length; j++ ) { found = found.concat(domUtils.getElements(options, currentContext[j]));