UNPKG

4.16 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 if(name === "*") return filter(function(elem){
89 var type = elem.type;
90 return type === ElementType.Tag || type === ElementType.Script || type === ElementType.Style;
91 });
92
93 return filter(function(elem){
94 var type = elem.type;
95 if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style)
96 return false;
97 return elem.name === name;
98 }, element, recurse, limit);
99};
100
101DomUtils.getElementsByTagType = function(type, element, recurse, limit){
102 if(typeof type === "function"){
103 return filter(function(elem){ return type(elem.type); }, element, recurse, limit);
104 } else {
105 return filter(function(elem){ return elem.type === type; }, element, recurse, limit);
106 }
107};
108
109DomUtils.getInnerHTML = function(elem){
110 if(!elem.children) return "";
111
112 var childs = elem.children,
113 childNum = childs.length,
114 ret = "";
115
116 for(var i = 0; i < childNum; i++){
117 ret += this.getOuterHTML(childs[i]);
118 }
119
120 return ret;
121};
122
123DomUtils.getOuterHTML = function(elem){
124 var type = elem.type,
125 name = elem.name;
126
127 if(type === ElementType.Text) return elem.data;
128 if(type === ElementType.Comment) return "<!--" + elem.data + "-->";
129 if(type === ElementType.Directive) return "<" + elem.data + ">";
130
131 var ret = "<" + name;
132 if(elem.hasOwnProperty("attribs")){
133 for(var attr in elem.attribs){
134 if(elem.attribs.hasOwnProperty(attr)){
135 ret += " " + attr + "=\"" + elem.attribs[attr] + "\"";
136 }
137 }
138 }
139
140 ret += ">";
141
142 if(type === ElementType.Directive) return ret;
143
144 return ret + this.getInnerHTML(elem) + "</" + name + ">";
145};
\No newline at end of file