| var isTag = require("domelementtype").isTag; |
| |
| module.exports = { |
| filter: filter, |
| find: find, |
| findOneChild: findOneChild, |
| findOne: findOne, |
| existsOne: existsOne, |
| findAll: findAll |
| }; |
| |
| function filter(test, element, recurse, limit){ |
| if(!Array.isArray(element)) element = [element]; |
| |
| if(typeof limit !== "number" || !isFinite(limit)){ |
| limit = Infinity; |
| } |
| return find(test, element, recurse !== false, limit); |
| } |
| |
| function find(test, elems, recurse, limit){ |
| var result = [], childs; |
| |
| for(var i = 0, j = elems.length; i < j; i++){ |
| if(test(elems[i])){ |
| result.push(elems[i]); |
| if(--limit <= 0) break; |
| } |
| |
| childs = elems[i].children; |
| if(recurse && childs && childs.length > 0){ |
| childs = find(test, childs, recurse, limit); |
| result = result.concat(childs); |
| limit -= childs.length; |
| if(limit <= 0) break; |
| } |
| } |
| |
| return result; |
| } |
| |
| function findOneChild(test, elems){ |
| for(var i = 0, l = elems.length; i < l; i++){ |
| if(test(elems[i])) return elems[i]; |
| } |
| |
| return null; |
| } |
| |
| function findOne(test, elems){ |
| var elem = null; |
| |
| for(var i = 0, l = elems.length; i < l && !elem; i++){ |
| if(!isTag(elems[i])){ |
| continue; |
| } else if(test(elems[i])){ |
| elem = elems[i]; |
| } else if(elems[i].children.length > 0){ |
| elem = findOne(test, elems[i].children); |
| } |
| } |
| |
| return elem; |
| } |
| |
| function existsOne(test, elems){ |
| for(var i = 0, l = elems.length; i < l; i++){ |
| if( |
| isTag(elems[i]) && ( |
| test(elems[i]) || ( |
| elems[i].children.length > 0 && |
| existsOne(test, elems[i].children) |
| ) |
| ) |
| ){ |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| function findAll(test, rootElems){ |
| var result = []; |
| var stack = rootElems.slice(); |
| while(stack.length){ |
| var elem = stack.shift(); |
| if(!isTag(elem)) continue; |
| if (elem.children && elem.children.length > 0) { |
| stack.unshift.apply(stack, elem.children); |
| } |
| if(test(elem)) result.push(elem); |
| } |
| return result; |
| } |