diff --git a/lib/compile.js b/lib/compile.js index 91ac5925..679c391f 100644 --- a/lib/compile.js +++ b/lib/compile.js @@ -44,6 +44,7 @@ function includesScopePseudo(t){ } var DESCENDANT_TOKEN = {type: "descendant"}, + FLEXIBLE_DESCENDANT_TOKEN = {type: "flexibleDescendant"}, SCOPE_TOKEN = {type: "pseudo", name: "scope"}, PLACEHOLDER_ELEMENT = {}, getParent = DomUtils.getParent; @@ -83,8 +84,14 @@ function compileToken(token, options, context){ absolutize(token, context); + console.log(token); return token - .map(function(rules){ return compileRules(rules, options, context, isArrayContext); }) + .map(function(rules){ + if (isArrayContext && rules[0] && rules[1] && rules[0].name === "scope" && rules[1].type === "descendant") { + rules[1] = FLEXIBLE_DESCENDANT_TOKEN; + } + return compileRules(rules, options, context); + }) .reduce(reduceRules, falseFunc); } @@ -92,11 +99,10 @@ function isTraversal(t){ return procedure[t.type] < 0; } -function compileRules(rules, options, context, isArrayContext){ - var acceptSelf = (isArrayContext && rules[0].name === "scope" && rules[1].type === "descendant"); - return rules.reduce(function(func, rule, index){ +function compileRules(rules, options, context){ + return rules.reduce(function(func, rule){ if(func === falseFunc) return func; - return Rules[rule.type](func, rule, options, context, acceptSelf && index === 1); + return Rules[rule.type](func, rule, options, context); }, options && options.rootFunc || trueFunc); } diff --git a/lib/general.js b/lib/general.js index fbc960fe..a714a388 100644 --- a/lib/general.js +++ b/lib/general.js @@ -23,11 +23,9 @@ module.exports = { }, //traversal - descendant: function(next, rule, options, context, acceptSelf){ + descendant: function(next){ return function descendant(elem){ - if (acceptSelf && next(elem)) return true; - var found = false; while(!found && (elem = getParent(elem))){ @@ -37,6 +35,19 @@ module.exports = { return found; }; }, + flexibleDescendant: function(next){ + // Include element itself, only used while querying an array + return function descendant(elem){ + + var found = next(elem); + + while(!found && (elem = getParent(elem))){ + found = next(elem); + } + + return found; + }; + }, parent: function(next, data, options){ if(options && options.strict) throw SyntaxError("Parent selector isn't part of CSS3");