var DomUtils = require("domutils"), isTag = DomUtils.isTag, getParent = DomUtils.getParent, getChildren = DomUtils.getChildren, getSiblings = DomUtils.getSiblings, getName = DomUtils.getName; /* all available rules */ module.exports = { __proto__: null, attribute: require("./attributes.js").compile, pseudo: require("./pseudos.js").compile, //tags tag: function(next, data){ var name = data.name; return function tag(elem){ return getName(elem) === name && next(elem); }; }, //traversal descendant: function(next, rule, options, context, acceptSelf){ return function descendant(elem){ if (acceptSelf && next(elem)) return true; var found = false; 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"); return function parent(elem){ return getChildren(elem).some(test); }; function test(elem){ return isTag(elem) && next(elem); } }, child: function(next){ return function child(elem){ var parent = getParent(elem); return !!parent && next(parent); }; }, sibling: function(next){ return function sibling(elem){ var siblings = getSiblings(elem); for(var i = 0; i < siblings.length; i++){ if(isTag(siblings[i])){ if(siblings[i] === elem) break; if(next(siblings[i])) return true; } } return false; }; }, adjacent: function(next){ return function adjacent(elem){ var siblings = getSiblings(elem), lastElement; for(var i = 0; i < siblings.length; i++){ if(isTag(siblings[i])){ if(siblings[i] === elem) break; lastElement = siblings[i]; } } return !!lastElement && next(lastElement); }; }, universal: function(next){ return next; } };