| Leo Repp | 58b9f11 | 2021-11-22 11:57:47 +0100 | [diff] [blame^] | 1 | var attributes = require("./attributes.js"); |
| 2 | var Pseudos = require("./pseudos"); |
| 3 | |
| 4 | /* |
| 5 | all available rules |
| 6 | */ |
| 7 | module.exports = { |
| 8 | __proto__: null, |
| 9 | |
| 10 | attribute: attributes.compile, |
| 11 | pseudo: Pseudos.compile, |
| 12 | |
| 13 | //tags |
| 14 | tag: function(next, data, options) { |
| 15 | var name = data.name; |
| 16 | var adapter = options.adapter; |
| 17 | |
| 18 | return function tag(elem) { |
| 19 | return adapter.getName(elem) === name && next(elem); |
| 20 | }; |
| 21 | }, |
| 22 | |
| 23 | //traversal |
| 24 | descendant: function(next, data, options) { |
| 25 | // eslint-disable-next-line no-undef |
| 26 | var isFalseCache = typeof WeakSet !== "undefined" ? new WeakSet() : null; |
| 27 | var adapter = options.adapter; |
| 28 | |
| 29 | return function descendant(elem) { |
| 30 | var found = false; |
| 31 | |
| 32 | while (!found && (elem = adapter.getParent(elem))) { |
| 33 | if (!isFalseCache || !isFalseCache.has(elem)) { |
| 34 | found = next(elem); |
| 35 | if (!found && isFalseCache) { |
| 36 | isFalseCache.add(elem); |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | return found; |
| 42 | }; |
| 43 | }, |
| 44 | _flexibleDescendant: function(next, data, options) { |
| 45 | var adapter = options.adapter; |
| 46 | |
| 47 | // Include element itself, only used while querying an array |
| 48 | return function descendant(elem) { |
| 49 | var found = next(elem); |
| 50 | |
| 51 | while (!found && (elem = adapter.getParent(elem))) { |
| 52 | found = next(elem); |
| 53 | } |
| 54 | |
| 55 | return found; |
| 56 | }; |
| 57 | }, |
| 58 | parent: function(next, data, options) { |
| 59 | if (options && options.strict) { |
| 60 | throw new Error("Parent selector isn't part of CSS3"); |
| 61 | } |
| 62 | |
| 63 | var adapter = options.adapter; |
| 64 | |
| 65 | return function parent(elem) { |
| 66 | return adapter.getChildren(elem).some(test); |
| 67 | }; |
| 68 | |
| 69 | function test(elem) { |
| 70 | return adapter.isTag(elem) && next(elem); |
| 71 | } |
| 72 | }, |
| 73 | child: function(next, data, options) { |
| 74 | var adapter = options.adapter; |
| 75 | |
| 76 | return function child(elem) { |
| 77 | var parent = adapter.getParent(elem); |
| 78 | return !!parent && next(parent); |
| 79 | }; |
| 80 | }, |
| 81 | sibling: function(next, data, options) { |
| 82 | var adapter = options.adapter; |
| 83 | |
| 84 | return function sibling(elem) { |
| 85 | var siblings = adapter.getSiblings(elem); |
| 86 | |
| 87 | for (var i = 0; i < siblings.length; i++) { |
| 88 | if (adapter.isTag(siblings[i])) { |
| 89 | if (siblings[i] === elem) break; |
| 90 | if (next(siblings[i])) return true; |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | return false; |
| 95 | }; |
| 96 | }, |
| 97 | adjacent: function(next, data, options) { |
| 98 | var adapter = options.adapter; |
| 99 | |
| 100 | return function adjacent(elem) { |
| 101 | var siblings = adapter.getSiblings(elem), |
| 102 | lastElement; |
| 103 | |
| 104 | for (var i = 0; i < siblings.length; i++) { |
| 105 | if (adapter.isTag(siblings[i])) { |
| 106 | if (siblings[i] === elem) break; |
| 107 | lastElement = siblings[i]; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | return !!lastElement && next(lastElement); |
| 112 | }; |
| 113 | }, |
| 114 | universal: function(next) { |
| 115 | return next; |
| 116 | } |
| 117 | }; |