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; }