blob: dbc3cde8229eb087e85c52f98fd21c3a1cd7077b [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001var isTag = require("domelementtype").isTag;
2
3module.exports = {
4 filter: filter,
5 find: find,
6 findOneChild: findOneChild,
7 findOne: findOne,
8 existsOne: existsOne,
9 findAll: findAll
10};
11
12function filter(test, element, recurse, limit){
13 if(!Array.isArray(element)) element = [element];
14
15 if(typeof limit !== "number" || !isFinite(limit)){
16 limit = Infinity;
17 }
18 return find(test, element, recurse !== false, limit);
19}
20
21function find(test, elems, recurse, limit){
22 var result = [], childs;
23
24 for(var i = 0, j = elems.length; i < j; i++){
25 if(test(elems[i])){
26 result.push(elems[i]);
27 if(--limit <= 0) break;
28 }
29
30 childs = elems[i].children;
31 if(recurse && childs && childs.length > 0){
32 childs = find(test, childs, recurse, limit);
33 result = result.concat(childs);
34 limit -= childs.length;
35 if(limit <= 0) break;
36 }
37 }
38
39 return result;
40}
41
42function findOneChild(test, elems){
43 for(var i = 0, l = elems.length; i < l; i++){
44 if(test(elems[i])) return elems[i];
45 }
46
47 return null;
48}
49
50function findOne(test, elems){
51 var elem = null;
52
53 for(var i = 0, l = elems.length; i < l && !elem; i++){
54 if(!isTag(elems[i])){
55 continue;
56 } else if(test(elems[i])){
57 elem = elems[i];
58 } else if(elems[i].children.length > 0){
59 elem = findOne(test, elems[i].children);
60 }
61 }
62
63 return elem;
64}
65
66function existsOne(test, elems){
67 for(var i = 0, l = elems.length; i < l; i++){
68 if(
69 isTag(elems[i]) && (
70 test(elems[i]) || (
71 elems[i].children.length > 0 &&
72 existsOne(test, elems[i].children)
73 )
74 )
75 ){
76 return true;
77 }
78 }
79
80 return false;
81}
82
83function findAll(test, rootElems){
84 var result = [];
85 var stack = rootElems.slice();
86 while(stack.length){
87 var elem = stack.shift();
88 if(!isTag(elem)) continue;
89 if (elem.children && elem.children.length > 0) {
90 stack.unshift.apply(stack, elem.children);
91 }
92 if(test(elem)) result.push(elem);
93 }
94 return result;
95}