Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions lib/soupselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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]));
Expand Down