Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cheerio

Package Overview
Dependencies
Maintainers
3
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cheerio - npm Package Compare versions

Comparing version 0.17.0 to 0.18.0

coverage/coverage.json

70

History.md
0.18.0 / 2014-11-06
==================
* bump htmlparser2 dependency to ~3.8.1 (Chris Rebert)
* Correct unit test titles (Mike Pennisi)
* Correct behavior of `after` and `before` (Mike Pennisi)
* implement jQuery's .has() (Chris Rebert)
* Update repository url (haqii)
* attr() should return undefined or name for booleans (Raoul Millais)
* Update Readme.md (Ryan Breen)
* Implement `Cheerio#not` (Mike Pennisi)
* Clone nodes according to original parsing options (Mike Pennisi)
* fix lint error (David Chambers)
* Add explicit tests for DOM level 1 API (Mike Pennisi)
* Expose DOM level 1 API for Node-like objects (Mike Pennisi)
* Correct error in documentation (Mike Pennisi)
* Return a fully-qualified Function from `$.load` (Mike Pennisi)
* Update tests to avoid duck typing (Mike Pennisi)
* Alter "loaded" functions to produce true instances (Mike Pennisi)
* Organize tests for `cheerio.load` (Mike Pennisi)
* Complete `$.prototype.find` (Mike Pennisi)
* Use JSHint's `extends` option (Mike Pennisi)
* Remove aliases for exported methods (Mike Pennisi)
* Disallow unused variables (Mike Pennisi)
* Remove unused internal variables (Mike Pennisi)
* Remove unused variables from unit tests (Mike Pennisi)
* Remove unused API method references (Mike Pennisi)
* Move tests for `contains` method (Mike Pennisi)
* xyz@0.4.0 (David Chambers)
* Created a wiki for companies using cheerio in production (Matthew Mueller)
* Implement `$.prototype.index` (Mike Pennisi)
* Implement `$.prototype.addBack` (Mike Pennisi)
* Added double quotes to radio attribute name to account for characters such as brackets (akant10)
* Update History.md (Gabriel Falkenberg)
* add 0.17.0 changelog (David Chambers)
* exit prepublish script if tag not found (David Chambers)
* alphabetize devDependencies (fb55)
* ignore coverage dir (fb55)
* submit coverage to coveralls (fb55)
* replace jscoverage with istanbul (fb55)
0.17.0 / 2014-06-10
==================
* Fix bug in internal `uniqueSplice` function (Mike Pennisi)
* accept buffer argument to cheerio.load (David Chambers)
* Respect options on the element level (Alex Indigo)
* Change state definition to more readable (Artem Burtsev)
* added test (0xBADC0FFEE)
* add class only if doesn't exist (Artem Burtsev)
* Made it less insane. (Alex Indigo)
* Implement `Cheerio#add` (Mike Pennisi)
* Use "loaded" instance of Cheerio in unit tests (Mike Pennisi)
* Be more strict with object check. (Alex Indigo)
* Added options argument to .html() static method. (Alex Indigo)
* Fixed encoding mishaps. Adjusted tests. (Alex Indigo)
* use dom-serializer module (fb55)
* don't test on 0.8, don't ignore 0.11 (Felix Böhm)
* parse: rm unused variables (coderaiser)
* cheerio: rm unused variable (coderaiser)
* Fixed test (Avi Kohn)
* Added test (Avi Kohn)
* Changed == to === (Avi Kohn)
* Fixed a bug in removing type="hidden" attr (Avi Kohn)
* sorted (Alexey Raspopov)
* add `muted` attr to booleanAttributes (Alexey Raspopov)
* fixed context of `this` in .html (Felix Böhm)
* append new elements for each element in selection (fb55)
0.16.0 / 2014-05-08

@@ -241,3 +305,3 @@ ==================

* updated docs to remove reference to size method (@ironchefpython)
* removed tidy from cheerio
* removed HTML tidy/pretty print from cheerio

@@ -315,3 +379,3 @@ 0.10.1 / 2012-10-04

* Fixed spacing between attributes and their values
* Added HTML pretty print
* Added HTML tidy/pretty print
* Exposed node-htmlparser2 parsing options

@@ -318,0 +382,0 @@ * Revert .replaceWith(...) to be consistent with jQuery

39

lib/api/attributes.js

@@ -39,3 +39,3 @@ var _ = require('lodash'),

// Get the (decoded) attribute
return elem.attribs[name];
return rboolean.test(name) ? name : elem.attribs[name];
}

@@ -53,3 +53,3 @@ };

