* 查询符合条件的节点
(selector, extra)
| 332 | * 查询符合条件的节点 |
| 333 | */ |
| 334 | exec(selector, extra) { |
| 335 | selector = selector.trim().replace(/\s+/g, ' ').replace(/\s*(,|[>\s+~](?!=)|[*^$|~!]?=)\s*/g, '$1') |
| 336 | const {idMap, tagMap, classMap} = extra |
| 337 | |
| 338 | // 查询缓存 |
| 339 | let segment = this.getParseCache(selector) |
| 340 | |
| 341 | // 无缓存,进行解析 |
| 342 | if (!segment) { |
| 343 | segment = this.parse(selector) |
| 344 | |
| 345 | // 无法正常解析 |
| 346 | if (!segment) return [] |
| 347 | |
| 348 | this.setParseCache(selector, segment) |
| 349 | } |
| 350 | |
| 351 | // 无解析结果 |
| 352 | if (!segment[0]) return [] |
| 353 | |
| 354 | // 执行解析结果 |
| 355 | const lastRule = segment[segment.length - 1] // 从右往左 |
| 356 | const {id, class: classList, tag} = lastRule |
| 357 | let hitNodes = [] |
| 358 | |
| 359 | // 寻找可能符合要求的节点 |
| 360 | if (id) { |
| 361 | // id 选择器 |
| 362 | const node = idMap[id] |
| 363 | hitNodes = node ? [node] : [] |
| 364 | } else if (classList && classList.length) { |
| 365 | // 类选择器 |
| 366 | for (const className of classList) { |
| 367 | const classNodes = classMap[className] |
| 368 | if (classNodes) { |
| 369 | for (const classNode of classNodes) { |
| 370 | if (hitNodes.indexOf(classNode) === -1) hitNodes.push(classNode) |
| 371 | } |
| 372 | } |
| 373 | } |
| 374 | } else if (tag && tag !== '*') { |
| 375 | // 标签选择器,查询指定标签,支持内置组件 |
| 376 | const tagName = tool.checkIsWxComponent(tag.toLowerCase(), false) ? 'WX-COMPONENT' : tag.toUpperCase() |
| 377 | const tagNodes = tagMap[tagName] |
| 378 | if (tagNodes) hitNodes = tagNodes |
| 379 | } else { |
| 380 | // 标签选择器,查询全部节点 |
| 381 | Object.keys(tagMap).forEach(key => { |
| 382 | const tagNodes = tagMap[key] |
| 383 | if (tagNodes) { |
| 384 | for (const tagNode of tagNodes) hitNodes.push(tagNode) |
| 385 | } |
| 386 | }) |
| 387 | } |
| 388 | |
| 389 | // 从下往上过滤节点列表 |
| 390 | if (hitNodes.length && segment.length) { |
| 391 | for (let i = hitNodes.length - 1; i >= 0; i--) { |
no test coverage detected