UNPKG

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