UNPKG

3.92 kBJavaScriptView Raw
1var ElementType = require("./ElementType.js"),
2 arrayPush = Array.prototype.push,
3 DomUtils = module.exports;
4
5function filterArray(test, arr, recurse, limit){
6 var result = [], childs;
7
8 for(var i = 0, j = arr.length; i < j; i++){
9 if(test(arr[i])){
10 result.push(arr[i]);
11 if(--limit <= 0) break;
12 }
13
14 childs = arr[i].children;
15 if(recurse && childs){
16 childs = filterArray(test, childs, recurse, limit);
17 arrayPush.apply(result, childs);
18 limit -= childs.length;
19 if(limit <= 0) break;
20 }
21 }
22
23 return result;
24}
25
26function filter(test, element, recurse, limit){
27 if(recurse !== false) recurse = true;
28 if(isNaN(limit)) limit = Infinity;
29 if(!Array.isArray(element)) element = [element];
30
31 return filterArray(test, element, recurse, limit);
32}
33
34DomUtils.testElement = function(options, element){
35 var type = element.type;
36 for(var key in options){
37 if(!options.hasOwnProperty(key));
38 else if(key === "tag_name"){
39 if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style) return false;
40 if(!options.tag_name(element.name)) return false;
41 } else if(key === "tag_type"){
42 if(!options.tag_type(type)) return false;
43 } else if(key === "tag_contains"){
44 if(type !== ElementType.Text && type !== ElementType.Comment && type !== ElementType.Directive) return false;
45 if(!options.tag_contains(element.data)) return false;
46 } else if(!element.attribs || !options[key](element.attribs[key])) return false;
47 }
48
49 return true;
50};
51
52function getEqualityFunc(check){
53 return (function(val){ return val === check; });
54}
55
56DomUtils.getElements = function(options, element, recurse, limit){
57 for(var key in options){
58 if(options.hasOwnProperty(key) && typeof options[key] !== "function"){
59 options[key] = getEqualityFunc(options[key]);
60 }
61 }
62
63 return filter(function(elem){ return DomUtils.testElement(options, elem); }, element, recurse, limit);
64};
65
66DomUtils.getElementById = function(id, element, recurse){
67 var result;
68
69 if(typeof id === "function"){
70 result = filter(function(elem){ return elem.attribs && id(elem.attribs); }, element, recurse, 1);
71 } else {
72 result = filter(function(elem){ return elem.attribs && elem.attribs.id === id; }, element, recurse, 1);
73 }
74
75 return result.length ? result[0] : null;
76};
77
78DomUtils.getElementsByTagName = function(name, element, recurse, limit){
79 if(typeof name === "function"){
80 return filter(function(elem){
81 var type = elem.type;
82 if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style)
83 return false;
84 return name(elem.name);
85 }, element, recurse, limit);
86 }
87
88 return filter(function(elem){
89 var type = elem.type;
90 if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style)
91 return false;
92 return elem.name === name;
93 }, element, recurse, limit);
94};
95
96DomUtils.getElementsByTagType = function(type, element, recurse, limit){
97 if(typeof type === "function"){
98 return filter(function(elem){ return type(elem.type); }, element, recurse, limit);
99 } else {
100 return filter(function(elem){ return elem.type === type; }, element, recurse, limit);
101 }
102};
103
104DomUtils.getInnerHTML = function(elem){
105 if(!elem.children) return "";
106
107 var childs = elem.children,
108 childNum = childs.length,
109 ret = "";
110
111 for(var i = 0; i < childNum; i++){
112 ret += this.getOuterHTML(childs[i]);
113 }
114
115 return ret;
116};
117
118DomUtils.getOuterHTML = function(elem){
119 var type = elem.type,
120 name = elem.name;
121
122 if(type === ElementType.Text) return elem.data;
123 if(type === ElementType.Comment) return "<!--" + elem.data + "-->";
124
125 var ret = "<" + name;
126 if(elem.hasOwnProperty("attribs")){
127 for(var attr in elem.attribs){
128 if(elem.attribs.hasOwnProperty(attr)){
129 ret += " " + attr + "=\"" + elem.attribs[attr] + "\"";
130 }
131 }
132 }
133
134 ret += ">";
135
136 if(type === ElementType.Directive) return ret;
137
138 return ret + this.getInnerHTML(elem) + "</" + name + ">";
139};
\No newline at end of file