* 检查节点是否符合规则
(node, rule)
| 89 | * 检查节点是否符合规则 |
| 90 | */ |
| 91 | function checkHit(node, rule) { |
| 92 | if (!node) return false |
| 93 | |
| 94 | const { |
| 95 | id, class: classList, tag, pseudo, attr |
| 96 | } = rule |
| 97 | |
| 98 | // id 选择器 |
| 99 | if (id) { |
| 100 | if (node.id !== id) return false |
| 101 | } |
| 102 | |
| 103 | // 类选择器 |
| 104 | if (classList && classList.length) { |
| 105 | for (const className of classList) { |
| 106 | if (!node.classList || !node.classList.contains(className)) return false |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // 标签选择器 |
| 111 | if (tag && tag !== '*') { |
| 112 | if (tool.checkIsWxComponent(tag.toLowerCase(), false)) { |
| 113 | // 内置组件 |
| 114 | if (node.tagName !== 'WX-COMPONENT' || node.behavior !== tag.slice(3).toLowerCase()) return false |
| 115 | } else if (node.tagName !== tag.toUpperCase()) { |
| 116 | return false |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | // 伪类选择器 |
| 121 | if (pseudo) { |
| 122 | for (const {name, param} of pseudo) { |
| 123 | const checkPseudo = PSEUDO_CHECK[name] |
| 124 | if (!checkPseudo || !checkPseudo(node, param, rule)) return false |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | // 属性选择器 |
| 129 | if (attr) { |
| 130 | for (const {name, opr, val} of attr) { |
| 131 | const nodeVal = node[name] || node.getAttribute(name) |
| 132 | |
| 133 | if (nodeVal === undefined || nodeVal === null) return false |
| 134 | if (opr) { |
| 135 | // 存在操作符 |
| 136 | const checkAttr = ATTR_CHECK[opr] |
| 137 | if (!checkAttr || !checkAttr(nodeVal, val)) return false |
| 138 | } |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | return true |
| 143 | } |
| 144 | |
| 145 | /** |
| 146 | * 数组去重 |
no test coverage detected