-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.js
112 lines (94 loc) · 2.54 KB
/
parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* global module: true */
var parser = function () {
'use strict';
function Collection(nodes) {
extend(this, nodes);
this.length = nodes.length;
this.parent = null;
}
/*
* Method extend from Underscore.js 1.6.0
* http://underscorejs.org
* (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Underscore may be freely distributed under the MIT license.
*/
function extend(obj) {
Array.prototype.slice.call(arguments, 1).forEach(function (source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
}
});
return obj;
}
function nodeMatcher(node, selectorExpr) {
var type = typeof selectorExpr;
if (type === 'string') {
return node.name === selectorExpr;
} else if (type === 'function') {
return !!selectorExpr(node);
} else {
throw new TypeError('Cannot filter node with selector ' + selectorExpr);
}
}
Collection.prototype = {
toArray: function () {
return Array.prototype.slice.call(this);
},
find: function (selectorExpr) {
var foundNodes = [];
this.traverse(function (node) {
if (nodeMatcher(node, selectorExpr)) {
foundNodes.push(node);
}
});
return this.pushStack(foundNodes);
},
filter: function(selectorExpr) {
var filteredNodes = this.toArray().filter(function(node) {
return nodeMatcher(node, selectorExpr);
});
return this.pushStack(filteredNodes);
},
each: function (callback) {
this.toArray().forEach(callback);
return this;
},
map: function (callback) {
return this.toArray().map(callback);
},
traverse: function (callback) {
function traverse(node, index) {
callback.call(node, node, index);
(node.leaf || []).forEach(traverse);
}
this.each(traverse);
return this;
},
pushStack: function (nodes) {
var newInstance = new Collection(nodes);
newInstance.parent = this;
return newInstance;
},
children: function () {
var allChildren = [];
this.each(function (node) {
allChildren = allChildren.concat(node.leaf);
});
return this.pushStack(allChildren);
},
props: function (propName) {
return this.map(function (node) {
return node[propName];
});
},
names: function () {
return this.props('name');
}
};
return function (nodes) {
return new Collection(nodes);
};
};
module.exports = parser;