var attributes = require("./attributes.js"); var Pseudos = require("./pseudos"); /* all available rules */ module.exports = { __proto__: null, attribute: attributes.compile, pseudo: Pseudos.compile, //tags tag: function(next, data, options) { var name = data.name; var adapter = options.adapter; return function tag(elem) { return adapter.getName(elem) === name && next(elem); }; }, //traversal descendant: function(next, data, options) { // eslint-disable-next-line no-undef var isFalseCache = typeof WeakSet !== "undefined" ? new WeakSet() : null; var adapter = options.adapter; return function descendant(elem) { var found = false; while (!found && (elem = adapter.getParent(elem))) { if (!isFalseCache || !isFalseCache.has(elem)) { found = next(elem); if (!found && isFalseCache) { isFalseCache.add(elem); } } } return found; }; }, _flexibleDescendant: function(next, data, options) { var adapter = options.adapter; // Include element itself, only used while querying an array return function descendant(elem) { var found = next(elem); while (!found && (elem = adapter.getParent(elem))) { found = next(elem); } return found; }; }, parent: function(next, data, options) { if (options && options.strict) { throw new Error("Parent selector isn't part of CSS3"); } var adapter = options.adapter; return function parent(elem) { return adapter.getChildren(elem).some(test); }; function test(elem) { return adapter.isTag(elem) && next(elem); } }, child: function(next, data, options) { var adapter = options.adapter; return function child(elem) { var parent = adapter.getParent(elem); return !!parent && next(parent); }; }, sibling: function(next, data, options) { var adapter = options.adapter; return function sibling(elem) { var siblings = adapter.getSiblings(elem); for (var i = 0; i < siblings.length; i++) { if (adapter.isTag(siblings[i])) { if (siblings[i] === elem) break; if (next(siblings[i])) return true; } } return false; }; }, adjacent: function(next, data, options) { var adapter = options.adapter; return function adjacent(elem) { var siblings = adapter.getSiblings(elem), lastElement; for (var i = 0; i < siblings.length; i++) { if (adapter.isTag(siblings[i])) { if (siblings[i] === elem) break; lastElement = siblings[i]; } } return !!lastElement && next(lastElement); }; }, universal: function(next) { return next; } };