-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathcheerio.js
143 lines (111 loc) · 2.84 KB
/
cheerio.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
Module dependencies
*/
var path = require('path'),
select = require('cheerio-select'),
parse = require('./parse'),
evaluate = parse.evaluate,
updateDOM = parse.update,
_ = require('underscore');
/*
* The API
*/
var api = ['attributes', 'traversing', 'manipulation'];
/*
* A simple way to check for HTML strings or ID strings
*/
var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
/**
* Static Methods
*/
var $ = require('./static');
/*
* Instance of cheerio
*/
var Cheerio = module.exports = function(selector, context, root) {
if (!(this instanceof Cheerio)) return new Cheerio(selector, context, root);
// $(), $(null), $(undefined), $(false)
if (!selector) return this;
if (root) {
if (typeof root === 'string') root = parse(root);
this._root = this.make(root, this);
}
// $($)
if (selector.cheerio) return selector;
// $(dom)
if (selector.name || Array.isArray(selector))
return this.make(selector, this);
// $(<html>)
if (typeof selector === 'string' && isHtml(selector)) {
return this.make(parse(selector).children);
}
// If we don't have a context, maybe we have a root, from loading
if (!context) {
context = this._root;
} else if (typeof context === 'string') {
if (isHtml(context)) {
// $('li', '<ul>...</ul>')
context = parse(context);
context = this.make(context, this);
} else {
// $('li', 'ul')
selector = [context, selector].join(' ');
context = this._root;
}
}
// If we still don't have a context, return
if (!context) return this;
// #id, .class, tag
return context.find(selector);
};
/**
* Inherit from `static`
*/
Cheerio.__proto__ = require('./static');
/*
* Set a signature of the object
*/
Cheerio.prototype.cheerio = '[cheerio object]';
/*
* Cheerio default options
*/
Cheerio.prototype.options = {
ignoreWhitespace: false,
xmlMode: false,
lowerCaseTags: false
};
/*
* Make cheerio an array-like object
*/
Cheerio.prototype.length = 0;
Cheerio.prototype.sort = [].splice;
/*
* Check if string is HTML
*/
var isHtml = function(str) {
// Faster than running regex, if str starts with `<` and ends with `>`, assume it's HTML
if (str.charAt(0) === '<' && str.charAt(str.length - 1) === '>' && str.length >= 3) return true;
// Run the regex
var match = quickExpr.exec(str);
return !!(match && match[1]);
};
/*
* Make a cheerio object
*/
Cheerio.prototype.make = function(dom, context) {
if (dom.cheerio) return dom;
dom = (Array.isArray(dom)) ? dom : [dom];
return _.extend(context || new Cheerio(), dom, { length: dom.length });
};
/**
* Turn a cheerio object into an array
*/
Cheerio.prototype.toArray = function() {
return [].slice.call(this, 0);
};
/**
* Plug in the API
*/
api.forEach(function(mod) {
_.extend(Cheerio.prototype, require('./api/' + mod));
});