You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.2 KiB
117 lines
3.2 KiB
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; |
|
} |
|
};
|
|
|