querying.js 1.8 KB

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