var attr = exports.attr = function(name, value) {
exports.attr = function(name, value) {
// Set the value (with attr map support)

@@ -128,3 +128,3 @@ if (typeof name === 'object' || value !== undefined) {

var data = exports.data = function(name, value) {
exports.data = function(name, value) {
var elem = this[0];

@@ -160,3 +160,3 @@

var val = exports.val = function(value) {
exports.val = function(value) {
var querying = arguments.length === 0,

@@ -173,3 +173,3 @@ element = this[0];

case 'radio':
var queryString = 'input[type=radio][name=' + this.attr('name') + ']:checked';
var queryString = 'input[type=radio][name="' + this.attr('name') + '"]:checked';
var parentEl, root;

@@ -238,10 +238,7 @@

if (name === elem.attribs[name] && rboolean.test(elem.attribs[name]))
elem.attribs[name] = false;
else
delete elem.attribs[name];
delete elem.attribs[name];
};
var removeAttr = exports.removeAttr = function(name) {
exports.removeAttr = function(name) {
domEach(this, function(i, elem) {

@@ -254,3 +251,3 @@ removeAttribute(elem, name);

var hasClass = exports.hasClass = function(className) {
exports.hasClass = function(className) {
return _.any(this, function(elem) {

@@ -275,3 +272,3 @@ var attrs = elem.attribs,

var addClass = exports.addClass = function(value) {
exports.addClass = function(value) {
// Support functions

@@ -281,3 +278,3 @@ if (typeof value === 'function') {

var className = el.attribs['class'] || '';
addClass.call([el], value.call(el, i, className));
exports.addClass.call([el], value.call(el, i, className));
});

@@ -326,3 +323,3 @@ }

var removeClass = exports.removeClass = function(value) {
exports.removeClass = function(value) {
var classes,

@@ -335,3 +332,5 @@ numClasses,

return domEach(this, function(i, el) {
removeClass.call([el], value.call(el, i, el.attribs['class'] || ''));
exports.removeClass.call(
[el], value.call(el, i, el.attribs['class'] || '')
);
});

@@ -374,7 +373,11 @@ }

var toggleClass = exports.toggleClass = function(value, stateVal) {
exports.toggleClass = function(value, stateVal) {
// Support functions
if (typeof value === 'function') {
return domEach(this, function(i, el) {
toggleClass.call([el], value.call(el, i, el.attribs['class'] || '', stateVal), stateVal);
exports.toggleClass.call(
[el],
value.call(el, i, el.attribs['class'] || '', stateVal),
stateVal
);
});

@@ -419,3 +422,3 @@ }

var is = exports.is = function (selector) {
exports.is = function (selector) {
if (selector) {

@@ -422,0 +425,0 @@ return this.filter(selector).length > 0;

@@ -8,3 +8,2 @@ var _ = require('lodash'),

domEach = utils.domEach,
encode = utils.encode,
slice = Array.prototype.slice;

@@ -103,11 +102,11 @@

var append = exports.append = _insert(function(dom, children, parent) {
exports.append = _insert(function(dom, children, parent) {
uniqueSplice(children, children.length, 0, dom, parent);
});
var prepend = exports.prepend = _insert(function(dom, children, parent) {
exports.prepend = _insert(function(dom, children, parent) {
uniqueSplice(children, 0, 0, dom, parent);
});
var after = exports.after = function() {
exports.after = function() {
var elems = slice.call(arguments),

@@ -130,3 +129,3 @@ dom = this._makeDomArray(elems),

if (typeof elems[0] === 'function') {
dom = self._makeDomArray(elems[0].call(el, i));
dom = self._makeDomArray(elems[0].call(el, i, $.html(el.children)));
}

@@ -141,3 +140,3 @@

var before = exports.before = function() {
exports.before = function() {
var elems = slice.call(arguments),

@@ -160,3 +159,3 @@ dom = this._makeDomArray(elems),

if (typeof elems[0] === 'function') {
dom = self._makeDomArray(elems[0].call(el, i));
dom = self._makeDomArray(elems[0].call(el, i, $.html(el.children)));
}

@@ -174,3 +173,3 @@

*/
var remove = exports.remove = function(selector) {
exports.remove = function(selector) {
var elems = this;

@@ -207,3 +206,3 @@

var replaceWith = exports.replaceWith = function(content) {
exports.replaceWith = function(content) {
var self = this;

@@ -235,3 +234,3 @@

var empty = exports.empty = function() {
exports.empty = function() {
domEach(this, function(i, el) {

@@ -250,3 +249,3 @@ _.each(el.children, function(el) {

*/
var html = exports.html = function(str) {
exports.html = function(str) {
if (str === undefined) {

@@ -272,7 +271,7 @@ if (!this[0] || !this[0].children) return null;

var toString = exports.toString = function() {
exports.toString = function() {
return $.html(this);
};
var text = exports.text = function(str) {
exports.text = function(str) {
// If `str` is undefined, act as a "getter"

@@ -285,3 +284,3 @@ if (str === undefined) {

var $el = [el];
return text.call($el, str.call(el, i, $.text($el)));
return exports.text.call($el, str.call(el, i, $.text($el)));
});

@@ -311,6 +310,6 @@ }

var clone = exports.clone = function() {
exports.clone = function() {
// Turn it into HTML, then recreate it,
// Seems to be the easiest way to reconnect everything correctly
return this._make($.html(this));
return this._make($.html(this, this.options));
};

@@ -8,8 +8,27 @@ var _ = require('lodash'),

var find = exports.find = function(selector) {
exports.find = function(selectorOrHaystack) {
var elems = _.reduce(this, function(memo, elem) {
return memo.concat(_.filter(elem.children, isTag));
}, []);
var contains = this.constructor.contains;
var haystack;
return this._make(select(selector, elems, this.options));
if (selectorOrHaystack && typeof selectorOrHaystack !== 'string') {
if (selectorOrHaystack.cheerio) {
haystack = selectorOrHaystack.get();
} else {
haystack = [selectorOrHaystack];
}
return this._make(haystack.filter(function(elem) {
var idx, len;
for (idx = 0, len = this.length; idx < len; ++idx) {
if (contains(this[idx], elem)) {
return true;
}
}
}, this));
}
return this._make(select(selectorOrHaystack, elems, this.options));
};

@@ -19,5 +38,4 @@

// optionally filtered by a selector.
var parent = exports.parent = function(selector) {
exports.parent = function(selector) {
var set = [];
var $set;

@@ -32,3 +50,3 @@ domEach(this, function(idx, elem) {

if (arguments.length) {
set = filter.call(set, selector, this);
set = exports.filter.call(set, selector, this);
}

@@ -39,3 +57,3 @@

var parents = exports.parents = function(selector) {
exports.parents = function(selector) {
var parentNodes = [];

@@ -59,3 +77,3 @@

var parentsUntil = exports.parentsUntil = function(selector, filter) {
exports.parentsUntil = function(selector, filter) {
var parentNodes = [], untilNode, untilNodes;

@@ -93,3 +111,3 @@

// DOM tree.
var closest = exports.closest = function(selector) {
exports.closest = function(selector) {
var set = [];

@@ -113,3 +131,3 @@

var next = exports.next = function(selector) {
exports.next = function(selector) {
if (!this[0]) { return this; }

@@ -127,6 +145,8 @@ var elems = [];

return selector ? filter.call(elems, selector, this) : this._make(elems);
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
var nextAll = exports.nextAll = function(selector) {
exports.nextAll = function(selector) {
if (!this[0]) { return this; }

@@ -143,6 +163,8 @@ var elems = [];

return selector ? filter.call(elems, selector, this) : this._make(elems);
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
var nextUntil = exports.nextUntil = function(selector, filterSelector) {
exports.nextUntil = function(selector, filterSelector) {
if (!this[0]) { return this; }

@@ -174,7 +196,7 @@ var elems = [], untilNode, untilNodes;

return filterSelector ?
filter.call(elems, filterSelector, this) :
exports.filter.call(elems, filterSelector, this) :
this._make(elems);
};
var prev = exports.prev = function(selector) {
exports.prev = function(selector) {
if (!this[0]) { return this; }

@@ -192,6 +214,8 @@ var elems = [];

return selector ? filter.call(elems, selector, this) : this._make(elems);
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
var prevAll = exports.prevAll = function(selector) {
exports.prevAll = function(selector) {
if (!this[0]) { return this; }

@@ -208,6 +232,8 @@ var elems = [];

return selector ? filter.call(elems, selector, this) : this._make(elems);
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
var prevUntil = exports.prevUntil = function(selector, filterSelector) {
exports.prevUntil = function(selector, filterSelector) {
if (!this[0]) { return this; }

@@ -239,7 +265,7 @@ var elems = [], untilNode, untilNodes;

return filterSelector ?
filter.call(elems, filterSelector, this) :
exports.filter.call(elems, filterSelector, this) :
this._make(elems);
};
var siblings = exports.siblings = function(selector) {
exports.siblings = function(selector) {
var parent = this.parent();

@@ -254,3 +280,3 @@

if (selector !== undefined) {
return filter.call(elems, selector, this);
return exports.filter.call(elems, selector, this);
} else {

@@ -261,3 +287,3 @@ return this._make(elems);

var children = exports.children = function(selector) {
exports.children = function(selector) {

@@ -271,6 +297,6 @@ var elems = _.reduce(this, function(memo, elem) {

return filter.call(elems, selector, this);
return exports.filter.call(elems, selector, this);
};
var contents = exports.contents = function() {
exports.contents = function() {
return this._make(_.reduce(this, function(all, elem) {

@@ -282,3 +308,3 @@ all.push.apply(all, elem.children);

var each = exports.each = function(fn) {
exports.each = function(fn) {
var i = 0, len = this.length;

@@ -289,3 +315,3 @@ while (i < len && fn.call(this[i], i, this[i]) !== false) ++i;

var map = exports.map = function(fn) {
exports.map = function(fn) {
return this._make(_.reduce(this, function(memo, el, i) {

@@ -297,30 +323,40 @@ var val = fn.call(el, i, el);

var filter = exports.filter = function(match, container) {
container = container || this;
var makeFilterMethod = function(filterFn) {
return function(match, container) {
var testFn;
container = container || this;
var make = _.bind(container._make, container);
var filterFn;
if (typeof match === 'string') {
testFn = select.compile(match, container.options);
} else if (typeof match === 'function') {
testFn = function(el, i) {
return match.call(el, i, el);
};
} else if (match.cheerio) {
testFn = match.is.bind(match);
} else {
testFn = function(el) {
return match === el;
};
}
if (typeof match === 'string') {
filterFn = select.compile(match, container.options);
} else if (typeof match === 'function') {
filterFn = function(el, i) {
return match.call(el, i, el);
};
} else if (match.cheerio) {
filterFn = match.is.bind(match);
} else {
filterFn = function(el) {
return match === el;
};
}
return container._make(filterFn(this, testFn));
};
};
return make(_.filter(this, filterFn));
exports.filter = makeFilterMethod(_.filter);
exports.not = makeFilterMethod(_.reject);
exports.has = function(selectorOrHaystack) {
var that = this;
return exports.filter.call(this, function() {
return that._make(this).find(selectorOrHaystack).length > 0;
});
};
var first = exports.first = function() {
exports.first = function() {
return this.length > 1 ? this._make(this[0]) : this;
};
var last = exports.last = function() {
exports.last = function() {
return this.length > 1 ? this._make(this[this.length - 1]) : this;

@@ -330,3 +366,3 @@ };

// Reduce the set of matched elements to the one at the specified index.
var eq = exports.eq = function(i) {
exports.eq = function(i) {
i = +i;

@@ -342,3 +378,3 @@

// Retrieve the DOM elements matched by the jQuery object.
var get = exports.get = function(i) {
exports.get = function(i) {
if (i == null) {

@@ -351,3 +387,21 @@ return Array.prototype.slice.call(this);

var slice = exports.slice = function() {
// Search for a given element from among the matched elements.
exports.index = function(selectorOrNeedle) {
var $haystack, needle;
if (arguments.length === 0) {
$haystack = this.parent().children();
needle = this[0];
} else if (typeof selectorOrNeedle === 'string') {
$haystack = this._make(selectorOrNeedle);
needle = this[0];
} else {
$haystack = this;
needle = selectorOrNeedle.cheerio ? selectorOrNeedle[0] : selectorOrNeedle;
}
return $haystack.get().indexOf(needle);
};
exports.slice = function() {
return this._make([].slice.apply(this, arguments));

@@ -359,3 +413,3 @@ };

while (elem && elems.length < limit) {
if (!selector || filter.call([elem], selector, self).length) {
if (!selector || exports.filter.call([elem], selector, self).length) {
elems.push(elem);

@@ -370,7 +424,7 @@ }

// set of matched elements to its previous state.
var end = exports.end = function() {
exports.end = function() {
return this.prevObject || this._make([]);
};
var add = exports.add = function(other, context) {
exports.add = function(other, context) {
var selection = this._make(other, context);

@@ -386,1 +440,9 @@ var contents = uniqueSort(selection.get().concat(this.get()));

};
// Add the previous set of elements on the stack to the current set, optionally
// filtered by a selector.
exports.addBack = function(selector) {
return this.add(
arguments.length ? this.prevObject.filter(selector) : this.prevObject
);
};

@@ -5,4 +5,3 @@ /*

var path = require('path'),
parse = require('./parse'),
var parse = require('./parse'),
_ = require('lodash');

@@ -107,2 +106,3 @@

Cheerio.prototype.options = {
withDomLvl1: true,
normalizeWhitespace: false,

@@ -109,0 +109,0 @@ xmlMode: false,

/*
Module Dependencies
*/
var htmlparser = require('htmlparser2'),
utils = require('./utils');
var htmlparser = require('htmlparser2');

@@ -11,16 +10,10 @@ /*

exports = module.exports = function(content, options) {
var dom = evaluate(content, options);
var dom = exports.evaluate(content, options),
// Generic root element
root = exports.evaluate('<root></root>', options)[0];
// Generic root element
var root = {
type: 'root',
name: 'root',
parent: null,
prev: null,
next: null,
children: []
};
root.type = 'root';
// Update the dom using the root
update(dom, root);
exports.update(dom, root);

@@ -30,3 +23,3 @@ return root;

var evaluate = exports.evaluate = function(content, options) {
exports.evaluate = function(content, options) {
// options = options || $.fn.options;

@@ -48,3 +41,3 @@

*/
var update = exports.update = function(arr, parent) {
exports.update = function(arr, parent) {
// normalize

@@ -51,0 +44,0 @@ if (!Array.isArray(arr)) arr = [arr];

@@ -14,3 +14,3 @@ /**

var load = exports.load = function(content, options) {
exports.load = function(content, options) {
var Cheerio = require('./cheerio');

@@ -24,7 +24,11 @@

opts = _.defaults(opts || {}, options);
return new Cheerio(selector, context, r || root, opts);
return Cheerio.call(this, selector, context, r || root, opts);
};
// Ensure that selections created by the "loaded" `initialize` function are
// true Cheerio instances.
initialize.prototype = Cheerio.prototype;
// Add in the static methods
initialize.__proto__ = exports;
_.merge(initialize, exports);

@@ -43,3 +47,3 @@ // Add in the root

var html = exports.html = function(dom, options) {
exports.html = function(dom, options) {
var Cheerio = require('./cheerio');

@@ -75,3 +79,3 @@

var xml = exports.xml = function(dom) {
exports.xml = function(dom) {
if (dom) {

@@ -91,3 +95,3 @@ dom = (typeof dom === 'string') ? select(dom, this._root, this.options) : dom;

var text = exports.text = function(elems) {
exports.text = function(elems) {
if (!elems) return '';

@@ -103,3 +107,3 @@

else if (elem.children && elem.type !== 'comment') {
ret += text(elem.children);
ret += exports.text(elem.children);
}

@@ -116,3 +120,3 @@ }

*/
var parseHTML = exports.parseHTML = function(data, context, keepScripts) {
exports.parseHTML = function(data, context, keepScripts) {
var parsed;

@@ -139,3 +143,3 @@

*/
var root = exports.root = function() {
exports.root = function() {
return this(this._root);

@@ -147,3 +151,3 @@ };

*/
var contains = exports.contains = function(container, contained) {
exports.contains = function(container, contained) {

@@ -150,0 +154,0 @@ // According to the jQuery API, an element does not "contain" itself

{
"name": "cheerio",
"version": "0.17.0",
"version": "0.18.0",
"description": "Tiny, fast, and elegant implementation of core jQuery designed specifically for the server",

@@ -16,3 +16,3 @@ "author": "Matt Mueller <mattmuelle@gmail.com> (mat.io)",

"type": "git",
"url": "git://github.com/MatthewMueller/cheerio.git"
"url": "git://github.com/cheeriojs/cheerio.git"
},

@@ -26,3 +26,3 @@ "main": "./index.js",

"entities": "~1.1.1",
"htmlparser2": "~3.7.2",
"htmlparser2": "~3.8.1",
"dom-serializer": "~0.0.0",

@@ -33,7 +33,9 @@ "lodash": "~2.4.1"

"benchmark": "~1.0.0",
"coveralls": "~2.10",
"expect.js": "~0.3.1",
"istanbul": "~0.2",
"jsdom": "~0.8.9",
"jshint": "~2.3.0",
"jshint": "~2.5.1",
"mocha": "*",
"xyz": "~0.3.0"
"xyz": "~0.4.0"
},

@@ -40,0 +42,0 @@ "scripts": {

@@ -245,3 +245,5 @@ # cheerio [![Build Status](https://secure.travis-ci.org/cheeriojs/cheerio.svg?branch=master)](http://travis-ci.org/cheeriojs/cheerio)

#### .find(selector)
Get a set of descendants filtered by `selector` of each element in the current set of matched elements.
#### .find(selection)
#### .find(node)
Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.

@@ -251,2 +253,4 @@ ```js

//=> 3
$('#fruits').find($('.apple')).length
//=> 1
```

@@ -402,5 +406,5 @@

// this === el
return $('<div>').text($(this).text());
}).html();
//=> <div>apple</div><div>orange</div><div>pear</div>
return $(this).text();
}).get().join(' ');
//=> "apple orange pear"
```

@@ -429,2 +433,41 @@

#### .not( selector ) <br /> .not( selection ) <br /> .not( element ) <br /> .not( function(index, elem) )
Remove elements from the set of matched elements. Given a jQuery object that represents a set of DOM elements, the `.not()` method constructs a new jQuery object from a subset of the matching elements. The supplied selector is tested against each element; the elements that don't match the selector will be included in the result. The `.not()` method can take a function as its argument in the same way that `.filter()` does. Elements for which the function returns true are excluded from the filtered set; all other elements are included.
Selector:
```js
$('li').not('.apple').length;
//=> 2
```
Function:
```js
$('li').filter(function(i, el) {
// this === el
return $(this).attr('class') === 'orange';
}).length;
//=> 2
```
#### .has( selector ) <br /> .has( element )
Filters the set of matched elements to only those which have the given DOM element as a descendant or which have a descendant that matches the given selector. Equivalent to `.filter(':has(selector)')`.
Selector:
```js
$('ul').has('.pear').attr('id');
//=> fruits
```
Element:
```js
$('ul').has($('.pear')[0]).attr('id');
//=> fruits
```
#### .first()

@@ -462,3 +505,3 @@ Will select the first element of a cheerio object

```js
$('li').get(0).name
$('li').get(0).tagName
//=> li

@@ -474,2 +517,17 @@ ```

#### .index()
#### .index( selector )
#### .index( nodeOrSelection )
Search for a given element from among the matched elements.
```
$('.pear').index()
//=> 2
$('.orange').index('li')
//=> 1
$('.apple').index($('#fruit, li'))
//=> 1
```
#### .end()

@@ -495,2 +553,11 @@ End the most recent filtering operation in the current chain and return the set of matched elements to its previous state.

#### .addBack( [filter] )
Add the previous set of elements on the stack to the current set, optionally filtered by a selector.
```js
$('li').eq(0).addBack('.orange').length
//=> 2
```
### Manipulation

@@ -582,3 +649,3 @@ Methods for modifying the DOM structure.

#### .empty()
Empties an element, removing all it's children.
Empties an element, removing all its children.

@@ -679,2 +746,15 @@ ```js

### The "DOM Node" object
Cheerio collections are made up of objects that bear some resemblence to [browser-based DOM nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node). You can expect them to define the following properties:
- `tagName`
- `parentNode`
- `previousSibling`
- `nextSibling`
- `nodeValue`
- `firstChild`
- `childNodes`
- `lastChild`
## Screencasts

@@ -766,2 +846,6 @@

## Cheerio in the real world
Are you using cheerio in production? Add it to the [wiki](https://github.com/cheeriojs/cheerio/wiki/Cheerio-in-Production)!
## Special Thanks

@@ -768,0 +852,0 @@

@@ -35,6 +35,11 @@ var expect = require('expect.js');

it('(valid key) : valid attr should get name when boolean', function() {
var attr = $('<input name=email autofocus>').attr('autofocus');
expect(attr).to.equal('autofocus');
});
it('(key, value) : should set attr', function() {
var $pear = $('.pear').attr('id', 'pear');
expect($('#pear')).to.have.length(1);
expect($pear.cheerio).to.not.be(undefined);
expect($pear).to.be.a($);
});

@@ -100,3 +105,3 @@

$apple.removeAttr('autofocus');
expect($apple.attr('autofocus')).to.equal(false);
expect($apple.attr('autofocus')).to.be(undefined);
});

@@ -326,2 +331,6 @@

});
it('.val(value): on radio with special characters should set value', function() {
var element = $('input[name="radio[brackets]"]').val('off');
expect(element.val()).to.equal('off');
});
it('.val(values): on multiple select should set multiple values', function() {

@@ -343,4 +352,4 @@ var element = $('select#multi').val(['1', '3', '4']);

it('should return cheerio object', function() {
var obj = $('ul').removeAttr('id').cheerio;
expect(obj).to.be.ok();
var obj = $('ul').removeAttr('id');
expect(obj).to.be.a($);
});

@@ -422,3 +431,3 @@

$fruits.addClass(function(idx, currentClass) {
$fruits.addClass(function(idx) {
args.push(toArray(arguments));

@@ -468,3 +477,3 @@ thisVals.push(this);

var $vegetables = cheerio(vegetables);
var thrown = null;
expect(function() {

@@ -521,3 +530,3 @@ $('li', $vegetables).removeClass('vegetable');

$fruits.removeClass(function(idx, currentClass) {
$fruits.removeClass(function(idx) {
args.push(toArray(arguments));

@@ -604,3 +613,3 @@ thisVals.push(this);

$('li').toggleClass(function(index, className, switchVal) {
$('li').toggleClass(function() {
return $(this).parent().is('#fruits') ? 'fruit' : 'vegetable';

@@ -657,3 +666,3 @@ });

var result = $('li').is(function() {
return this.name === 'li' && $(this).hasClass('pear');
return this.tagName === 'li' && $(this).hasClass('pear');
});

@@ -665,3 +674,3 @@ expect(result).to.be(true);

var result = $('li').last().is(function() {
return this.name === 'ul';
return this.tagName === 'ul';
});

@@ -668,0 +677,0 @@ expect(result).to.be(false);

@@ -18,3 +18,3 @@ var expect = require('expect.js'),

it('() : should do nothing', function() {
expect($('#fruits').append()[0].name).to.equal('ul');
expect($('#fruits').append()[0].tagName).to.equal('ul');
});

@@ -98,3 +98,3 @@

it('(fn) : should invoke the callback with the correct argument and context', function() {
it('(fn) : should invoke the callback with the correct arguments and context', function() {
$fruits = $fruits.children();

@@ -188,3 +188,3 @@ var args = [];

expect($plum[0].root).to.not.be.ok();
expect(root.children).to.not.contain($plum[0]);
expect(root.childNodes).to.not.contain($plum[0]);
});

@@ -196,3 +196,3 @@ });

it('() : should do nothing', function() {
expect($('#fruits').prepend()[0].name).to.equal('ul');
expect($('#fruits').prepend()[0].tagName).to.equal('ul');
});

@@ -260,3 +260,3 @@

it('(fn) : should invoke the callback with the correct argument and context', function() {
it('(fn) : should invoke the callback with the correct arguments and context', function() {
var args = [];

@@ -342,3 +342,3 @@ var thisValues = [];

expect($plum[0].root).to.not.be.ok();
expect(root.children).to.not.contain($plum[0]);
expect(root.childNodes).to.not.contain($plum[0]);
});

@@ -350,3 +350,3 @@ });

it('() : should do nothing', function() {
expect($('#fruits').after()[0].name).to.equal('ul');
expect($('#fruits').after()[0].tagName).to.equal('ul');
});

@@ -414,3 +414,3 @@

it('(fn) : should invoke the callback with the correct argument and context', function() {
it('(fn) : should invoke the callback with the correct arguments and context', function() {
var args = [];

@@ -425,3 +425,3 @@ var thisValues = [];

expect(args).to.eql([[0], [1], [2]]);
expect(args).to.eql([[0, 'Apple'], [1, 'Orange'], [2, 'Pear']]);
expect(thisValues).to.eql([

@@ -477,3 +477,3 @@ $fruits[0],

expect($plum[0].root).to.not.be.ok();
expect(root.children).to.not.contain($plum[0]);
expect(root.childNodes).to.not.contain($plum[0]);
});

@@ -485,3 +485,3 @@ });

it('() : should do nothing', function() {
expect($('#fruits').before()[0].name).to.equal('ul');
expect($('#fruits').before()[0].tagName).to.equal('ul');
});

@@ -549,3 +549,3 @@

it('(fn) : should invoke the callback with the correct argument and context', function() {
it('(fn) : should invoke the callback with the correct arguments and context', function() {
var args = [];

@@ -560,3 +560,3 @@ var thisValues = [];

expect(args).to.eql([[0], [1], [2]]);
expect(args).to.eql([[0, 'Apple'], [1, 'Orange'], [2, 'Pear']]);
expect(thisValues).to.eql([

@@ -612,3 +612,3 @@ $fruits[0],

expect($plum[0].root).to.not.be.ok();
expect(root.children).to.not.contain($plum[0]);
expect(root.childNodes).to.not.contain($plum[0]);
});

@@ -643,3 +643,3 @@ });

expect($plum[0].root).to.not.be.ok();
expect(root.children).to.not.contain($plum[0]);
expect(root.childNodes).to.not.contain($plum[0]);
});

@@ -671,4 +671,4 @@ });

var $replaced = $src.find('span').replaceWith($new[0]);
expect($new[0].parent).to.equal($src[0]);
expect($replaced[0].parent).to.equal(null);
expect($new[0].parentNode).to.equal($src[0]);
expect($replaced[0].parentNode).to.equal(null);
expect($.html($src)).to.equal('<h2>hi <ul></ul></h2>');

@@ -697,4 +697,4 @@ });

var $replaced = $src.find('span').replaceWith($new);
expect($new[0].parent).to.equal($src[0]);
expect($replaced[0].parent).to.equal(null);
expect($new[0].parentNode).to.equal($src[0]);
expect($replaced[0].parentNode).to.equal(null);
expect($.html($src)).to.equal('<h2>hi <div>here</div></h2>');

@@ -707,3 +707,3 @@ });

var $replaced = $src.find('span').replaceWith(newStr);
expect($replaced[0].parent).to.equal(null);
expect($replaced[0].parentNode).to.equal(null);
expect($.html($src)).to.equal('<h2>hi <div>here</div></h2>');

@@ -715,3 +715,3 @@ });

var $replaced = $src.find('br').replaceWith(' ');
expect($replaced[0].parent).to.equal(null);
expect($replaced[0].parentNode).to.equal(null);
expect($.html($src)).to.equal('<b>a b c d</b>');

@@ -774,3 +774,3 @@ });

expect($plum[0].root).to.not.be.ok();
expect(root.children).to.not.contain($plum[0]);
expect(root.childNodes).to.not.contain($plum[0]);
});

@@ -795,4 +795,4 @@ });

$fruits.append($('<div></div><div></div>'));
var $remove = $fruits.children().eq(0),
$keep = $fruits.children().eq(1);
var $remove = $fruits.children().eq(0);
$remove.replaceWith($children);

@@ -869,4 +869,4 @@ expect($fruits.children()).to.have.length(4);

var $remove = $fruits.children().eq(0),
$keep = $fruits.children().eq(1);
var $remove = $fruits.children().eq(0);
$remove.replaceWith($children);

@@ -904,3 +904,3 @@ expect($fruits.children()).to.have.length(4);

$('.apple').text('Granny Smith Apple');
expect($('.apple')[0].children[0].data).to.equal('Granny Smith Apple');
expect($('.apple')[0].childNodes[0].data).to.equal('Granny Smith Apple');
});

@@ -912,3 +912,3 @@

$('li').each(function(){
expect(this.children[0].parent).to.equal(this);
expect(this.childNodes[0].parent).to.equal(this);
tested++;

@@ -925,3 +925,3 @@ });

});
expect($('.apple')[0].children[0].data).to.equal('whatever mate');
expect($('.apple')[0].childNodes[0].data).to.equal('whatever mate');
});

@@ -962,3 +962,3 @@

$apple.text('blah <script>alert("XSS!")</script> blah');
expect($apple[0].children[0].data).to.equal('blah <script>alert("XSS!")</script> blah');
expect($apple[0].childNodes[0].data).to.equal('blah <script>alert("XSS!")</script> blah');
expect($apple.text()).to.equal('blah <script>alert("XSS!")</script> blah');

@@ -965,0 +965,0 @@

@@ -66,2 +66,44 @@ var expect = require('expect.js'),

describe('(cheerio object) :', function() {
it('returns only those nodes contained within the current selection', function() {
var $ = cheerio.load(food);
var $selection = $('#fruits').find($('li'));
expect($selection).to.have.length(3);
expect($selection[0]).to.be($('.apple')[0]);
expect($selection[1]).to.be($('.orange')[0]);
expect($selection[2]).to.be($('.pear')[0]);
});
it('returns only those nodes contained within any element in the current selection', function() {
var $ = cheerio.load(food);
var $selection = $('.apple, #vegetables').find($('li'));
expect($selection).to.have.length(2);
expect($selection[0]).to.be($('.carrot')[0]);
expect($selection[1]).to.be($('.sweetcorn')[0]);
});
});
describe('(node) :', function() {
it('returns node when contained within the current selection', function() {
var $ = cheerio.load(food);
var $selection = $('#fruits').find($('.apple')[0]);
expect($selection).to.have.length(1);
expect($selection[0]).to.be($('.apple')[0]);
});
it('returns node when contained within any element the current selection', function() {
var $ = cheerio.load(food);
var $selection = $('#fruits, #vegetables').find($('.carrot')[0]);
expect($selection).to.have.length(1);
expect($selection[0]).to.be($('.carrot')[0]);
});
it('does not return node that is not contained within the current selection', function() {
var $ = cheerio.load(food);
var $selection = $('#fruits').find($('.carrot')[0]);
expect($selection).to.have.length(0);
});
});
});

@@ -612,3 +654,3 @@

var iterationCount = 0;
$('li').each(function(idx, elem) {
$('li').each(function(idx) {
iterationCount++;

@@ -648,3 +690,3 @@ return idx < 1;

var $fruits = $('li');
var $mapped = $fruits.map(function(i, el) {
var $mapped = $fruits.map(function(i) {
return $fruits[2 - i];

@@ -663,3 +705,3 @@ });

var $mapped = $fruits.map(function(i, el) {
var $mapped = $fruits.map(function(i) {
return retVals[i];

@@ -675,3 +717,3 @@ });

var $mapped = $fruits.map(function(i, el) {
var $mapped = $fruits.map(function() {
return [1, [3, 4]];

@@ -690,3 +732,3 @@ });

var $mapped = $fruits.map(function(i, el) {
var $mapped = $fruits.map(function() {
return [null, undefined];

@@ -729,3 +771,3 @@ });

expect(this).to.be(el);
expect(el.name).to.be('li');
expect(el.tagName).to.be('li');
expect(i).to.be.a('number');

@@ -739,2 +781,88 @@ return $(this).attr('class') === 'orange';

describe('.not', function() {
it('(selector) : should reduce the set of matched elements to those that do not match the selector', function() {
var $fruits = $('li');
var $notPear = $fruits.not('.pear');
expect($notPear).to.have.length(2);
expect($notPear[0]).to.be($fruits[0]);
expect($notPear[1]).to.be($fruits[1]);
});
it('(selector) : should not consider nested elements', function() {
var lis = $('#fruits').not('li');
expect(lis).to.have.length(1);
});
it('(selection) : should reduce the set of matched elements to those that are mot contained in the provided selection', function() {
var $fruits = $('li');
var $orange = $('.orange');
var $notOrange = $fruits.not($orange);
expect($notOrange).to.have.length(2);
expect($notOrange[0]).to.be($fruits[0]);
expect($notOrange[1]).to.be($fruits[2]);
});
it('(element) : should reduce the set of matched elements to those that specified directly', function() {
var $fruits = $('li');
var apple = $('.apple')[0];
var $notApple = $fruits.not(apple);
expect($notApple).to.have.length(2);
expect($notApple[0]).to.be($fruits[1]);
expect($notApple[1]).to.be($fruits[2]);
});
it('(fn) : should reduce the set of matched elements to those that do not pass the function\'s test', function() {
var $fruits = $('li');
var $notOrange = $fruits.not(function(i, el) {
expect(this).to.be(el);
expect(el.name).to.be('li');
expect(i).to.be.a('number');
return $(this).attr('class') === 'orange';
});
expect($notOrange).to.have.length(2);
expect($notOrange[0]).to.be($fruits[0]);
expect($notOrange[1]).to.be($fruits[2]);
});
});
describe('.has', function() {
beforeEach(function() {
$ = cheerio.load(food);
});
it('(selector) : should reduce the set of matched elements to those with descendants that match the selector', function() {
var $fruits = $('#fruits,#vegetables').has('.pear');
expect($fruits).to.have.length(1);
expect($fruits[0]).to.be($('#fruits')[0]);
});
it('(selector) : should only consider nested elements', function() {
var $empty = $('#fruits').has('#fruits');
expect($empty).to.have.length(0);
});
it('(element) : should reduce the set of matched elements to those that are ancestors of the provided element', function() {
var $fruits = $('#fruits,#vegetables').has($('.pear')[0]);
expect($fruits).to.have.length(1);
expect($fruits[0]).to.be($('#fruits')[0]);
});
it('(element) : should only consider nested elements', function() {
var $fruits = $('#fruits');
var fruits = $fruits[0];
var $empty = $fruits.has(fruits);
expect($empty).to.have.length(0);
});
});
describe('.first', function() {

@@ -746,3 +874,3 @@

expect($elem.length).to.equal(1);
expect($elem[0].children[0].data).to.equal('foo');
expect($elem[0].childNodes[0].data).to.equal('foo');
});

@@ -765,3 +893,3 @@

expect($elem.length).to.equal(1);
expect($elem[0].children[0].data).to.equal('baz');
expect($elem[0].childNodes[0].data).to.equal('baz');
});

@@ -785,5 +913,5 @@

expect($first.length).to.equal(1);
expect($first[0].children[0].data).to.equal('bar');
expect($first[0].childNodes[0].data).to.equal('bar');
expect($last.length).to.equal(1);
expect($last[0].children[0].data).to.equal('bar');
expect($last[0].childNodes[0].data).to.equal('bar');
expect($first[0]).to.equal($last[0]);

@@ -798,3 +926,3 @@ });

if(!el.length) return '';
return el[0].children[0].data;
return el[0].childNodes[0].data;
}

@@ -841,2 +969,56 @@

describe('.index', function() {
describe('() : ', function() {
it('returns the index of a child amongst its siblings', function() {
expect($('.orange').index()).to.be(1);
});
it('returns -1 when the selection has no parent', function() {
expect($('<div/>').index()).to.be(-1);
});
});
describe('(selector) : ', function() {
it('returns the index of the first element in the set matched by `selector`', function() {
expect($('.apple').index('#fruits, li')).to.be(1);
});
it('returns -1 when the item is not present in the set matched by `selector`', function() {
expect($('.apple').index('#fuits')).to.be(-1);
});
it('returns -1 when the first element in the set has no parent', function() {
expect($('<div/>').index('*')).to.be(-1);
});
});
describe('(node) : ', function() {
it('returns the index of the given node within the current selection', function() {
var $lis = $('li');
expect($lis.index($lis.get(1))).to.be(1);
});
it('returns the index of the given node within the current selection when the current selection has no parent', function() {
var $apple = $('.apple').remove();
expect($apple.index($apple.get(0))).to.be(0);
});
it('returns -1 when the given node is not present in the current selection', function() {
expect($('li').index($('#fruits').get(0))).to.be(-1);
});
it('returns -1 when the current selection is empty', function() {
expect($('.not-fruit').index($('#fruits').get(0))).to.be(-1);
});
});
describe('(selection) : ', function() {
it('returns the index of the first node in the provided selection within the current selection', function() {
var $lis = $('li');
expect($lis.index($('.orange, .pear'))).to.be(1);
});
it('returns -1 when the given node is not present in the current selection', function() {
expect($('li').index($('#fruits'))).to.be(-1);
});
it('returns -1 when the current selection is empty', function() {
expect($('.not-fruit').index($('#fruits'))).to.be(-1);
});
});
});
describe('.slice', function() {

@@ -846,3 +1028,3 @@

if(!el.length) return '';
return el[0].children[0].data;
return el[0].childNodes[0].data;
}

@@ -1196,2 +1378,46 @@

describe('.addBack', function() {
describe('() : ', function() {
it('includes siblings and self', function() {
var $selection = $('.orange').siblings().addBack();
expect($selection).to.have.length(3);
expect($selection[0]).to.be($('.apple')[0]);
expect($selection[1]).to.be($('.orange')[0]);
expect($selection[2]).to.be($('.pear')[0]);
});
it('includes children and self', function() {
var $selection = $('#fruits').children().addBack();
expect($selection).to.have.length(4);
expect($selection[0]).to.be($('#fruits')[0]);
expect($selection[1]).to.be($('.apple')[0]);
expect($selection[2]).to.be($('.orange')[0]);
expect($selection[3]).to.be($('.pear')[0]);
});
it('includes parent and self', function() {
var $selection = $('.apple').parent().addBack();
expect($selection).to.have.length(2);
expect($selection[0]).to.be($('#fruits')[0]);
expect($selection[1]).to.be($('.apple')[0]);
});
it('includes parents and self', function() {
var $ = cheerio.load(food);
var $selection = $('.apple').parents().addBack();
expect($selection).to.have.length(3);
expect($selection[0]).to.be($('#food')[0]);
expect($selection[1]).to.be($('#fruits')[0]);
expect($selection[2]).to.be($('.apple')[0]);
});
});
it('(filter) : filters the previous selection', function() {
var $selection = $('li').eq(1).addBack('.apple');
expect($selection).to.have.length(2);
expect($selection[0]).to.be($('.apple')[0]);
expect($selection[1]).to.be($('.orange')[0]);
});
});
});

@@ -86,2 +86,8 @@ var expect = require('expect.js'),

it('() : should preserve parsing options', function() {
var $ = cheerio.load('<div>π</div>', { decodeEntities: false });
var $div = $('div');
expect($div.text()).to.equal($div.clone().text());
});
});

@@ -118,3 +124,3 @@

var html = '<script>undefined()</script>';
expect(cheerio.parseHTML(html, true)[0].name).to.match(/script/i);
expect(cheerio.parseHTML(html, true)[0].tagName).to.match(/script/i);
});

@@ -124,3 +130,3 @@

var html = '<script>undefined()</script><div></div>';
expect(cheerio.parseHTML(html)[0].name).to.match(/div/i);
expect(cheerio.parseHTML(html)[0].tagName).to.match(/div/i);
});

@@ -130,3 +136,3 @@

var html = '<script>undefined()</script><div></div>';
expect(cheerio.parseHTML(html, true)[0].name).to.match(/script/i);
expect(cheerio.parseHTML(html, true)[0].tagName).to.match(/script/i);
});

@@ -161,2 +167,33 @@

describe('.contains', function() {
var $;
beforeEach(function() {
$ = cheerio.load(fixtures.food);
});
it('(container, contained) : should correctly detect the provided element', function() {
var $food = $('#food');
var $fruits = $('#fruits');
var $apple = $('.apple');
expect($.contains($food[0], $fruits[0])).to.equal(true);
expect($.contains($food[0], $apple[0])).to.equal(true);
});
it('(container, other) : should not detect elements that are not contained', function() {
var $fruits = $('#fruits');
var $vegetables = $('#vegetables');
var $apple = $('.apple');
expect($.contains($vegetables[0], $apple[0])).to.equal(false);
expect($.contains($fruits[0], $vegetables[0])).to.equal(false);
expect($.contains($vegetables[0], $fruits[0])).to.equal(false);
expect($.contains($fruits[0], $fruits[0])).to.equal(false);
expect($.contains($vegetables[0], $vegetables[0])).to.equal(false);
});
});
describe('.root', function() {

@@ -163,0 +200,0 @@

@@ -47,3 +47,3 @@ var expect = require('expect.js'),

expect($h2).to.have.length(1);
expect($h2[0].name).to.equal('h2');
expect($h2[0].tagName).to.equal('h2');
});

@@ -57,3 +57,3 @@

expect($script[0].attribs.type).to.equal('text/javascript');
expect($script[0].children).to.be.empty();
expect($script[0].childNodes).to.be.empty();
});

@@ -64,7 +64,7 @@

$apple = $apple[0];
expect($apple.parent.name).to.equal('ul');
expect($apple.parentNode.tagName).to.equal('ul');
expect($apple.prev).to.be(null);
expect($apple.next.attribs['class']).to.equal('orange');
expect($apple.children).to.have.length(1);
expect($apple.children[0].data).to.equal('Apple');
expect($apple.childNodes).to.have.length(1);
expect($apple.childNodes[0].data).to.equal('Apple');
};

@@ -96,14 +96,5 @@

expect($ul).to.have.length(1);
expect($ul[0].name).to.equal('ul');
expect($ul[0].tagName).to.equal('ul');
});
it('should be able to filter down using the context', function() {
var q = $.load(fruits),
apple = q('.apple', 'ul'),
lis = q('li', 'ul');
expect(apple).to.have.length(1);
expect(lis).to.have.length(3);
});
it('should accept a node reference as a context', function() {

@@ -127,9 +118,2 @@ var $elems = $('<div><span></span></div>');

it('should allow loading a pre-parsed DOM', function() {
var dom = htmlparser2.parseDOM(food),
q = $.load(dom);
expect(q('ul')).to.have.length(3);
});
it('should be able to select multiple tags', function() {

@@ -162,3 +146,3 @@ var $fruits = $('li', null, fruits);

expect($a).to.have.length(1);
expect($a[0].children[0].data).to.equal('Save');
expect($a[0].childNodes[0].data).to.equal('Save');
});

@@ -244,3 +228,3 @@

var extended = [];
var custom = extended.find = extended.children = extended.each = function() {};
extended.find = extended.children = extended.each = function() {};
var $empty = $(extended);

@@ -253,36 +237,66 @@

it('should render xml in html() when options.xmlMode = true', function() {
var str = '<MixedCaseTag UPPERCASEATTRIBUTE=""></MixedCaseTag>',
expected = '<MixedCaseTag UPPERCASEATTRIBUTE=""/>',
dom = $.load(str, {xmlMode: true});
describe('.load', function() {
expect(dom('MixedCaseTag').get(0).name).to.equal('MixedCaseTag');
expect(dom.html()).to.be(expected);
});
it('should generate selections as proper instances', function() {
var q = $.load(fruits);
it('should render xml in html() when options.xmlMode = true passed to html()', function() {
var str = '<MixedCaseTag UPPERCASEATTRIBUTE=""></MixedCaseTag>',
// since parsing done without xmlMode flag, all tags converted to lowercase
expectedXml = '<mixedcasetag uppercaseattribute=""/>',
expectedNoXml = '<mixedcasetag uppercaseattribute=""></mixedcasetag>',
dom = $.load(str);
expect(q('.apple')).to.be.a(q);
});
expect(dom('MixedCaseTag').get(0).name).to.equal('mixedcasetag');
expect(dom.html()).to.be(expectedNoXml);
expect(dom.html({xmlMode: true})).to.be(expectedXml);
});
it('should be able to filter down using the context', function() {
var q = $.load(fruits),
apple = q('.apple', 'ul'),
lis = q('li', 'ul');
it('should respect options on the element level', function() {
var str = '<!doctype html><html><head><title>Some test</title></head><body><footer><p>Copyright &copy; 2003-2014</p></footer></body></html>',
expectedHtml = '<p>Copyright &copy; 2003-2014</p>',
expectedXml = '<p>Copyright &#xA9; 2003-2014</p>',
domNotEncoded = $.load(str, {decodeEntities: false}),
domEncoded = $.load(str);
expect(apple).to.have.length(1);
expect(lis).to.have.length(3);
});
expect(domNotEncoded('footer').html()).to.be(expectedHtml);
// TODO: Make it more html friendly, maybe with custom encode tables
expect(domEncoded('footer').html()).to.be(expectedXml);
});
it('should allow loading a pre-parsed DOM', function() {
var dom = htmlparser2.parseDOM(food),
q = $.load(dom);
expect(q('ul')).to.have.length(3);
});
it('should render xml in html() when options.xmlMode = true', function() {
var str = '<MixedCaseTag UPPERCASEATTRIBUTE=""></MixedCaseTag>',
expected = '<MixedCaseTag UPPERCASEATTRIBUTE=""/>',
dom = $.load(str, {xmlMode: true});
expect(dom('MixedCaseTag').get(0).tagName).to.equal('MixedCaseTag');
expect(dom.html()).to.be(expected);
});
it('should render xml in html() when options.xmlMode = true passed to html()', function() {
var str = '<MixedCaseTag UPPERCASEATTRIBUTE=""></MixedCaseTag>',
// since parsing done without xmlMode flag, all tags converted to lowercase
expectedXml = '<mixedcasetag uppercaseattribute=""/>',
expectedNoXml = '<mixedcasetag uppercaseattribute=""></mixedcasetag>',
dom = $.load(str);
expect(dom('MixedCaseTag').get(0).tagName).to.equal('mixedcasetag');
expect(dom.html()).to.be(expectedNoXml);
expect(dom.html({xmlMode: true})).to.be(expectedXml);
});
it('should respect options on the element level', function() {
var str = '<!doctype html><html><head><title>Some test</title></head><body><footer><p>Copyright &copy; 2003-2014</p></footer></body></html>',
expectedHtml = '<p>Copyright &copy; 2003-2014</p>',
expectedXml = '<p>Copyright &#xA9; 2003-2014</p>',
domNotEncoded = $.load(str, {decodeEntities: false}),
domEncoded = $.load(str);
expect(domNotEncoded('footer').html()).to.be(expectedHtml);
// TODO: Make it more html friendly, maybe with custom encode tables
expect(domEncoded('footer').html()).to.be(expectedXml);
});
it('should return a fully-qualified Function', function() {
var $c = $.load('<div>');
expect($c).to.be.a(Function);
});
});
});

@@ -47,2 +47,3 @@ /* jshint indent: false */

'<input type="radio" value="off" name="radio" /><input type="radio" name="radio" value="on" checked />',
'<input type="radio" value="off" name="radio[brackets]" /><input type="radio" name="radio[brackets]" value="on" checked />',
'<select id="multi" multiple><option value="1">1</option><option value="2" selected>2</option><option value="3" selected>3</option><option value="4">4</option></select>'

@@ -49,0 +50,0 @@ ].join('');

@@ -48,4 +48,4 @@ var expect = require('expect.js'),

expect(tag.type).to.equal('tag');
expect(tag.name).to.equal('html');
expect(tag.children).to.be.empty();
expect(tag.tagName).to.equal('html');
expect(tag.childNodes).to.be.empty();
});

@@ -59,4 +59,4 @@

expect(dom).to.have.length(2);
expect(h2.name).to.equal('h2');
expect(p.name).to.equal('p');
expect(h2.tagName).to.equal('h2');
expect(p.tagName).to.equal('p');
});

@@ -67,4 +67,4 @@

expect(tag.type).to.equal('tag');
expect(tag.name).to.equal('br');
expect(tag.children).to.be.empty();
expect(tag.tagName).to.equal('br');
expect(tag.childNodes).to.be.empty();
});

@@ -75,4 +75,4 @@

expect(tag.type).to.equal('tag');
expect(tag.name).to.equal('br');
expect(tag.children).to.be.empty();
expect(tag.tagName).to.equal('br');
expect(tag.childNodes).to.be.empty();
});

@@ -83,5 +83,5 @@

expect(tag.type).to.equal('tag');
expect(tag.name).to.equal('html');
expect(tag.children).to.be.ok();
expect(tag.children).to.have.length(1);
expect(tag.tagName).to.equal('html');
expect(tag.childNodes).to.be.ok();
expect(tag.childNodes).to.have.length(1);
});

@@ -91,4 +91,4 @@

var tag = parse.evaluate(li, defaultOpts)[0];
expect(tag.children).to.have.length(1);
expect(tag.children[0].data).to.equal('Durian');
expect(tag.childNodes).to.have.length(1);
expect(tag.childNodes[0].data).to.equal('Durian');
});

@@ -130,7 +130,7 @@

expect(script_.type).to.equal('script');
expect(script_.name).to.equal('script');
expect(script_.tagName).to.equal('script');
expect(script_.attribs.type).to.equal('text/javascript');
expect(script_.children).to.have.length(1);
expect(script_.children[0].type).to.equal('text');
expect(script_.children[0].data).to.equal('alert("hi world!");');
expect(script_.childNodes).to.have.length(1);
expect(script_.childNodes[0].type).to.equal('text');
expect(script_.childNodes[0].data).to.equal('alert("hi world!");');
});

@@ -141,7 +141,7 @@

expect(style_.type).to.equal('style');
expect(style_.name).to.equal('style');
expect(style_.tagName).to.equal('style');
expect(style_.attribs.type).to.equal('text/css');
expect(style_.children).to.have.length(1);
expect(style_.children[0].type).to.equal('text');
expect(style_.children[0].data).to.equal(' h2 { color:blue; } ');
expect(style_.childNodes).to.have.length(1);
expect(style_.childNodes[0].type).to.equal('text');
expect(style_.childNodes[0].data).to.equal(' h2 { color:blue; } ');
});

@@ -153,3 +153,3 @@

expect(elem.data).to.equal('!doctype html');
expect(elem.name).to.equal('!doctype');
expect(elem.tagName).to.equal('!doctype');
});

@@ -163,11 +163,11 @@

function rootTest(root) {
expect(root.name).to.equal('root');
expect(root.tagName).to.equal('root');
// Should exist but be null
expect(root.next).to.be(null);
expect(root.prev).to.be(null);
expect(root.parent).to.be(null);
expect(root.nextSibling).to.be(null);
expect(root.previousSibling).to.be(null);
expect(root.parentNode).to.be(null);
var child = root.children[0];
expect(child.parent).to.be(null);
var child = root.childNodes[0];
expect(child.parentNode).to.be(null);
}

@@ -178,4 +178,4 @@

rootTest(root);
expect(root.children).to.have.length(1);
expect(root.children[0].name).to.equal('html');
expect(root.childNodes).to.have.length(1);
expect(root.childNodes[0].tagName).to.equal('html');
});

@@ -186,6 +186,6 @@

rootTest(root);
expect(root.children).to.have.length(2);
expect(root.children[0].name).to.equal('h2');
expect(root.children[1].name).to.equal('p');
expect(root.children[1].parent).to.equal(null);
expect(root.childNodes).to.have.length(2);
expect(root.childNodes[0].tagName).to.equal('h2');
expect(root.childNodes[1].tagName).to.equal('p');
expect(root.childNodes[1].parent).to.equal(null);
});

@@ -196,4 +196,4 @@

rootTest(root);
expect(root.children).to.have.length(1);
expect(root.children[0].type).to.equal('comment');
expect(root.childNodes).to.have.length(1);
expect(root.childNodes[0].type).to.equal('comment');
});

@@ -204,4 +204,4 @@

rootTest(root);
expect(root.children).to.have.length(1);
expect(root.children[0].type).to.equal('text');
expect(root.childNodes).to.have.length(1);
expect(root.childNodes[0].type).to.equal('text');
});

@@ -212,4 +212,4 @@

rootTest(root);
expect(root.children).to.have.length(1);
expect(root.children[0].type).to.equal('script');
expect(root.childNodes).to.have.length(1);
expect(root.childNodes[0].type).to.equal('script');
});

@@ -220,4 +220,4 @@

rootTest(root);
expect(root.children).to.have.length(1);
expect(root.children[0].type).to.equal('style');
expect(root.childNodes).to.have.length(1);
expect(root.childNodes[0].type).to.equal('style');
});

@@ -228,8 +228,42 @@

rootTest(root);
expect(root.children).to.have.length(1);
expect(root.children[0].type).to.equal('directive');
expect(root.childNodes).to.have.length(1);
expect(root.childNodes[0].type).to.equal('directive');
});
it('should expose the DOM level 1 API', function() {
var root = parse('<div><a></a><span></span><p></p></div>', defaultOpts).childNodes[0];
var childNodes = root.childNodes;
expect(childNodes).to.have.length(3);
expect(root.tagName).to.be('div');
expect(root.firstChild).to.be(childNodes[0]);
expect(root.lastChild).to.be(childNodes[2]);
expect(childNodes[0].tagName).to.be('a');
expect(childNodes[0].previousSibling).to.be(null);
expect(childNodes[0].nextSibling).to.be(childNodes[1]);
expect(childNodes[0].parentNode).to.be(root);
expect(childNodes[0].childNodes).to.have.length(0);
expect(childNodes[0].firstChild).to.be(null);
expect(childNodes[0].lastChild).to.be(null);
expect(childNodes[1].tagName).to.be('span');
expect(childNodes[1].previousSibling).to.be(childNodes[0]);
expect(childNodes[1].nextSibling).to.be(childNodes[2]);
expect(childNodes[1].parentNode).to.be(root);
expect(childNodes[1].childNodes).to.have.length(0);
expect(childNodes[1].firstChild).to.be(null);
expect(childNodes[1].lastChild).to.be(null);
expect(childNodes[2].tagName).to.be('p');
expect(childNodes[2].previousSibling).to.be(childNodes[1]);
expect(childNodes[2].nextSibling).to.be(null);
expect(childNodes[2].parentNode).to.be(root);
expect(childNodes[2].childNodes).to.have.length(0);
expect(childNodes[2].firstChild).to.be(null);
expect(childNodes[2].lastChild).to.be(null);
});
});
});

@@ -47,3 +47,2 @@ var expect = require('expect.js'),

var $x = cheerio.load('', { xmlMode: false });
var $h = cheerio.load('', { xmlMode: true });

@@ -50,0 +49,0 @@ expect($x(str).html()).to.equal('<someelem someattribute="something">hello</someelem>');

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc