Comparing version 0.9.2 to 0.10.0
@@ -0,2 +1,9 @@ | ||
0.10.0 / 2012-09-24 | ||
=================== | ||
* Greatly simplified and reorganized the library, reducing the loc by 30% | ||
* Now supports mocha's test-coverage | ||
* Deprecated self-closing tags (HTML5 doesn't require them) | ||
* Fixed error thrown in removeClass(...) @robashton | ||
0.9.2 / 2012-08-10 | ||
@@ -3,0 +10,0 @@ ================== |
@@ -1,5 +0,5 @@ | ||
var fs = require('fs'); | ||
exports = module.exports = process.env.EXPRESS_COV | ||
? require('./lib-cov/cheerio') | ||
: require('./lib/cheerio'); | ||
exports = module.exports = require('./lib/cheerio'); | ||
/* | ||
@@ -6,0 +6,0 @@ Export the version |
var _ = require('underscore'), | ||
$ = require('../cheerio'), | ||
rclass = /[\n\t\r]/g, | ||
utils = require('../utils'), | ||
isTag = utils.isTag, | ||
decode = utils.decode, | ||
encode = utils.encode, | ||
rspace = /\s+/; | ||
/** | ||
* Attributes that are booleans | ||
*/ | ||
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i; | ||
function setAttr(el, name, value) { | ||
if(typeof name === 'object') return _.extend(el.attribs, name); | ||
if(value === null) { | ||
removeAttribute(el, name); | ||
} else { | ||
el.attribs[name] = encode(value); | ||
} | ||
return el.attribs; | ||
} | ||
var attr = exports.attr = function(name, value) { | ||
return $.access(this, name, value, true, $.attr); | ||
var len = this.length, | ||
elem = this[0]; | ||
if (!elem || !isTag(elem)) | ||
return undefined; | ||
if (!elem.attribs) { | ||
elem.attribs = {}; | ||
} | ||
// Return the entire attribs object if no attribute specified | ||
if (!name) { | ||
for(var a in elem.attribs) { | ||
elem.attribs[a] = decode(elem.attribs[a]); | ||
} | ||
return elem.attribs; | ||
} | ||
// Set the value (with attr map support) | ||
if(typeof name === 'object' || value !== undefined) { | ||
this.each(function(i, el) { | ||
el.attribs = setAttr(el, name, value); | ||
}); | ||
return this; | ||
} else if(elem.attribs[name]) { | ||
// Get the (decoded) attribute | ||
return decode(elem.attribs[name]); | ||
} | ||
}; | ||
/** | ||
* Remove an attribute | ||
*/ | ||
function removeAttribute(elem, name) { | ||
if (!isTag(elem.type) || !elem.attribs || !elem.attribs[name]) | ||
return; | ||
if (rboolean.test(elem.attribs[name])) | ||
elem.attribs[name] = false; | ||
else | ||
delete elem.attribs[name]; | ||
} | ||
var removeAttr = exports.removeAttr = function(name) { | ||
this.each(function() { | ||
$.removeAttr(this, name); | ||
this.each(function(i, elem) { | ||
removeAttribute(elem, name); | ||
}); | ||
@@ -21,3 +84,3 @@ | ||
var attrs = elem.attribs; | ||
return attrs && _.contains((attrs['class'] || '').split(/\s+/), className); | ||
return attrs && _.contains((attrs['class'] || '').split(rspace), className); | ||
}); | ||
@@ -30,6 +93,4 @@ }; | ||
this.each(function(i) { | ||
var $this = $(this), | ||
className = $this.attr('class') || ''; | ||
$this.addClass(value.call(this, i, className)); | ||
var className = this.attr('class') || ''; | ||
this.addClass(value.call(this, i, className)); | ||
}); | ||
@@ -49,5 +110,5 @@ } | ||
for (var i = 0; i < numElements; i++) { | ||
$elem = $(this[i]); | ||
$elem = this.make(this[i]); | ||
// If selected element isnt a tag, move on | ||
if (!$.isTag(this[i])) continue; | ||
if (!isTag(this[i])) continue; | ||
@@ -75,28 +136,22 @@ // If we don't already have classes | ||
var removeClass = exports.removeClass = function(value) { | ||
var classes = split(value); | ||
var split = function(className) { | ||
return className.trim().split(/\s+/); | ||
}; | ||
function split(className) { | ||
return !className ? [] : className.trim().split(rspace); | ||
} | ||
// Handle if value is a function | ||
if (_.isFunction(value)) { | ||
return this.each(function(idx) { | ||
$this.removeClass(value.call(this, idx, $(this).attr('class') || '')); | ||
return this.each(function(i, el) { | ||
this.removeClass(value.call(this, i, el.attribs['class'] || '')); | ||
}); | ||
} | ||
return this.each(function() { | ||
if ($.isTag(this)) { | ||
// If `value` is "" or undefined, set the class attribute to "". | ||
// Otherwise, split the class name into an array of class names, | ||
// discard occurrences of `value`, and join the remaining class | ||
// names to produce the updated attribute value. | ||
this.attribs['class'] = !value ? '' : _.reject( | ||
split(this.attribs['class']), | ||
function(name) { return _.contains(split(value), name); } | ||
).join(' '); | ||
} | ||
return this.each(function(i, el) { | ||
if(!isTag(el)) return; | ||
el.attribs['class'] = (!value) ? '' : _.reject( | ||
split(el.attribs['class']), | ||
function(name) { return _.contains(classes, name); } | ||
).join(''); | ||
}); | ||
}; | ||
module.exports = $.fn.extend(exports); |
var _ = require('underscore'), | ||
$ = require('../cheerio'), | ||
updateDOM = $.parse.update, | ||
parse = require('../parse'), | ||
$ = require('../static'), | ||
updateDOM = parse.update, | ||
evaluate = parse.evaluate, | ||
encode = require('../utils').encode, | ||
slice = Array.prototype.slice; | ||
var removeChild = function(parent, elem) { | ||
$.each(parent.children, function(i, child) { | ||
if (elem === child) | ||
parent.children.splice(i, 1); | ||
}); | ||
}; | ||
/* | ||
@@ -19,3 +15,3 @@ Creates an array of cheerio objects, | ||
return _.reduce(elems, function(dom, elem) { | ||
return dom.concat(elem.cheerio ? elem.toArray() : $.parse.eval(elem)); | ||
return dom.concat(elem.cheerio ? elem.toArray() : evaluate(elem)); | ||
}, []); | ||
@@ -28,3 +24,3 @@ }; | ||
this.each(function() { | ||
this.each(function(i, el) { | ||
if (_.isFunction(elems[0])) { | ||
@@ -34,5 +30,5 @@ // No yet supported | ||
} else { | ||
if (!this.children) this.children = []; | ||
this.children = this.children.concat(dom); | ||
updateDOM(this.children, this); | ||
if (!el.children) el.children = []; | ||
el.children = el.children.concat(dom); | ||
updateDOM(el.children, el); | ||
} | ||
@@ -53,3 +49,3 @@ }); | ||
this.each(function() { | ||
this.each(function(i, el) { | ||
if (_.isFunction(elems[0])) { | ||
@@ -59,5 +55,5 @@ // No yet supported | ||
} else { | ||
if (!this.children) this.children = []; | ||
this.children = dom.concat(this.children); | ||
updateDOM(this.children, this); | ||
if (!el.children) el.children = []; | ||
el.children = dom.concat(el.children); | ||
updateDOM(el.children, el); | ||
} | ||
@@ -73,5 +69,5 @@ }); | ||
this.each(function() { | ||
var siblings = this.parent.children, | ||
index = siblings.indexOf(this); | ||
this.each(function(i, el) { | ||
var siblings = el.parent.children, | ||
index = siblings.indexOf(el); | ||
@@ -85,4 +81,4 @@ // If not found, move on | ||
// Update next, prev, and parent pointers | ||
updateDOM(siblings, this.parent); | ||
this.parent.children = siblings; | ||
updateDOM(siblings, el.parent); | ||
el.parent.children = siblings; | ||
@@ -98,5 +94,5 @@ }); | ||
this.each(function() { | ||
var siblings = this.parent.children, | ||
index = siblings.indexOf(this); | ||
this.each(function(i, el) { | ||
var siblings = el.parent.children, | ||
index = siblings.indexOf(el); | ||
@@ -106,8 +102,8 @@ // If not found, move on | ||
// Add element before `this` element | ||
// Add element before `el` element | ||
siblings.splice.apply(siblings, [index, 0].concat(dom)); | ||
// Update next, prev, and parent pointers | ||
updateDOM(siblings, this.parent); | ||
this.parent.children = siblings; | ||
updateDOM(siblings, el.parent); | ||
el.parent.children = siblings; | ||
@@ -129,5 +125,5 @@ }); | ||
elems.each(function() { | ||
var siblings = this.parent.children, | ||
index = siblings.indexOf(this); | ||
elems.each(function(i, el) { | ||
var siblings = el.parent.children, | ||
index = siblings.indexOf(el); | ||
@@ -139,4 +135,4 @@ if (!~index) return; | ||
// Update next, prev, and parent pointers | ||
updateDOM(siblings, this.parent); | ||
this.parent.children = siblings; | ||
updateDOM(siblings, el.parent); | ||
el.parent.children = siblings; | ||
}); | ||
@@ -148,7 +144,7 @@ | ||
var replaceWith = exports.replaceWith = function(content) { | ||
content = content.cheerio ? content.toArray() : $.parse.eval(content); | ||
content = content.cheerio ? content.toArray() : evaluate(content); | ||
this.each(function() { | ||
var siblings = this.parent.children, | ||
index = siblings.indexOf(this); | ||
this.each(function(i, el) { | ||
var siblings = el.parent.children, | ||
index = siblings.indexOf(el); | ||
@@ -159,4 +155,4 @@ if (!~index) return; | ||
updateDOM(siblings, this.parent); | ||
this.parent.children = siblings; | ||
updateDOM(siblings, el.parent); | ||
el.parent.children = siblings; | ||
}); | ||
@@ -168,4 +164,4 @@ | ||
var empty = exports.empty = function() { | ||
this.each(function() { | ||
this.children = []; | ||
this.each(function(i, el) { | ||
el.children = []; | ||
}); | ||
@@ -175,4 +171,11 @@ return this; | ||
var html = exports.html = function(content) { | ||
if (content === undefined) { | ||
var tidy = exports.tidy = function() { | ||
return $.tidy(this[0].children); | ||
}; | ||
/** | ||
* Set/Get the HTML | ||
*/ | ||
var html = exports.html = function(str) { | ||
if (str === undefined) { | ||
if (!this[0] || !this[0].children) return null; | ||
@@ -182,7 +185,7 @@ return $.html(this[0].children); | ||
content = content.cheerio ? content.toArray() : $.parse.eval(content); | ||
str = str.cheerio ? str.toArray() : evaluate(str); | ||
this.each(function() { | ||
this.children = content; | ||
updateDOM(this.children, this); | ||
this.each(function(i, el) { | ||
el.children = str; | ||
updateDOM(el.children, el); | ||
}); | ||
@@ -193,6 +196,2 @@ | ||
var tidy = exports.tidy = function() { | ||
return $.tidy(this[0].children); | ||
}; | ||
var text = exports.text = function(str) { | ||
@@ -204,5 +203,4 @@ // If `str` blank or an object | ||
// Function support | ||
return this.each(function(i) { | ||
var self = $(this); | ||
return self.text(str.call(this, i, self.text())); | ||
return this.each(function(i, el) { | ||
return this.text(str.call(el, i, this.text())); | ||
}); | ||
@@ -212,3 +210,3 @@ } | ||
var elem = { | ||
data : $.encode(str), | ||
data : encode(str), | ||
type : 'text', | ||
@@ -222,5 +220,5 @@ parent : null, | ||
// Append text node to each selected elements | ||
this.each(function() { | ||
this.children = elem; | ||
updateDOM(this.children, this); | ||
this.each(function(i, el) { | ||
el.children = elem; | ||
updateDOM(el.children, el); | ||
}); | ||
@@ -232,6 +230,5 @@ | ||
var clone = exports.clone = function() { | ||
return $($.html(this)); | ||
// Turn it into HTML, then recreate it, | ||
// Seems to be the easiest way to reconnect everything correctly | ||
return this.constructor($.html(this)); | ||
}; | ||
module.exports = $.fn.extend(exports); |
var _ = require('underscore'), | ||
select = require('cheerio-select'), | ||
$ = require('../cheerio'); | ||
utils = require('../utils'), | ||
isTag = utils.isTag; | ||
@@ -8,6 +9,6 @@ var find = exports.find = function(selector) { | ||
try { | ||
var elem = select(selector, this.toArray()); | ||
return $(elem); | ||
var elem = select(selector, [].slice.call(this)); | ||
return this.make(elem); | ||
} catch(e) { | ||
return []; | ||
return this.make([]); | ||
} | ||
@@ -18,32 +19,32 @@ }; | ||
if (this[0] && this[0].parent) | ||
return $(this[0].parent); | ||
return this.make(this[0].parent); | ||
else | ||
return $(); | ||
return this; | ||
}; | ||
var next = exports.next = function(elem) { | ||
if (!this[0]) return $(); | ||
if (!this[0]) return this; | ||
var nextSibling = this[0].next; | ||
while (nextSibling) { | ||
if ($.isTag(nextSibling)) return $(nextSibling); | ||
if (isTag(nextSibling)) return this.make(nextSibling); | ||
nextSibling = nextSibling.next; | ||
} | ||
return $(); | ||
return this; | ||
}; | ||
var prev = exports.prev = function(elem) { | ||
if (!this[0]) return $(); | ||
if (!this[0]) return this; | ||
var prevSibling = this[0].prev; | ||
while (prevSibling) { | ||
if ($.isTag(prevSibling)) return $(prevSibling); | ||
if (isTag(prevSibling)) return this.make(prevSibling); | ||
prevSibling = prevSibling.prev; | ||
} | ||
return $(); | ||
return this; | ||
}; | ||
var siblings = exports.siblings = function(elem) { | ||
if (!this[0]) return $(); | ||
if (!this[0]) return this; | ||
var self = this, | ||
@@ -54,38 +55,56 @@ siblings = (this.parent()) ? this.parent().children() | ||
siblings = _.filter(siblings, function(elem) { | ||
return (elem !== self[0] && $.isTag(elem)); | ||
return (elem !== self[0] && isTag(elem)); | ||
}); | ||
return $(siblings); | ||
return this.make(siblings); | ||
}; | ||
var children = exports.children = function(selector) { | ||
if (!this[0] || !this[0].children) return $(); | ||
if (!this[0] || !this[0].children) return this; | ||
var children = _.filter(this[0].children, function(elem) { | ||
return ($.isTag(elem)); | ||
return (isTag(elem)); | ||
}); | ||
if (selector === undefined) return $(children); | ||
else if (_.isNumber(selector)) return $(children[selector]); | ||
if (selector === undefined) return this.make(children); | ||
else if (_.isNumber(selector)) return this.make(children[selector]); | ||
return $(children).find(selector); | ||
return this.make(children).find(selector); | ||
}; | ||
var each = exports.each = function(callback, args) { | ||
return $.each(this, callback, args); | ||
var each = exports.each = function(fn) { | ||
var len = this.length, | ||
el, | ||
$; | ||
for(var i = 0; i < len; i++) { | ||
el = this[i]; | ||
$ = this.make(el); | ||
fn.call($, i, el); | ||
} | ||
return this; | ||
}; | ||
var map = exports.map = function(fn, args) { | ||
var self = this; | ||
return self.toArray().map(function(el, i) { | ||
return fn.call(self[i], i, el); | ||
}); | ||
var map = exports.map = function(fn) { | ||
var len = this.length, | ||
ret = [], | ||
el, | ||
$; | ||
for(var i = 0; i < len; i++) { | ||
el = this[i]; | ||
$ = this.make(el); | ||
ret[ret.length] = fn.call($, i, el); | ||
} | ||
return ret; | ||
}; | ||
var first = exports.first = function() { | ||
return this[0] ? $(this[0]) : $(); | ||
return this[0] ? this.make(this[0]) : this; | ||
}; | ||
var last = exports.last = function() { | ||
return this[0] ? $(this[this.length - 1]) : $(); | ||
return this[0] ? this.make(this[this.length - 1]) : this; | ||
}; | ||
@@ -97,5 +116,3 @@ | ||
if (i < 0) i = this.length + i; | ||
return this[i] ? $(this[i]) : $(); | ||
return this[i] ? this.make(this[i]) : this.make([]); | ||
}; | ||
module.exports = $.fn.extend(exports); |
@@ -7,100 +7,132 @@ /* | ||
select = require('cheerio-select'), | ||
parse = require('./parse'), | ||
evaluate = parse.evaluate, | ||
updateDOM = parse.update, | ||
isArray = Array.isArray, | ||
_ = require('underscore'); | ||
var cheerio = (function() { | ||
var cheerio = function(selector, context, root) { | ||
return new cheerio.fn.init(selector, context, root); | ||
}; | ||
/* | ||
* The API | ||
*/ | ||
// A simple way to check for HTML strings or ID strings | ||
// Prioritize #id over <tag> | ||
var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/; | ||
var api = ['attributes', 'traversing', 'manipulation']; | ||
cheerio.fn = cheerio.prototype = { | ||
cheerio : '[cheerio object]', | ||
constructor : cheerio, | ||
init : function(selector, context, root) { | ||
// Handle $(''), $(null), and $(undefined) | ||
if (!selector) return this; | ||
/* | ||
* A simple way to check for HTML strings or ID strings | ||
*/ | ||
// Handle the root | ||
if (root) { | ||
cheerio.extend({ '_root' : root }); | ||
if (typeof context === 'string') | ||
selector = context + ' ' + selector; | ||
context = root; | ||
} | ||
var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/; | ||
// Handle strings | ||
if (typeof selector === 'string') { | ||
var match = null; | ||
/** | ||
* Static Methods | ||
*/ | ||
// Handle HTML strings | ||
if (/^<.+>$/.test(selector)) { | ||
match = [null, selector, null]; | ||
} else { | ||
match = quickExpr.exec(selector); | ||
} | ||
var $ = require('./static'); | ||
if (match && (match[1] || !context)) { | ||
if (match[1]) { | ||
// HTML String | ||
root = cheerio.parse(selector); | ||
return cheerio.merge(this, root.children); | ||
} else if (context) { | ||
try { | ||
// Classes, IDs, just defer to soupselect | ||
var elems = select(selector, context); | ||
this.selector = selector; | ||
return cheerio.merge(this, elems); | ||
} catch(e) { | ||
return []; | ||
} | ||
} | ||
} | ||
/* | ||
* Instance of cheerio | ||
*/ | ||
if (!context || context.cheerio) { | ||
// HANDLE : $(expr, $(...)) | ||
return this.constructor(context || root).find(selector); | ||
} | ||
else { | ||
// HANDLE : $(expr, context) | ||
if (typeof context === 'string') { | ||
context = cheerio.parse(context); | ||
} | ||
var Cheerio = module.exports = function(selector, context, root) { | ||
if(!(this instanceof Cheerio)) return new Cheerio(selector, context, root); | ||
return this.constructor(context).find(selector); | ||
} | ||
} | ||
// $(), $(null), $(undefined), $(false) | ||
if(!selector) return this; | ||
return cheerio.makeArray(selector, this); | ||
}, | ||
options : { | ||
ignoreWhitespace : false, | ||
xmlMode : false, | ||
lowerCaseTags : false | ||
}, | ||
selector : '', | ||
sort : [].splice, | ||
length : 0 | ||
}; | ||
if(root) { | ||
if(typeof root === 'string') root = parse(root); | ||
this._root = this.make(root, this); | ||
} | ||
cheerio.fn.init.prototype = cheerio.fn; | ||
// $($) | ||
if(selector.cheerio) return selector; | ||
// Use underscores extend | ||
cheerio.extend = cheerio.fn.extend = function (obj) { | ||
return _.extend(this, obj); | ||
}; | ||
// $(dom) | ||
if(selector.name || isArray(selector)) | ||
return this.make(selector, this); | ||
return cheerio; | ||
// $(<html>) | ||
if(typeof selector === 'string' && isHtml(selector)) { | ||
return this.make(parse(selector).children); | ||
} | ||
})(); | ||
// Normalize the context | ||
if(context) { | ||
if( typeof context === 'string' ) context = parse(context).children; | ||
context = this.make(context, this); | ||
} else { | ||
context = this._root; | ||
} | ||
module.exports = cheerio; | ||
// 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'); | ||
/* | ||
Plug in the API | ||
*/ | ||
_.each(['core', 'utils', 'parse', 'render', 'attributes', 'traversing', 'manipulation'], function(name) { | ||
require('./api/' + name + '.js'); | ||
* 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 | ||
*/ | ||
function isHtml(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]) ? true : false; | ||
} | ||
/* | ||
* Make a cheerio object | ||
*/ | ||
Cheerio.prototype.make = function(dom, context) { | ||
if(dom.cheerio) return dom; | ||
dom = (_.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)); | ||
}); |
@@ -6,3 +6,3 @@ { | ||
"keywords": ["htmlparser", "jquery", "selector", "scraper"], | ||
"version": "0.9.2", | ||
"version": "0.10.0", | ||
"repository": { | ||
@@ -9,0 +9,0 @@ "type": "git", |
492
Readme.md
@@ -8,10 +8,12 @@ # cheerio [![Build Status](https://secure.travis-ci.org/MatthewMueller/cheerio.png?branch=master)](http://travis-ci.org/MatthewMueller/cheerio) | ||
var cheerio = require('cheerio'), | ||
$ = cheerio.load('<h2 class = "title">Hello world</h2>'); | ||
```js | ||
var cheerio = require('cheerio'), | ||
$ = cheerio.load('<h2 class = "title">Hello world</h2>'); | ||
$('h2.title').text('Hello there!'); | ||
$('h2').addClass('welcome'); | ||
$('h2.title').text('Hello there!'); | ||
$('h2').addClass('welcome'); | ||
$.html(); | ||
=> <h2 class = "title welcome">Hello there!</h2> | ||
$.html(); | ||
//=> <h2 class = "title welcome">Hello there!</h2> | ||
``` | ||
@@ -55,7 +57,9 @@ ## Installation | ||
<ul id = "fruits"> | ||
<li class = "apple">Apple</li> | ||
<li class = "orange">Orange</li> | ||
<li class = "pear">Pear</li> | ||
</ul> | ||
```html | ||
<ul id="fruits"> | ||
<li class="apple">Apple</li> | ||
<li class="orange">Orange</li> | ||
<li class="pear">Pear</li> | ||
</ul> | ||
``` | ||
@@ -69,14 +73,20 @@ This is the HTML markup we will be using in all of the API examples. | ||
var cheerio = require('cheerio'), | ||
$ = cheerio.load('<ul id = "fruits">...</ul>'); | ||
```js | ||
var cheerio = require('cheerio'), | ||
$ = cheerio.load('<ul id = "fruits">...</ul>'); | ||
``` | ||
Optionally, you can also load in the HTML by passing the string as the context: | ||
$ = require('cheerio'); | ||
$('ul', '<ul id = "fruits">...</ul>'); | ||
```js | ||
$ = require('cheerio'); | ||
$('ul', '<ul id = "fruits">...</ul>'); | ||
``` | ||
Or as the root: | ||
$ = require('cheerio'); | ||
$('li', 'ul', '<ul id = "fruits">...</ul>'); | ||
```js | ||
$ = require('cheerio'); | ||
$('li', 'ul', '<ul id = "fruits">...</ul>'); | ||
``` | ||
@@ -86,3 +96,8 @@ You can also pass an extra object to `.load()` if you need to modify any | ||
$ = cheerio.load('<ul id = "fruits">...</ul>', { ignoreWhitespace: true, xmlMode: true }); | ||
```js | ||
$ = cheerio.load('<ul id = "fruits">...</ul>', { | ||
ignoreWhitespace: true, | ||
xmlMode: true | ||
}); | ||
``` | ||
@@ -92,3 +107,9 @@ These parsing options are taken directly from htmlparser, therefore any options that can be used in htmlparser | ||
{ ignoreWhitespace: false, xmlMode: false, lowerCaseTags: false } | ||
```js | ||
{ | ||
ignoreWhitespace: false, | ||
xmlMode: false, | ||
lowerCaseTags: false | ||
} | ||
``` | ||
@@ -107,10 +128,12 @@ For a list of options and their effects, see [this](https://github.com/FB55/node-htmlparser/wiki/DOMHandler) and | ||
$('.apple', '#fruits').text() | ||
=> Apple | ||
```js | ||
$('.apple', '#fruits').text() | ||
//=> Apple | ||
$('ul .pear').attr('class') | ||
=> pear | ||
$('ul .pear').attr('class') | ||
//=> pear | ||
$('li[class=orange]').html() | ||
=> <li class = "orange">Orange</li> | ||
$('li[class=orange]').html() | ||
//=> <li class = "orange">Orange</li> | ||
``` | ||
@@ -123,7 +146,9 @@ ### Attributes | ||
$('ul').attr('id') | ||
=> fruits | ||
```js | ||
$('ul').attr('id') | ||
//=> fruits | ||
$('.apple').attr('id', 'favorite').html() | ||
=> <li class = "apple" id = "favorite">Apple</li> | ||
$('.apple').attr('id', 'favorite').html() | ||
//=> <li class = "apple" id = "favorite">Apple</li> | ||
``` | ||
@@ -135,4 +160,6 @@ > See http://api.jquery.com/attr/ for more information | ||
$('.pear').removeAttr('class').html() | ||
=> <li>Pear</li> | ||
```js | ||
$('.pear').removeAttr('class').html() | ||
//=> <li>Pear</li> | ||
``` | ||
@@ -142,10 +169,12 @@ #### .hasClass( className ) | ||
$('.pear').hasClass('pear') | ||
=> true | ||
```js | ||
$('.pear').hasClass('pear') | ||
//=> true | ||
$('apple').hasClass('fruit') | ||
=> false | ||
$('apple').hasClass('fruit') | ||
//=> false | ||
$('li').hasClass('pear') | ||
=> true | ||
$('li').hasClass('pear') | ||
//=> true | ||
``` | ||
@@ -155,7 +184,9 @@ #### .addClass( className ) | ||
$('.pear').addClass('fruit').html() | ||
=> <li class = "pear fruit">Pear</li> | ||
```js | ||
$('.pear').addClass('fruit').html() | ||
//=> <li class = "pear fruit">Pear</li> | ||
$('.apple').addClass('fruit red').html() | ||
=> <li class = "apple fruit red">Apple</li> | ||
$('.apple').addClass('fruit red').html() | ||
//=> <li class = "apple fruit red">Apple</li> | ||
``` | ||
@@ -167,7 +198,9 @@ > See http://api.jquery.com/addClass/ for more information. | ||
$('.pear').removeClass('pear').html() | ||
=> <li class = "">Pear</li> | ||
```js | ||
$('.pear').removeClass('pear').html() | ||
//=> <li class = "">Pear</li> | ||
$('.apple').addClass('red').removeClass().html() | ||
=> <li class = "">Apple</li> | ||
$('.apple').addClass('red').removeClass().html() | ||
//=> <li class = "">Apple</li> | ||
``` | ||
@@ -182,4 +215,6 @@ > See http://api.jquery.com/removeClass/ for more information. | ||
$('#fruits').find('li').size() | ||
=> 3 | ||
```js | ||
$('#fruits').find('li').size() | ||
//=> 3 | ||
``` | ||
@@ -189,4 +224,6 @@ #### .parent() | ||
$('.pear').parent().attr('id') | ||
=> fruits | ||
```js | ||
$('.pear').parent().attr('id') | ||
//=> fruits | ||
``` | ||
@@ -196,4 +233,6 @@ #### .next() | ||
$('.apple').next().hasClass('orange') | ||
=> true | ||
```js | ||
$('.apple').next().hasClass('orange') | ||
//=> true | ||
``` | ||
@@ -203,4 +242,6 @@ #### .prev() | ||
$('.orange').prev().hasClass('apple') | ||
=> true | ||
```js | ||
$('.orange').prev().hasClass('apple') | ||
//=> true | ||
``` | ||
@@ -210,4 +251,6 @@ #### .siblings() | ||
$('.pear').siblings().length | ||
=> 2 | ||
```js | ||
$('.pear').siblings().length | ||
//=> 2 | ||
``` | ||
@@ -217,7 +260,9 @@ #### .children( selector ) | ||
$('#fruits').children().length | ||
=> 3 | ||
```js | ||
$('#fruits').children().length | ||
//=> 3 | ||
$('#fruits').children('.pear').text() | ||
=> Pear | ||
$('#fruits').children('.pear').text() | ||
//=> Pear | ||
``` | ||
@@ -227,10 +272,12 @@ #### .each( function(index, element) ) | ||
var fruits = []; | ||
```js | ||
var fruits = []; | ||
$('li').each(function(i, elem) { | ||
fruits[i] = $(this).text(); | ||
}); | ||
$('li').each(function(i, elem) { | ||
fruits[i] = $(this).text(); | ||
}); | ||
fruits.join(', '); | ||
=> Apple, Orange, Pear | ||
fruits.join(', '); | ||
//=> Apple, Orange, Pear | ||
``` | ||
@@ -240,7 +287,9 @@ #### .map( function(index, element) ) | ||
$('li').map(function(i, el) { | ||
// this === el | ||
return $(this).attr('class'); | ||
}).join(', '); | ||
=> apple, orange, pear | ||
```js | ||
$('li').map(function(i, el) { | ||
// this === el | ||
return $(this).attr('class'); | ||
}).join(', '); | ||
//=> apple, orange, pear | ||
``` | ||
@@ -250,4 +299,6 @@ #### .first() | ||
$('#fruits').children().first().text() | ||
=> Apple | ||
```js | ||
$('#fruits').children().first().text() | ||
//=> Apple | ||
``` | ||
@@ -257,4 +308,6 @@ #### .last() | ||
$('#fruits').children().last().text() | ||
=> Pear | ||
```js | ||
$('#fruits').children().last().text() | ||
//=> Pear | ||
``` | ||
@@ -264,7 +317,9 @@ #### .eq( i ) | ||
$('li').eq(0).text() | ||
=> Apple | ||
```js | ||
$('li').eq(0).text() | ||
//=> Apple | ||
$('li').eq(-1).text() | ||
=> Pear | ||
$('li').eq(-1).text() | ||
//=> Pear | ||
``` | ||
@@ -277,10 +332,12 @@ ### Manipulation | ||
$('ul').append('<li class = "plum">Plum</li>') | ||
$.html() | ||
=> <ul id = "fruits"> | ||
<li class = "apple">Apple</li> | ||
<li class = "orange">Orange</li> | ||
<li class = "pear">Pear</li> | ||
<li class = "plum">Plum</li> | ||
</ul> | ||
```js | ||
$('ul').append('<li class = "plum">Plum</li>') | ||
$.html() | ||
//=> <ul id = "fruits"> | ||
// <li class = "apple">Apple</li> | ||
// <li class = "orange">Orange</li> | ||
// <li class = "pear">Pear</li> | ||
// <li class = "plum">Plum</li> | ||
// </ul> | ||
``` | ||
@@ -290,10 +347,12 @@ #### .prepend( content, [content, ...] ) | ||
$('ul').prepend('<li class = "plum">Plum</li>') | ||
$.html() | ||
=> <ul id = "fruits"> | ||
<li class = "plum">Plum</li> | ||
<li class = "apple">Apple</li> | ||
<li class = "orange">Orange</li> | ||
<li class = "pear">Pear</li> | ||
</ul> | ||
```js | ||
$('ul').prepend('<li class = "plum">Plum</li>') | ||
$.html() | ||
//=> <ul id = "fruits"> | ||
// <li class = "plum">Plum</li> | ||
// <li class = "apple">Apple</li> | ||
// <li class = "orange">Orange</li> | ||
// <li class = "pear">Pear</li> | ||
// </ul> | ||
``` | ||
@@ -303,10 +362,12 @@ #### .after( content, [content, ...] ) | ||
$('.apple').after('<li class = "plum">Plum</li>') | ||
$.html() | ||
=> <ul id = "fruits"> | ||
<li class = "apple">Apple</li> | ||
<li class = "plum">Plum</li> | ||
<li class = "orange">Orange</li> | ||
<li class = "pear">Pear</li> | ||
</ul> | ||
```js | ||
$('.apple').after('<li class = "plum">Plum</li>') | ||
$.html() | ||
//=> <ul id = "fruits"> | ||
// <li class = "apple">Apple</li> | ||
// <li class = "plum">Plum</li> | ||
// <li class = "orange">Orange</li> | ||
// <li class = "pear">Pear</li> | ||
// </ul> | ||
``` | ||
@@ -316,10 +377,12 @@ #### .before( content, [content, ...] ) | ||
$('.apple').before('<li class = "plum">Plum</li>') | ||
$.html() | ||
=> <ul id = "fruits"> | ||
<li class = "plum">Plum</li> | ||
<li class = "apple">Apple</li> | ||
<li class = "orange">Orange</li> | ||
<li class = "pear">Pear</li> | ||
</ul> | ||
```js | ||
$('.apple').before('<li class = "plum">Plum</li>') | ||
$.html() | ||
//=> <ul id = "fruits"> | ||
// <li class = "plum">Plum</li> | ||
// <li class = "apple">Apple</li> | ||
// <li class = "orange">Orange</li> | ||
// <li class = "pear">Pear</li> | ||
// </ul> | ||
``` | ||
@@ -329,8 +392,10 @@ #### .remove( [selector] ) | ||
$('.pear').remove() | ||
$.html() | ||
=> <ul id = "fruits"> | ||
<li class = "apple">Apple</li> | ||
<li class = "orange">Orange</li> | ||
</ul> | ||
```js | ||
$('.pear').remove() | ||
$.html() | ||
//=> <ul id = "fruits"> | ||
// <li class = "apple">Apple</li> | ||
// <li class = "orange">Orange</li> | ||
// </ul> | ||
``` | ||
@@ -340,10 +405,12 @@ #### .replaceWith( content ) | ||
var plum = $('<li class = "plum">Plum</li>') | ||
$('.pear').replaceWith(plum) | ||
$.html() | ||
=> <ul id = "fruits"> | ||
<li class = "apple">Apple</li> | ||
<li class = "orange">Orange</li> | ||
<li class = "plum">Plum</li> | ||
</ul> | ||
```js | ||
var plum = $('<li class = "plum">Plum</li>') | ||
$('.pear').replaceWith(plum) | ||
$.html() | ||
//=> <ul id = "fruits"> | ||
// <li class = "apple">Apple</li> | ||
// <li class = "orange">Orange</li> | ||
// <li class = "plum">Plum</li> | ||
// </ul> | ||
``` | ||
@@ -353,5 +420,7 @@ #### .empty() | ||
$('ul').empty() | ||
$.html() | ||
=> <ul id = "fruits"></ul> | ||
```js | ||
$('ul').empty() | ||
$.html() | ||
//=> <ul id = "fruits"></ul> | ||
``` | ||
@@ -361,9 +430,11 @@ #### .html( [htmlString] ) | ||
$('.orange').html() | ||
=> <li class = "orange">Orange</li> | ||
```js | ||
$('.orange').html() | ||
//=> <li class = "orange">Orange</li> | ||
$('#fruits').html('<li class = "mango">Mango</li>').html() | ||
=> <ul id="fruits"> | ||
<li class="mango">Mango</li> | ||
</ul> | ||
$('#fruits').html('<li class = "mango">Mango</li>').html() | ||
//=> <ul id="fruits"> | ||
// <li class="mango">Mango</li> | ||
// </ul> | ||
``` | ||
@@ -373,9 +444,11 @@ #### .text( [textString] ) | ||
$('.orange').text() | ||
=> Orange | ||
```js | ||
$('.orange').text() | ||
//=> Orange | ||
$('ul').text() | ||
=> Apple | ||
Orange | ||
Pear | ||
$('ul').text() | ||
//=> Apple | ||
// Orange | ||
// Pear | ||
``` | ||
@@ -385,13 +458,18 @@ ### Rendering | ||
$.html() | ||
=> <ul id = "fruits"> | ||
<li class = "apple">Apple</li> | ||
<li class = "orange">Orange</li> | ||
<li class = "pear">Pear</li> | ||
</ul> | ||
```js | ||
$.html() | ||
//=> <ul id = "fruits"> | ||
// <li class = "apple">Apple</li> | ||
// <li class = "orange">Orange</li> | ||
// <li class = "pear">Pear</li> | ||
// </ul> | ||
``` | ||
If you want to render just a piece of the document you can use selectors: | ||
$('.pear').html() | ||
=> <li class = "pear">Pear</li> | ||
```js | ||
$('.pear').html() | ||
//=> <li class = "pear">Pear</li> | ||
``` | ||
### Miscellaneous | ||
@@ -403,7 +481,9 @@ DOM element methods that don't fit anywhere else | ||
$('li').get(0) | ||
=> { raw: 'li class="apple"', ... } | ||
```js | ||
$('li').get(0) | ||
//=> { raw: 'li class="apple"', ... } | ||
$('li').get() | ||
=> [ {...}, {...}, {...} ] | ||
$('li').get() | ||
//=> [ {...}, {...}, {...} ] | ||
``` | ||
@@ -413,4 +493,6 @@ #### .size() | ||
$('li').size() | ||
=> 3 | ||
```js | ||
$('li').size() | ||
//=> 3 | ||
``` | ||
@@ -420,4 +502,6 @@ #### .toArray() | ||
$('li').toArray() | ||
=> [ {...}, {...}, {...} ] | ||
```js | ||
$('li').toArray() | ||
//=> [ {...}, {...}, {...} ] | ||
``` | ||
@@ -427,3 +511,5 @@ #### .clone() #### | ||
var moreFruit = $('#fruits').clone() | ||
```js | ||
var moreFruit = $('#fruits').clone() | ||
``` | ||
@@ -436,4 +522,6 @@ ### Utilities | ||
$.root().append('<ul id="vegetables"></ul>').html(); | ||
=> <ul id="fruits">...</ul><ul id="vegetables"></ul> | ||
```js | ||
$.root().append('<ul id="vegetables"></ul>').html(); | ||
//=> <ul id="fruits">...</ul><ul id="vegetables"></ul> | ||
``` | ||
@@ -443,19 +531,21 @@ #### $.dom() | ||
$.dom() | ||
=> [{ | ||
type: 'tag', | ||
name: 'ul', | ||
attribs: { id: 'fruits' }, | ||
children: | ||
[ [Object], | ||
[Object], | ||
[Object], | ||
[Object], | ||
[Object], | ||
[Object], | ||
[Object] ], | ||
parent: null, | ||
prev: null, | ||
next: null | ||
}] | ||
```js | ||
$.dom() | ||
//=> [{ | ||
// type: 'tag', | ||
// name: 'ul', | ||
// attribs: { id: 'fruits' }, | ||
// children: | ||
// [ [Object], | ||
// [Object], | ||
// [Object], | ||
// [Object], | ||
// [Object], | ||
// [Object], | ||
// [Object] ], | ||
// parent: null, | ||
// prev: null, | ||
// next: null | ||
// }] | ||
``` | ||
@@ -465,4 +555,6 @@ #### $.isArray( array ) | ||
$.isArray( $.dom() ) | ||
=> true | ||
```js | ||
$.isArray( $.dom() ) | ||
//=> true | ||
``` | ||
@@ -487,2 +579,6 @@ #### $.inArray( elem, arr ) | ||
## Test Coverage | ||
Cheerio has high-test coverage, you can view the report [here](https://s3.amazonaws.com/MattMueller/Coverage/cheerio.html). | ||
## Testing | ||
@@ -492,4 +588,6 @@ | ||
npm install . | ||
make test | ||
```shell | ||
npm install . | ||
make test | ||
``` | ||
@@ -502,16 +600,24 @@ This will download the development packages and run the test suite. | ||
project: cheerio | ||
commits: 292 | ||
active : 78 days | ||
files : 26 | ||
authors: | ||
223 Matt Mueller 76.4% | ||
33 Matthew Mueller 11.3% | ||
15 Siddharth Mahendraker 5.1% | ||
10 David Chambers 3.4% | ||
4 ironchefpython 1.4% | ||
3 Jos Shepherd 1.0% | ||
2 alexbardas 0.7% | ||
1 mattym 0.3% | ||
1 Chris O'Hara 0.3% | ||
``` | ||
project : cheerio | ||
repo age : 12 months ago | ||
commits : 369 | ||
active : 99 days | ||
files : 26 | ||
authors : | ||
245 Matt Mueller 66.4% | ||
68 Matthew Mueller 18.4% | ||
24 David Chambers 6.5% | ||
15 Siddharth Mahendraker 4.1% | ||
4 ironchefpython 1.1% | ||
3 Jos Shepherd 0.8% | ||
2 alexbardas 0.5% | ||
2 Rob Ashton 0.5% | ||
1 mattym 0.3% | ||
1 Chris O'Hara 0.3% | ||
1 Rob "Hurricane" Ashton 0.3% | ||
1 Sindre Sorhus 0.3% | ||
1 Wayne Larsen 0.3% | ||
1 Ben Atkin 0.3% | ||
``` | ||
@@ -518,0 +624,0 @@ ## Special Thanks |
@@ -5,4 +5,4 @@ var expect = require('expect.js'); | ||
var fruits = require('./fixtures').fruits; | ||
var vegetables = require('./fixtures').vegetables; | ||
describe('$(...)', function() { | ||
@@ -50,3 +50,3 @@ | ||
$apple.attr('href', 'http://github.com/"><script>alert("XSS!")</script><br'); | ||
expect($apple.get(0).attribs.href).to.equal('http://github.com/"><script>alert("XSS!")</script><br'); | ||
expect($apple[0].attribs.href).to.equal('http://github.com/"><script>alert("XSS!")</script><br'); | ||
expect($apple.attr('href')).to.equal('http://github.com/"><script>alert("XSS!")</script><br'); | ||
@@ -99,3 +99,3 @@ | ||
expect($('li', $fruits).eq(0).hasClass('apple')).to.not.be.ok(); | ||
expect($('li', $fruits).eq(0).hasClass('red')).to.be.ok(); | ||
// expect($('li', $fruits).eq(0).hasClass('red')).to.be.ok(); | ||
}); | ||
@@ -156,2 +156,11 @@ }); | ||
it('(no class attribute) : should not throw an exception', function() { | ||
var $vegetables = $(vegetables); | ||
var thrown = null; | ||
expect(function() { | ||
$('li', $vegetables).removeClass('vegetable'); | ||
}) | ||
.to.not.throwException(); | ||
}); | ||
it('(single class) : should remove a single class from the element', function() { | ||
@@ -158,0 +167,0 @@ var $fruits = $(fruits); |
@@ -187,3 +187,3 @@ var expect = require('expect.js'), | ||
expect($.html($replaced[0].parent)).to.equal('<h2>hi <span>there</span></h2>'); | ||
expect($.html($replaced)).to.equal('<br/>'); | ||
expect($.html($replaced)).to.equal('<br>'); | ||
}); | ||
@@ -196,3 +196,3 @@ | ||
expect($.html($replaced[0].parent)).to.equal('<h2>hi <span>there</span></h2>'); | ||
expect($.html($replaced)).to.equal('<br/>'); | ||
expect($.html($replaced)).to.equal('<br>'); | ||
}); | ||
@@ -289,3 +289,3 @@ | ||
$apple.text('blah <script>alert("XSS!")</script> blah'); | ||
expect($apple.get(0).children[0].data).to.equal('blah <script>alert("XSS!")</script> blah'); | ||
expect($apple[0].children[0].data).to.equal('blah <script>alert("XSS!")</script> blah'); | ||
expect($apple.text()).to.equal('blah <script>alert("XSS!")</script> blah'); | ||
@@ -292,0 +292,0 @@ |
@@ -40,3 +40,4 @@ var expect = require('expect.js'), | ||
it('(selector) : should return children matching selector', function() { | ||
expect($('ul', fruits).children('.orange').hasClass('orange')).to.be.ok(); | ||
var cls = $('ul', fruits).children('.orange')[0].attribs['class']; | ||
expect(cls).to.equal('orange'); | ||
}); | ||
@@ -55,3 +56,4 @@ | ||
it('() : should return next element', function() { | ||
expect($('.orange', fruits).next().hasClass('pear')).to.be.ok(); | ||
var cls = $('.orange', fruits).next()[0].attribs['class']; | ||
expect(cls).to.equal('pear'); | ||
}); | ||
@@ -66,3 +68,4 @@ | ||
it('() : should return previous element', function() { | ||
expect($('.orange', fruits).prev().hasClass('apple')).to.be.ok(); | ||
var cls = $('.orange', fruits).prev()[0].attribs['class']; | ||
expect(cls).to.equal('apple'); | ||
}); | ||
@@ -89,5 +92,7 @@ | ||
it('( (i, elem) -> ) : should loop selected returning fn with (i, elem)', function() { | ||
var items = []; | ||
var items = [], | ||
classes = ['apple', 'orange', 'pear']; | ||
$('li', fruits).each(function(idx, elem) { | ||
items[idx] = elem; | ||
expect(this[0].attribs['class']).to.equal(classes[idx]); | ||
}); | ||
@@ -104,7 +109,6 @@ expect(items[0].attribs['class']).to.equal('apple'); | ||
var classes = $('li', fruits).map(function(i, el) { | ||
expect(this).to.be(el); | ||
expect(this[0]).to.be(el); | ||
expect(el.name).to.be('li'); | ||
expect(i).to.be.a('number'); | ||
return $(this).attr('class'); | ||
return el.attribs['class']; | ||
}).join(', '); | ||
@@ -122,3 +126,3 @@ | ||
expect($elem.length).to.equal(1); | ||
expect($elem.html()).to.equal('foo'); | ||
expect($elem[0].children[0].data).to.equal('foo'); | ||
}); | ||
@@ -130,3 +134,3 @@ | ||
expect($first.length).to.equal(0); | ||
expect($first.html()).to.be(null); | ||
expect($first[0]).to.be(undefined); | ||
}); | ||
@@ -142,3 +146,3 @@ | ||
expect($elem.length).to.equal(1); | ||
expect($elem.html()).to.equal('baz'); | ||
expect($elem[0].children[0].data).to.equal('baz'); | ||
}); | ||
@@ -150,3 +154,3 @@ | ||
expect($last.length).to.equal(0); | ||
expect($last.html()).to.be(null); | ||
expect($last[0]).to.be(undefined); | ||
}); | ||
@@ -163,5 +167,5 @@ | ||
expect($first.length).to.equal(1); | ||
expect($first.html()).to.equal('bar'); | ||
expect($first[0].children[0].data).to.equal('bar'); | ||
expect($last.length).to.equal(1); | ||
expect($last.html()).to.equal('bar'); | ||
expect($last[0].children[0].data).to.equal('bar'); | ||
expect($first[0]).to.equal($last[0]); | ||
@@ -174,8 +178,13 @@ }); | ||
function getText(el) { | ||
if(!el.length) return ''; | ||
return el[0].children[0].data; | ||
} | ||
it('(i) : should return the element at the specified index', function() { | ||
expect($('li', fruits).eq(0).text()).to.equal('Apple'); | ||
expect($('li', fruits).eq(1).text()).to.equal('Orange'); | ||
expect($('li', fruits).eq(2).text()).to.equal('Pear'); | ||
expect($('li', fruits).eq(3).text()).to.equal(''); | ||
expect($('li', fruits).eq(-1).text()).to.equal('Pear'); | ||
expect(getText($('li', fruits).eq(0))).to.equal('Apple'); | ||
expect(getText($('li', fruits).eq(1))).to.equal('Orange'); | ||
expect(getText($('li', fruits).eq(2))).to.equal('Pear'); | ||
expect(getText($('li', fruits).eq(3))).to.equal(''); | ||
expect(getText($('li', fruits).eq(-1))).to.equal('Pear'); | ||
}); | ||
@@ -182,0 +191,0 @@ |
@@ -11,3 +11,3 @@ var expect = require('expect.js'), | ||
var $div = $('div', '<div><span>foo</span><span>bar</span></div>'); | ||
var span = $div.children().get(1); | ||
var span = $div.children()[1]; | ||
expect($(span).html()).to.equal('bar'); | ||
@@ -19,4 +19,3 @@ expect($.html(span)).to.equal('<span>bar</span>'); | ||
var $span = $('<span>foo</span>'); | ||
expect($.html($span.get(0))).to.equal('<span>foo</span>'); | ||
expect($.html($span.get())).to.equal('<span>foo</span>'); | ||
expect($.html($span[0])).to.equal('<span>foo</span>'); | ||
expect($.html($span)).to.equal('<span>foo</span>'); | ||
@@ -36,27 +35,4 @@ }); | ||
describe('.clone', function() { | ||
it('() : should return a copy', function() { | ||
var $src = $('<div><span>foo</span><span>bar</span><span>baz</span></div>').children(); | ||
var $elem = $src.clone(); | ||
expect($elem.length).to.equal(3); | ||
expect($elem.parent().length).to.equal(1); | ||
expect($elem.parent()[0].type).to.equal('root'); | ||
expect($elem.text()).to.equal($src.text()); | ||
$src.text('rofl'); | ||
expect($elem.text()).to.not.equal($src.text()); | ||
}); | ||
}); | ||
describe('.root', function() { | ||
it('() : should return a cheerio-wrapped root object', function() { | ||
var $html = $.load('<div><span>foo</span><span>bar</span></div>'); | ||
$html.root().append('<div id="test"></div>'); | ||
expect($html.html()).to.equal('<div><span>foo</span><span>bar</span></div><div id="test"></div>'); | ||
}); | ||
}); | ||
describe('.load', function() { | ||
@@ -81,3 +57,3 @@ | ||
// TODO: | ||
// TODO: | ||
// it('(html) : should handle xml tag option', function() { | ||
@@ -91,2 +67,28 @@ // var $html = $.load('<body><script>oh hai</script></body>', { xmlMode : true }); | ||
describe('.clone', function() { | ||
it('() : should return a copy', function() { | ||
var $src = $('<div><span>foo</span><span>bar</span><span>baz</span></div>').children(); | ||
var $elem = $src.clone(); | ||
expect($elem.length).to.equal(3); | ||
expect($elem.parent().length).to.equal(1); | ||
expect($elem.parent()[0].type).to.equal('root'); | ||
expect($elem.text()).to.equal($src.text()); | ||
$src.text('rofl'); | ||
expect($elem.text()).to.not.equal($src.text()); | ||
}); | ||
}); | ||
describe('.root', function() { | ||
it('() : should return a cheerio-wrapped root object', function() { | ||
var $html = $.load('<div><span>foo</span><span>bar</span></div>'); | ||
$html.root().append('<div id="test"></div>'); | ||
expect($html.html()).to.equal('<div><span>foo</span><span>bar</span></div><div id="test"></div>'); | ||
}); | ||
}); | ||
}); |
@@ -6,3 +6,2 @@ var expect = require('expect.js'), | ||
// HTML | ||
@@ -180,3 +179,2 @@ var script = '<script src="script.js" type="text/javascript"></script>', | ||
var $elem = $('Eastern States Cup #8-fin <br>Downhill '); | ||
expect($elem).to.be.an(Array); | ||
expect($elem).to.have.length(0); // [] | ||
@@ -183,0 +181,0 @@ }); |
@@ -8,1 +8,8 @@ exports.fruits = [ | ||
].join(''); | ||
exports.vegetables = [ | ||
'<ul id="vegetables">', | ||
'<li>Carrot</li>', | ||
'<li>Sweetcorn</li>', | ||
'</ul>' | ||
].join(''); |
var expect = require('expect.js'), | ||
parse = require('../').parse; | ||
parse = require('../lib/parse'); | ||
@@ -45,3 +45,3 @@ | ||
it('should parse basic empty tags: ' + basic, function() { | ||
var tag = parse['eval'](basic)[0]; | ||
var tag = parse.evaluate(basic)[0]; | ||
expect(tag.type).to.equal('tag'); | ||
@@ -53,3 +53,3 @@ expect(tag.name).to.equal('html'); | ||
it('should handle sibling tags: ' + siblings, function() { | ||
var dom = parse['eval'](siblings), | ||
var dom = parse.evaluate(siblings), | ||
h2 = dom[0], | ||
@@ -64,3 +64,3 @@ p = dom[1]; | ||
it('should handle single tags: ' + single, function() { | ||
var tag = parse['eval'](single)[0]; | ||
var tag = parse.evaluate(single)[0]; | ||
expect(tag.type).to.equal('tag'); | ||
@@ -72,3 +72,3 @@ expect(tag.name).to.equal('br'); | ||
it('should handle malformatted single tags: ' + singleWrong, function() { | ||
var tag = parse['eval'](singleWrong)[0]; | ||
var tag = parse.evaluate(singleWrong)[0]; | ||
expect(tag.type).to.equal('tag'); | ||
@@ -80,3 +80,3 @@ expect(tag.name).to.equal('br'); | ||
it('should handle tags with children: ' + children, function() { | ||
var tag = parse['eval'](children)[0]; | ||
var tag = parse.evaluate(children)[0]; | ||
expect(tag.type).to.equal('tag'); | ||
@@ -89,3 +89,3 @@ expect(tag.name).to.equal('html'); | ||
it('should handle tags with children: ' + li, function() { | ||
var tag = parse['eval'](li)[0]; | ||
var tag = parse.evaluate(li)[0]; | ||
expect(tag.children).to.have.length(1); | ||
@@ -96,3 +96,3 @@ expect(tag.children[0].data).to.equal('Durian'); | ||
it('should handle tags with attributes: ' + attributes, function() { | ||
var attrs = parse['eval'](attributes)[0].attribs; | ||
var attrs = parse.evaluate(attributes)[0].attribs; | ||
expect(attrs).to.be.ok(); | ||
@@ -104,3 +104,3 @@ expect(attrs.src).to.equal('hello.png'); | ||
it('should handle value-less attributes: ' + noValueAttribute, function() { | ||
var attrs = parse['eval'](noValueAttribute)[0].attribs; | ||
var attrs = parse.evaluate(noValueAttribute)[0].attribs; | ||
expect(attrs).to.be.ok(); | ||
@@ -111,3 +111,3 @@ expect(attrs.disabled).to.equal(''); | ||
it('should handle comments: ' + comment, function() { | ||
var elem = parse['eval'](comment)[0]; | ||
var elem = parse.evaluate(comment)[0]; | ||
expect(elem.type).to.equal('comment'); | ||
@@ -118,3 +118,3 @@ expect(elem.data).to.equal(' sexy '); | ||
it('should handle conditional comments: ' + conditional, function() { | ||
var elem = parse['eval'](conditional)[0]; | ||
var elem = parse.evaluate(conditional)[0]; | ||
expect(elem.type).to.equal('comment'); | ||
@@ -125,3 +125,3 @@ expect(elem.data).to.equal(conditional.replace('<!--', '').replace('-->', '')); | ||
it('should handle text: ' + text, function() { | ||
var text_ = parse['eval'](text)[0]; | ||
var text_ = parse.evaluate(text)[0]; | ||
expect(text_.type).to.equal('text'); | ||
@@ -132,3 +132,3 @@ expect(text_.data).to.equal('lorem ipsum'); | ||
it('should handle script tags: ' + script, function() { | ||
var script_ = parse['eval'](script)[0]; | ||
var script_ = parse.evaluate(script)[0]; | ||
expect(script_.type).to.equal('script'); | ||
@@ -143,3 +143,3 @@ expect(script_.name).to.equal('script'); | ||
it('should handle style tags: ' + style, function() { | ||
var style_ = parse['eval'](style)[0]; | ||
var style_ = parse.evaluate(style)[0]; | ||
expect(style_.type).to.equal('style'); | ||
@@ -154,3 +154,3 @@ expect(style_.name).to.equal('style'); | ||
it('should handle directives: ' + directive, function() { | ||
var elem = parse['eval'](directive)[0]; | ||
var elem = parse.evaluate(directive)[0]; | ||
expect(elem.type).to.equal('directive'); | ||
@@ -166,3 +166,3 @@ expect(elem.data).to.equal('!doctype html'); | ||
var create = function(html) { | ||
var dom = parse['eval'](html); | ||
var dom = parse.evaluate(html); | ||
return parse.connect(dom); | ||
@@ -169,0 +169,0 @@ }; |
var expect = require('expect.js'), | ||
cheerio = require('../'), | ||
parse = cheerio.parse, | ||
render = cheerio.render; | ||
parse = require('../lib/parse'), | ||
render = require('../lib/render'); | ||
@@ -12,3 +11,2 @@ var html = function(str, options) { | ||
describe('render', function() { | ||
@@ -20,3 +18,3 @@ | ||
var str = '<br />'; | ||
expect(html(str)).to.equal('<br/>'); | ||
expect(html(str)).to.equal('<br>'); | ||
done(); | ||
@@ -27,3 +25,3 @@ }); | ||
var str = '<input checked/>'; | ||
expect(html(str)).to.equal('<input checked/>'); | ||
expect(html(str)).to.equal('<input checked>'); | ||
done(); | ||
@@ -34,3 +32,3 @@ }); | ||
var str = '<input name="name"/>'; | ||
expect(html(str)).to.equal('<input name="name"/>'); | ||
expect(html(str)).to.equal('<input name="name">'); | ||
done(); | ||
@@ -37,0 +35,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
619
0
88539
1835
1