Socket
Socket
Sign inDemoInstall

cheerio

Package Overview
Dependencies
Maintainers
1
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.4.2 to 0.5.0

53

History.md

@@ -0,1 +1,9 @@

0.5.0 / 2012-02-04
==================
* Transitioned from Coffeescript back to Javascript
* Parser now ignores whitespace
* Fixed issue with double slashes on self-enclosing tags
* Added boolean attributes to html rendering
0.4.2 / 2012-01-16

@@ -15,8 +23,8 @@ ==================

* Rewrote all unit tests as cheerio transitioned from vows -> mocha
* Internally, renderer.render -> render(...), parser.parse -> parse(...)
* Append, prepend, html, before, after all work with only text (no tags)
* Bugfix: Attributes can now be removed from script and style tags
* Added yield as a single tag
* Cheerio now compatible with node >=0.4.7
* Rewrote all unit tests as cheerio transitioned from vows -> mocha
* Internally, renderer.render -> render(...), parser.parse -> parse(...)
* Append, prepend, html, before, after all work with only text (no tags)
* Bugfix: Attributes can now be removed from script and style tags
* Added yield as a single tag
* Cheerio now compatible with node >=0.4.7

@@ -26,3 +34,3 @@ 0.3.2 / 2011-12-1

* Fixed $(...).text(...) to work with "root" element
* Fixed $(...).text(...) to work with "root" element

@@ -32,6 +40,6 @@ 0.3.1 / 2011-11-25

* Now relying on cheerio-soupselect instead of node-soupselect
* Removed all lingering htmlparser dependencies
* parser now returns parent "root" element. Root now never needs to be updated when there is multiple roots. This fixes ongoing issues with before(...), after(...) and other manipulation functions
* Added jQuery's $(...).replaceWith(...)
* Now relying on cheerio-soupselect instead of node-soupselect
* Removed all lingering htmlparser dependencies
* parser now returns parent "root" element. Root now never needs to be updated when there is multiple roots. This fixes ongoing issues with before(...), after(...) and other manipulation functions
* Added jQuery's $(...).replaceWith(...)

@@ -41,7 +49,7 @@ 0.3.0 / 2011-11-19

* Now using htmlparser2 for parsing (2x speed increase, cleaner, actively developed)
* Added benchmark directory for future speed tests
* $("...").dom() was funky, so it was removed in favor of $("...").get(). $.dom() still works the same.
* $.root now correctly static across all instances of $
* Added a screencast
* Now using htmlparser2 for parsing (2x speed increase, cleaner, actively developed)
* Added benchmark directory for future speed tests
* $("...").dom() was funky, so it was removed in favor of $("...").get(). $.dom() still works the same.
* $.root now correctly static across all instances of $
* Added a screencast

@@ -51,5 +59,5 @@ 0.2.2 / 2011-11-9

* Traversing will select `<script>` and `<style>` tags (Closes Issue: #8)
* .text(string) now working with empty elements (Closes Issue: #7)
* Fixed before(...) & after(...) again if there is no parent (Closes Issue: #2)
* Traversing will select `<script>` and `<style>` tags (Closes Issue: #8)
* .text(string) now working with empty elements (Closes Issue: #7)
* Fixed before(...) & after(...) again if there is no parent (Closes Issue: #2)

@@ -59,5 +67,4 @@ 0.2.1 / 2011-11-5

* Fixed before(...) & after(...) if there is no parent (Closes Issue: #2)
* Comments now rendered correctly (Closes Issue: #5)
* Fixed before(...) & after(...) if there is no parent (Closes Issue: #2)
* Comments now rendered correctly (Closes Issue: #5)

@@ -67,2 +74,2 @@ < 0.2.0 / 2011-10-31

* Initial release (untracked development)
* Initial release (untracked development)

@@ -1,19 +0,18 @@

// Use source if we have coffeescript otherwise use lib
var base;
try {
// Need to have coffeescript installed locally in order to run from src
require('./node_modules/coffee-script');
base = './src/';
} catch (e) {
base = './lib/';
}
exports = module.exports = require('./lib/cheerio');
exports = module.exports = require(base + 'cheerio');
/*
Attach objects to cheerio
*/
exports.parse = require('./lib/parse');
exports.render = require('./lib/render');
exports.utils = require('./lib/utils');
exports.parse = require(base + 'parse');
exports.render = require(base + 'render');
exports.utils = require(base + 'utils');
/*
Export the version
*/
var version = function() {
var pkg = require('fs').readFileSync(__dirname + '/package.json', 'utf8');
return JSON.parse(pkg).version;
};
/*
Attach other modules on here, this will allow testing to be done in mocha without recompiling
*/
exports.__defineGetter__('version', version);

@@ -1,102 +0,124 @@

(function() {
var $, addClass, attr, hasClass, rclass, removeAttr, removeClass, rspace, _;
var _ = require("underscore"),
$ = require("../cheerio"),
rclass = /[\n\t\r]/g,
rspace = /\s+/;
_ = require("underscore");
var attr = exports.attr = function(name, value) {
return $.access(this, name, value, true, $.attr);
};
$ = require("../cheerio");
var removeAttr = exports.removeAttr = function(name) {
this.each(function() {
$.removeAttr(this, name);
});
return this;
};
rclass = /[\n\t\r]/g;
var hasClass = exports.hasClass = function(selector) {
var className = " " + selector + " ",
classes,
elem;
rspace = /\s+/;
for(var i = 0; i < this.length; i++) {
elem = this[i];
// Add spaces to support multiple classes
classes = (" " + elem.attribs["class"] + " ").replace(rclass, " ");
if ($.isTag(elem) && elem.attribs && classes.indexOf(className) > -1) {
return true;
}
}
return false;
};
attr = exports.attr = function(name, value) {
return $.access(this, name, value, true, $.attr);
};
var addClass = exports.addClass = function(value) {
// Support functions
if (_.isFunction(value)) {
this.each(function(i) {
var $this = $(this),
className = $this.attr('class') || "";
removeAttr = exports.removeAttr = function(name) {
return this.each(function() {
return $.removeAttr(this, name);
$this.addClass(value.call(this, i, className));
});
};
}
hasClass = exports.hasClass = function(selector) {
var className, elem, _i, _len;
className = " " + selector + " ";
for (_i = 0, _len = this.length; _i < _len; _i++) {
elem = this[_i];
if ($.isTag(elem) && elem.attribs && (" " + elem.attribs["class"] + " ").replace(rclass, " ").indexOf(className) > -1) {
return true;
// Return if no value or not a string or function
if (!value || !_.isString(value)) return this;
var classNames = value.split(rspace),
numElements = this.length,
numClasses,
setClass,
$elem;
for(var i = 0; i < numElements; i++) {
$elem = $(this[i]);
// If selected element isnt a tag, move on
if (!$.isTag(this[i])) continue;
// If we don't already have classes
if (!$elem.attr("class")) {
$elem.attr('class', classNames.join(' ').trim());
} else {
setClass = " " + $elem.attr("class") + " ";
numClasses = classNames.length;
// Check if class already exists
for (var j = 0; j < numClasses; j++) {
if (!~setClass.indexOf(" " + classNames[j] + " "))
setClass += classNames[j] + " ";
}
$elem.attr('class', setClass.trim());
}
return false;
};
}
addClass = exports.addClass = function(value) {
var $elem, className, classNames, elem, setClass, _i, _j, _len, _len2;
if (_.isFunction(value)) {
return this.each(function(i) {
var $this, className;
$this = $(this);
className = $this.attr('class') || "";
return $this.addClass(value.call(this, i, className));
});
return this;
};
var removeClass = exports.removeClass = function(value) {
// Handle if value is a function
if (_.isFunction(value)) {
this.each(function(j) {
var $this = $(this),
className = $this.attr('class') || "";
$this.removeClass(value.call(this, j, className));
});
}
// If value isnt undefined and also not a string
if(value !== undefined && !_.isString(value)) return this;
var classNames = (value || "").split(rspace),
numClasses = classNames.length,
className,
$elem,
ret;
for (var i = 0, iLen = this.length; i < iLen; i++) {
$elem = $(this[i]);
className = this[i].attribs['class'];
if(!$.isTag(this[i]) || !className) continue;
else if(!value) {
this[i].attribs['class'] = '';
continue;
}
if (value && _.isString(value)) {
classNames = value.split(rspace);
for (_i = 0, _len = this.length; _i < _len; _i++) {
elem = this[_i];
$elem = $(elem);
if ($.isTag(elem)) {
if (!$elem.attr("class")) {
$elem.attr('class', classNames.join(' ').trim());
} else {
setClass = " " + $elem.attr("class") + " ";
for (_j = 0, _len2 = classNames.length; _j < _len2; _j++) {
className = classNames[_j];
if (!~setClass.indexOf(" " + className + " ")) {
setClass += className + " ";
}
}
$elem.attr('class', setClass.trim());
}
}
}
}
return this;
};
removeClass = exports.removeClass = function(value) {
var $elem, className, classNames, elem, ret, _i, _j, _len, _len2;
if (_.isFunction(value)) {
return this.each(function(j) {
var $this, className;
$this = $(this);
className = $this.attr('class') || "";
return $this.removeClass(value.call(this, j, className));
});
// Separate out the classes
ret = (" " + className + " ").replace(rclass, " ");
for (var j = 0; j < numClasses; j++) {
className = classNames[j];
ret = ret.replace(" " + className + " ", " ");
}
if ((value && _.isString(value)) || value === void 0) {
classNames = (value || "").split(rspace);
for (_i = 0, _len = this.length; _i < _len; _i++) {
elem = this[_i];
$elem = $(elem);
if ($.isTag(elem) && $elem.attr('class')) {
if (value) {
ret = (" " + $elem.attr('class') + " ").replace(rclass, " ");
for (_j = 0, _len2 = classNames.length; _j < _len2; _j++) {
className = classNames[_j];
ret = ret.replace(" " + className + " ", " ");
}
$elem.attr('class', ret.trim());
} else {
$elem.attr('class', '');
}
}
}
}
return this;
};
module.exports = $.fn.extend(exports);
this[i].attribs['class'] = ret.trim();
}
}).call(this);
return this;
};
module.exports = $.fn.extend(exports);

@@ -1,64 +0,62 @@

(function() {
var $, get, pushStack, siblingsAndMe, size, toArray, underscore;
var underscore = require('underscore'),
$ = require('../cheerio');
var size = exports.size = function() {
return this.length;
};
underscore = require('underscore');
var toArray = exports.toArray = function() {
return Array.prototype.slice.call(this, 0);
};
$ = require('../cheerio');
var get = exports.get = function(num) {
if (num === undefined) return this.toArray();
size = exports.size = function() {
return this.length;
};
if(~num) {
return this[num];
} else {
// Reverse lookup
return this[this.length + num];
}
};
toArray = exports.toArray = function() {
return Array.prototype.slice.call(this, 0);
};
var pushStack = exports.pushStack = function(elems, name, selector) {
var ret = this.constructor();
if ($.isArray(elems)) {
push.apply(ret, elems);
} else {
$.merge(ret, elems);
}
ret.prevObject = this;
ret.context = this.context;
if (name === "find") {
ret.selector = this.selector + (this.selector ? " " : "") + selector;
} else if(name) {
ret.selector = this.selector + "." + name + "(" + selector + ")";
}
return ret;
};
get = exports.get = function(num) {
if (num === void 0) {
return this.toArray();
} else {
if (num < 0) {
return this[this.length + num];
} else {
return this[num];
}
}
};
pushStack = exports.pushStack = function(elems, name, selector) {
var ret;
ret = this.constructor();
if ($.isArray(elems)) {
push.apply(ret, elems);
} else {
$.merge(ret, elems);
}
ret.prevObject = this;
ret.context = this.context;
if (name === "find") {
ret.selector = this.selector + (this.selector ? " " : "") + selector;
} else {
if (name) ret.selector = this.selector + "." + name + "(" + selector + ")";
}
return ret;
};
siblingsAndMe = exports.siblingsAndMe = function() {
var element, raw, siblings;
siblings = [];
raw = this[0];
element = raw;
while (element.prev) {
element = element.prev;
}
var siblingsAndMe = exports.siblingsAndMe = function() {
var siblings = [],
raw = this[0],
element = raw;
while (element.prev) {
element = element.prev;
}
siblings.push(element);
while (element.next) {
element = element.next;
siblings.push(element);
while (element.next) {
element = element.next;
siblings.push(element);
}
return siblings;
};
}
return siblings;
};
module.exports = $.fn.extend(exports);
}).call(this);
module.exports = $.fn.extend(exports);

@@ -1,185 +0,216 @@

(function() {
var $, after, append, before, empty, html, parse, prepend, remove, removeChild, replaceWith, text, _;
var __slice = Array.prototype.slice;
var _ = require('underscore'),
$ = require('../cheerio'),
parse = require('../parse'),
slice = Array.prototype.slice;
_ = require('underscore');
var removeChild = function(parent, elem) {
$.each(parent.children, function(i, child) {
if (elem === child)
parent.children.splice(i, 1);
});
};
$ = require('../cheerio');
/*
Creates an array of cheerio objects,
parsing strings if necessary
*/
var makeCheerioArray = function(elems) {
var dom = [],
len = elems.length,
elem;
parse = require('../parse');
for(var i = 0; i < len; i++) {
elem = elems[i];
// If a cheerio object
if(elem.cheerio) {
dom = dom.concat(elem.toArray());
} else {
dom = dom.concat(parse.eval(elem));
}
}
removeChild = function(parent, elem) {
return $.each(parent.children, function(i, child) {
if (elem === child) return parent.children.splice(i, 1);
});
};
return dom;
};
append = exports.append = function() {
var dom, elem, elems, _i, _len;
elems = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
dom = [];
for (_i = 0, _len = elems.length; _i < _len; _i++) {
elem = elems[_i];
if (elem.cheerio) {
dom = dom.concat(elem.toArray());
} else {
dom = dom.concat(parse.eval(elem));
}
}
this.each(function() {
if (_.isFunction(elems[0])) {} else {
if (!this.children) this.children = [];
this.children = this.children.concat(dom);
return $.updateDOM(this.children, this);
}
});
return this;
};
var append = exports.append = function() {
var elems = slice.call(arguments),
dom = makeCheerioArray(elems);
prepend = exports.prepend = function() {
var dom, elem, elems, _i, _len;
elems = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
dom = [];
for (_i = 0, _len = elems.length; _i < _len; _i++) {
elem = elems[_i];
if (elem.cheerio) {
dom = dom.concat(elem.toArray());
} else {
dom = dom.concat(parse.eval(elem));
}
this.each(function() {
if(_.isFunction(elems[0])) {
// No yet supported
return;
} else {
if(!this.children) this.children = [];
this.children = this.children.concat(dom);
$.updateDOM(this.children, this);
}
this.each(function() {
if (_.isFunction(elems[0])) {} else {
if (!this.children) this.children = [];
this.children = dom.concat(this.children);
return $.updateDOM(this.children, this);
}
});
return this;
};
});
after = exports.after = function() {
var dom, elem, elems, _i, _len;
elems = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
dom = [];
for (_i = 0, _len = elems.length; _i < _len; _i++) {
elem = elems[_i];
if (elem.cheerio) {
dom = dom.concat(elem.toArray());
} else {
dom = dom.concat(parse.eval(elem));
}
}
this.each(function() {
var index, siblings;
siblings = this.parent.children;
index = siblings.indexOf(this);
if (index >= 0) siblings.splice.apply(siblings, [index + 1, 0].concat(dom));
$.updateDOM(siblings, this.parent);
return this.parent.children = siblings;
});
return this;
};
return this;
};
before = exports.before = function() {
var dom, elem, elems, _i, _len;
elems = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
dom = [];
for (_i = 0, _len = elems.length; _i < _len; _i++) {
elem = elems[_i];
if (elem.cheerio) {
dom = dom.concat(elem.toArray());
} else {
dom = dom.concat(parse.eval(elem));
}
/*
TODO: Refactor, only one line difference between,
this function and append
*/
var prepend = exports.prepend = function() {
var elems = slice.call(arguments),
dom = makeCheerioArray(elems);
this.each(function() {
if(_.isFunction(elems[0])) {
// No yet supported
return;
} else {
if(!this.children) this.children = [];
this.children = dom.concat(this.children);
$.updateDOM(this.children, this);
}
this.each(function() {
var index, siblings;
siblings = this.parent.children;
index = siblings.indexOf(this);
if (index >= 0) siblings.splice.apply(siblings, [index, 0].concat(dom));
$.updateDOM(siblings, this.parent);
return this.parent.children = siblings;
});
return this;
};
});
remove = exports.remove = function(selector) {
var elems;
elems = this;
if (selector) elems = this.find(selector);
elems.each(function() {
var index, siblings;
siblings = this.parent.children;
index = siblings.indexOf(this);
siblings.splice(index, 1);
$.updateDOM(siblings, this.parent);
return this.parent.children = siblings;
});
return this;
};
return this;
};
replaceWith = exports.replaceWith = function(content) {
var elems;
elems = parse.eval(content);
return this.each(function() {
var index, siblings;
siblings = this.parent.children;
index = siblings.indexOf(this);
siblings.splice.apply(siblings, [index, 1].concat(elems));
$.updateDOM(siblings, this.parent);
return this.parent.children = siblings;
});
};
var after = exports.after = function() {
var elems = slice.call(arguments),
dom = makeCheerioArray(elems);
empty = exports.empty = function() {
return this.each(function() {
return this.children = [];
this.each(function() {
var siblings = this.parent.children,
index = siblings.indexOf(this);
// If not found, move on
if(!~index) return;
// Add element after `this` element
siblings.splice.apply(siblings, [++index, 0].concat(dom));
// Update next, prev, and parent pointers
$.updateDOM(siblings, this.parent);
this.parent.children = siblings;
});
return this;
};
var before = exports.before = function() {
var elems = slice.call(arguments),
dom = makeCheerioArray(elems);
this.each(function() {
var siblings = this.parent.children,
index = siblings.indexOf(this);
// If not found, move on
if(!~index) return;
// Add element before `this` element
siblings.splice.apply(siblings, [index, 0].concat(dom));
// Update next, prev, and parent pointers
$.updateDOM(siblings, this.parent);
this.parent.children = siblings;
});
return this;
};
/*
remove([selector])
*/
var remove = exports.remove = function(selector) {
var elems = this;
// Filter if we have selector
if(selector)
elems = elems.find(selector);
elems.each(function() {
var siblings = this.parent.children,
index = siblings.indexOf(this);
if(!~index) return;
siblings.splice(index, 1);
// Update next, prev, and parent pointers
$.updateDOM(siblings, this.parent);
this.parent.children = siblings;
});
return this;
};
var replaceWith = exports.replaceWith = function(content) {
var elems = parse.eval(content);
this.each(function() {
var siblings = this.parent.children,
index = siblings.indexOf(this);
if(!~index) return;
siblings.splice.apply(siblings, [index, 1].concat(elems));
$.updateDOM(siblings, this.parent);
this.parent.children = siblings;
});
return this;
};
var empty = exports.empty = function() {
this.each(function() {
this.children = [];
});
return this;
};
var html = exports.html = function(str) {
if(!str || typeof(str) === 'object')
return $.html(this[0]);
str = parse.eval(str);
this.each(function() {
this.children = str;
});
return this;
};
var text = exports.text = function(str) {
// If `str` blank or an object
if(!str || typeof(str) === 'object') {
return $.text(this);
} else if (_.isFunction(str)) {
// Function support
this.each(function(i) {
var self = $(this);
return self.text(textString.call(this, i, self.text()));
});
};
}
html = exports.html = function(htmlString) {
var htmlElement;
if (typeof htmlString !== "object" && htmlString !== void 0) {
htmlElement = parse.eval(htmlString);
this.each(function(i) {
return this.children = htmlElement;
});
return this;
} else {
return $.html(this[0]);
}
var elem = {
data : str,
type : 'text',
parent : null,
prev : null,
next : null,
children : []
};
text = exports.text = function(textString) {
var textElement;
if (_.isFunction(textString)) {
this.each(function(i) {
var self;
self = $(this);
return self.text(textString.call(this, i, self.text()));
});
}
if (typeof textString !== "object" && textString !== void 0) {
textElement = {
raw: textString,
data: textString,
type: "text",
parent: null,
prev: null,
next: null,
children: []
};
this.each(function(i) {
this.children = textElement;
return $.updateDOM(this.children, this);
});
return this;
} else {
return $.text(this);
}
};
// Append text node to each selected elements
this.each(function() {
this.children = elem;
$.updateDOM(this.children, this);
});
module.exports = $.fn.extend(exports);
return this;
};
}).call(this);
module.exports = $.fn.extend(exports);

@@ -1,95 +0,70 @@

(function() {
var $, children, each, find, next, parent, prev, siblings, soupselect, _;
var _ = require("underscore"),
soupselect = require("cheerio-soupselect"),
$ = require("../cheerio");
_ = require("underscore");
var find = exports.find = function(selector) {
if(!selector) return this;
soupselect = require("cheerio-soupselect");
var elem = soupselect.select(this.toArray(), selector);
return $(elem);
};
$ = require("../cheerio");
var parent = exports.parent = function(elem) {
if(this[0] && this[0].parent)
return $(this[0].parent);
else
return null;
};
/*
Stupidly simple traversal
TODO : Make it more jQuery-like
*/
var next = exports.next = function(elem) {
if(!this[0]) return null;
find = exports.find = function(selector) {
var elem;
if (!selector) return this;
elem = soupselect.select(this.toArray(), selector);
return $(elem);
};
var nextSibling = this[0].next;
while(nextSibling) {
if($.isTag(nextSibling)) return $(nextSibling);
nextSibling = nextSibling.next;
}
};
parent = exports.parent = function(elem) {
if (this[0] && this[0].parent) {
return $(this[0].parent);
} else {
return null;
}
};
var prev = exports.prev = function(elem) {
if(!this[0]) return null;
next = exports.next = function(elem) {
var nextSibling;
if (!this[0]) return null;
nextSibling = this[0].next;
while (nextSibling) {
if ($.isTag(nextSibling)) return $(nextSibling);
nextSibling = nextSibling.next;
}
return null;
};
var prevSibling = this[0].prev;
while(prevSibling) {
if($.isTag(prevSibling)) return $(prevSibling);
prevSibling = prevSibling.prev;
}
};
prev = exports.prev = function(elem) {
var prevSibling;
if (!this[0]) return null;
prevSibling = this[0].prev;
while (prevSibling) {
if ($.isTag(prevSibling)) return $(prevSibling);
prevSibling = prevSibling.prev;
}
return null;
};
var siblings = exports.siblings = function(elem) {
if(!this[0]) return null;
siblings = exports.siblings = function(elem) {
var sibs;
var _this = this;
if (this.parent()) {
sibs = this.parent().children();
} else {
sibs = this.siblingsAndMe();
}
siblings = _.filter(sibs, function(elem) {
return elem !== _this[0] && $.isTag(elem);
});
return $(siblings);
};
var self = this,
siblings = (this.parent()) ? this.parent().children()
: this.siblingsAndMe();
children = exports.children = function(selector) {
if (this[0] && this[0].children) {
children = _.filter(this[0].children, function(elem) {
return $.isTag(elem);
});
if (selector !== void 0) {
if (_.isNumber(selector)) {
if (children[selector]) {
return $(children[selector]);
} else {
return null;
}
} else {
return $(children).find(selector);
}
}
return $(children);
} else {
return null;
}
};
siblings = _.filter(siblings, function(elem) {
return (elem !== self[0] && $.isTag(elem));
});
each = exports.each = function(callback, args) {
return $.each(this, callback, args);
};
return $(siblings);
};
module.exports = $.fn.extend(exports);
var children = exports.children = function(selector) {
if(!this[0] || !this[0].children) return null;
}).call(this);
var children = _.filter(this[0].children, function(elem) {
return ($.isTag(elem));
});
if(selector === undefined) return $(children);
else if(_.isNumber(selector)) return $(children[selector]);
return $(children).find(selector);
};
var each = exports.each = function(callback, args) {
return $.each(this, callback, args);
};
module.exports = $.fn.extend(exports);

@@ -1,243 +0,285 @@

(function() {
var $, access, attr, class2type, dom, each, html, inArray, indexOf, isArray, isTag, load, makeArray, merge, parse, push, rboolean, removeAttr, render, tags, text, toString, type, updateDOM, _;
/*
Module Dependencies
*/
var _ = require("underscore"),
$ = require("../cheerio"),
parse = require("../parse"),
render = require("../render"),
utils = require('../utils'),
isTag = utils.isTag;
var class2type = {},
types = 'Boolean Number String Function Array Date Regex Object',
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
toString = Object.prototype.toString,
push = Array.prototype.push,
indexOf = Array.prototype.indexOf,
tags = { tag : 1, script : 1, style : 1 };
_ = require("underscore");
/*
Node Types
directive : 10
comment : 8
script : 1
style : 1
text : 3
tag : 1
*/
$ = require("../cheerio");
// Fill in class2type
_.each(types.split(' '), function(name) {
class2type['[object '+ name +']'] = name.toLowerCase();
});
parse = require("../parse");
exports.isTag = isTag;
render = require("../render");
var updateDOM = exports.updateDOM = function(arr, parent) {
// normalize
arr = $(arr).get();
// Update neighbors
for(var i = 0; i < arr.length; i++) {
arr[i].prev = arr[i-1] || null;
arr[i].next = arr[i+1] || null;
arr[i].parent = parent || null;
}
// Update parent
parent.children = arr;
return parent;
};
class2type = {};
var type = exports.type = function(obj) {
if(obj === null)
return String(obj);
else
return class2type[toString.call(obj)] || 'object';
};
_.each("Boolean Number String Function Array Date Regex Object".split(" "), function(name, i) {
return class2type["[object " + name + "]"] = name.toLowerCase();
});
var isArray = exports.isArray = function(array) {
return _(this).isArray();
};
/*
Node Types
directive : 10
comment : 8
script : 1
style : 1
text : 3
tag : 1
*/
var merge = exports.merge = function( first, second ) {
var i = first.length,
j = 0;
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i;
if ( typeof second.length === "number" ) {
for ( var l = second.length; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
toString = Object.prototype.toString;
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
push = Array.prototype.push;
first.length = i;
indexOf = Array.prototype.indexOf;
return first;
};
tags = {
'tag': 1,
'script': 1,
'style': 1
};
var makeArray = exports.makeArray = function( array, results ) {
var ret = results || [],
type = $.type(array);
if(!array) return ret;
isTag = exports.isTag = function(type) {
if (type.type) type = type.type;
if (tags[type]) {
return true;
} else {
return false;
}
};
if ( array.length == null || type === "string" || type === "function" || type === "regexp") {
push.call( ret, array );
} else {
merge( ret, array );
}
return ret;
};
updateDOM = exports.updateDOM = function(arr, parent) {
var elem, i, _len;
arr = $(arr).get();
for (i = 0, _len = arr.length; i < _len; i++) {
elem = arr[i];
arr[i].prev = arr[i - 1] || null;
arr[i].next = arr[i + 1] || null;
arr[i].parent = parent || null;
}
if (!parent.children) parent.children = [];
parent.children = arr;
return parent;
};
var inArray = exports.inArray = function( elem, array, i ) {
var len;
type = exports.type = function(obj) {
if (obj === null) {
return String(obj);
} else {
return class2type[toString.call(obj)] || "object";
}
};
if ( array ) {
if ( indexOf ) {
return indexOf.call( array, elem, i );
}
isArray = exports.isArray = function(array) {
return _(this).isArray();
};
len = array.length;
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
merge = exports.merge = function(first, second) {
var i, j, l;
i = first.length;
j = 0;
if (typeof second.length === "number") {
l = second.length;
while (j < l) {
first[i++] = second[j];
j++;
}
} else {
while (second[j] !== void 0) {
first[i++] = second[j++];
}
}
first.length = i;
return first;
};
for ( ; i < len; i++ ) {
// Skip accessing in sparse arrays
if ( i in array && array[ i ] === elem ) {
return i;
}
}
}
makeArray = exports.makeArray = function(array, results) {
var ret;
ret = results || [];
if (array) {
type = $.type(array);
if (!(array.length != null) || type === "string" || type === "function" || type === "regexp") {
push.call(ret, array);
} else {
$.merge(ret, array);
}
}
return ret;
};
return -1;
};
inArray = exports.inArray = function(elem, array) {
if (!array) return -1;
return indexOf.call(array, elem);
};
// args is for internal usage only
var each = exports.each = function( object, callback, args ) {
var name, i = 0,
length = object.length,
isObj = length === undefined || _.isFunction( object );
each = exports.each = function(object, callback, args) {
var i, isObj, length, name;
length = object.length;
i = 0;
isObj = length === void 0 || _.isFunction(object);
if (args) {
if (isObj) {
for (name in object) {
if (callback.apply(object[name], args) === false) break;
}
} else {
while (i < length) {
if (callback.apply(object[i++], args) === false) break;
}
}
} else {
if (isObj) {
for (name in object) {
if (callback.call(object[name], name, object[name]) === false) break;
}
} else {
while (i < length) {
if (callback.call(object[i], i, object[i++]) === false) break;
}
}
}
return object;
};
if ( args ) {
if ( isObj ) {
for ( name in object ) {
if ( callback.apply( object[ name ], args ) === false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.apply( object[ i++ ], args ) === false ) {
break;
}
}
}
access = exports.access = function(elems, key, value, exec, fn, pass) {
var i, k, length;
length = elems.length;
if (typeof key === "object") {
for (k in key) {
access(elems, k, key[k], exec, fn, value);
}
return elems;
}
if (value !== void 0) {
exec = !pass && exec && _.isFunction(value);
i = 0;
while (i < length) {
fn(elems[i], key, (exec ? value.call(elems[i], i, fn(elems[i], key)) : value), pass);
i++;
}
return elems;
}
return (length ? fn(elems[0], key) : void 0);
};
// A special, fast, case for the most common use of each
} else {
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
break;
}
}
}
}
attr = exports.attr = function(elem, name, value, pass) {
type = elem.type;
if (!elem || !$.isTag(elem)) return;
if (!elem.attribs) elem.attribs = {};
if (!name) return elem.attribs;
if (value !== void 0) {
if (value === null) {
return $.removeAttr(elem, name);
} else {
return elem.attribs[name] = "" + value;
}
return object;
};
// Mutifunctional method to get and set values to a collection
// The value/s can optionally be executed if it's a function
var access = exports.access = function( elems, key, value, exec, fn, pass ) {
var length = elems.length;
// Setting many attributes
if ( typeof key === "object" ) {
for ( var k in key ) {
access( elems, k, key[k], exec, fn, value );
}
return elems;
}
// Setting one attribute
if ( value !== undefined ) {
// Optionally, function values get executed if exec is true
exec = !pass && exec && _.isFunction(value);
for ( var i = 0; i < length; i++ ) {
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
}
return elems;
}
// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
};
var attr = exports.attr = function( elem, name, value, pass ) {
var type = elem.type;
if (!elem || !isTag(elem))
return undefined;
if (!elem.attribs) {
elem.attribs = {};
}
// Return the entire attribs object if no attribute specified
if (!name) {
return elem.attribs;
}
if (value !== undefined) {
if (value === null) {
// Remove the attribute
$.removeAttr(elem, name);
} else {
return elem.attribs[name];
// Set the attribute
elem.attribs[name] = "" + value;
}
};
} else {
// Get the attributes
return elem.attribs[name];
}
};
removeAttr = exports.removeAttr = function(elem, name) {
if (isTag(elem.type) && elem.attribs) {
if (elem.attribs[name]) {
if (rboolean.test(elem.attribs[name])) {
return elem.attribs[name] = false;
} else {
return delete elem.attribs[name];
}
}
}
};
var removeAttr = exports.removeAttr = function(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];
};
text = exports.text = function(elems) {
var elem, ret, _i, _len;
ret = "";
if (!elems) return ret;
for (_i = 0, _len = elems.length; _i < _len; _i++) {
elem = elems[_i];
if (elem.type === "text") {
ret += elem.data;
} else if (elem.children && elem.type !== "comment") {
ret += text(elem.children);
}
}
return ret;
};
var text = exports.text = function(elems) {
if (!elems) return '';
load = exports.load = function(html) {
var fn, root;
root = parse(html);
$.extend({
'root': root
});
fn = function(selector, context, r) {
if (r) root = parse(r);
return $(selector, context, root);
};
return _(fn).extend($);
};
var ret = "",
len = elems.length,
elem;
html = exports.html = function(dom) {
if (dom !== void 0 && dom.type) {
return render(dom);
} else if (this.root && this.root.children) {
return render(this.root.children);
} else {
return "";
for(var i = 0; i < len; i ++) {
elem = elems[i];
if(elem.type === 'text') ret += elem.data;
else if(elem.children && elem.type !== 'comment') {
ret += text(elem.children);
}
};
}
return ret;
};
dom = exports.dom = function(dom) {
if (dom !== void 0) {
if (dom.type) return dom;
} else if (this.root && this.root.children) {
return this.root.children;
} else {
return "";
var load = exports.load = function(html) {
var root = parse(html);
function fn(selector, context, r) {
if (r) {
root = parse(r);
}
};
return $(selector, context, root);
}
$.extend({
'root': root
});
return _(fn).extend($);
};
module.exports = $.extend(exports);
var html = exports.html = function(dom) {
if (dom !== undefined && dom.type) {
return render(dom);
} else if (this.root && this.root.children) {
return render(this.root.children);
} else {
return "";
}
};
}).call(this);
var dom = exports.dom = function(dom) {
if (dom && dom.type) {
return dom;
} else if (this.root && this.root.children) {
return this.root.children;
} else {
return "";
}
};
module.exports = $.extend(exports);

@@ -1,86 +0,99 @@

(function() {
var api, cheerio, parse, path, plugin, soupselect, _, _i, _len;
path = require("path");
soupselect = require("cheerio-soupselect");
_ = require("underscore");
parse = require("./parse");
cheerio = (function() {
var quickExpr, trimLeft, trimRight;
cheerio = function(selector, context, root) {
return new cheerio.fn.init(selector, context, root);
};
quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
trimLeft = /^\s+/;
trimRight = /\s+$/;
cheerio.fn = cheerio.prototype = {
cheerio: "0.4.2",
constructor: cheerio,
init: function(selector, context, root) {
var elems, match;
if (!selector) return this;
if (root) {
cheerio.extend({
'root': root
});
if (_.isString(context)) selector = "" + context + " " + selector;
context = root;
/*
Module dependencies
*/
var path = require('path'),
soupselect = require('cheerio-soupselect'),
_ = require('underscore'),
parse = require('./parse');
var cheerio = (function() {
var cheerio = function(selector, context, root) {
return new cheerio.fn.init(selector, context, root);
};
// A simple way to check for HTML strings or ID strings
// Prioritize #id over <tag>
var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
cheerio.fn = cheerio.prototype = {
cheerio : '[cheerio object]',
constructor : cheerio,
init : function(selector, context, root) {
// Handle $(''), $(null), and $(undefined)
if(!selector) return this;
// Handle the root
if(root) {
cheerio.extend({ 'root' : root });
if(typeof context === 'string')
selector = context + ' ' + selector;
context = root;
}
// Handle strings
if(typeof selector === 'string') {
var match = null;
// Handle HTML strings
if (selector.charAt(0) === "<"
&& selector.charAt(selector.length - 1) === ">"
&& selector.length >= 3) {
match = [null, selector, null];
} else {
match = quickExpr.exec(selector);
}
if (typeof selector === "string") {
if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) {
match = [null, selector, null];
} else {
match = quickExpr.exec(selector);
if (match && (match[1] || !context)) {
if (match[1]) {
// HTML String
root = parse(selector);
return cheerio.merge(this, root.children);
} else if (context) {
// Classes, IDs, just defer to soupselect
var elems = soupselect.select(context, selector);
this.selector = selector;
return cheerio.merge(this, elems);
}
if (match && (match[1] || !context)) {
if (match[1]) {
root = parse(selector);
return cheerio.merge(this, root.children);
} else if (context) {
elems = soupselect.select(context, selector);
this.selector = selector;
return cheerio.merge(this, elems);
}
}
if(!context || context.cheerio) {
// HANDLE : $(expr, $(...))
return this.constructor(context || root).find(selector);
}
else {
// HANDLE : $(expr, context)
if(typeof context === 'string') {
context = parse(context);
}
/*
Refactor
*/
if (!context || context.cheerio) {
return this.constructor(context || root).find(selector);
} else {
if (_.isString(context)) context = parse(context);
return this.constructor(context).find(selector);
}
return this.constructor(context).find(selector);
}
return cheerio.makeArray(selector, this);
},
selector: "",
sort: [].sort,
splice: [].splice,
length: 0
};
cheerio.fn.init.prototype = cheerio.fn;
cheerio.extend = cheerio.fn.extend = function(obj) {
return _.extend(this, obj);
};
return cheerio;
})();
}
return cheerio.makeArray(selector, this);
},
selector : '',
sort : [].splice,
length : 0
};
cheerio.fn.init.prototype = cheerio.fn;
// Use underscores extend
cheerio.extend = cheerio.fn.extend = function (obj) {
return _.extend(this, obj);
};
module.exports = cheerio;
return cheerio;
})();
/*
Plug in the API
*/
module.exports = cheerio;
api = ['core', 'utils', 'attributes', 'traversing', 'manipulation'];
for (_i = 0, _len = api.length; _i < _len; _i++) {
plugin = api[_i];
require("./api/" + plugin);
}
}).call(this);
/*
Plug in the API
*/
var api = 'core utils attributes traversing manipulation';
api.split(' ').forEach(function(plugin) {
require('./api/' + plugin);
});

@@ -1,72 +0,78 @@

(function() {
var connect, eval, exports, htmlparser, isTag, parser;
/*
Module Dependencies
*/
var htmlparser = require('htmlparser2'),
utils = require('./utils'),
isTag = utils.isTag;
htmlparser = require("htmlparser2");
/*
Parser
*/
var parser = exports = module.exports = function(content) {
var dom = eval(content),
root = {
type : 'root',
name : 'root',
parent : null,
prev : null,
next : null,
children : []
};
root.children = connect(dom, root);
return root;
};
/*
parser
*/
var eval = exports.eval = function(content) {
var handler = new htmlparser.DefaultHandler({
ignoreWhitespace: true
}),
parser = new htmlparser.Parser(handler);
parser.includeLocation = false;
parser.parseComplete(content);
return handler.dom;
};
parser = exports = module.exports = function(content) {
var dom, root;
dom = eval(content);
root = {
type: 'root',
name: 'root',
parent: null,
prev: null,
next: null,
children: []
};
root.children = connect(dom, root);
return root;
};
var connect = exports.connect = function(dom, parent) {
parent = parent || null;
var prevIndex = -1,
lastElem = null,
len = dom.length;
for(var i = 0; i < len; i++) {
// If tag and no attributes, add empty object
if(isTag(dom[i].type) && dom[i].attribs === undefined)
dom[i].attribs = {};
// Set parent
dom[i].parent = parent;
// Previous Sibling
dom[i].prev = dom[prevIndex] || null;
// Next sibling
dom[i].next = null;
if(lastElem) lastElem.next = dom[i];
// Run through the children
if(dom[i].children)
connect(dom[i].children, dom[i]);
else if(isTag(dom[i].type))
dom[i].children = [];
// Get ready for next element
prevIndex = i;
lastElem = dom[i];
}
return dom;
};
eval = exports.eval = function(content) {
var handler;
handler = new htmlparser.DefaultHandler();
parser = new htmlparser.Parser(handler);
parser.includeLocation = false;
parser.parseComplete(content);
return handler.dom;
};
module.exports = exports;
isTag = function(type) {
if (type === 'tag' || type === 'script' || type === 'style') {
return true;
} else {
return false;
}
};
connect = exports.connect = function(dom, parent) {
var elem, i, lastElem, prev, prevIndex, _len;
if (parent == null) parent = null;
prevIndex = -1;
lastElem = null;
for (i = 0, _len = dom.length; i < _len; i++) {
elem = dom[i];
if (isTag(dom[i].type) && dom[i].attribs === void 0) dom[i].attribs = {};
dom[i].parent = parent;
prev = dom[prevIndex];
if (prev) {
dom[i].prev = prev;
} else {
dom[i].prev = null;
}
dom[i].next = null;
if (lastElem) lastElem.next = dom[i];
if (dom[i].children) {
connect(dom[i].children, dom[i]);
} else if (isTag(dom[i].type)) {
dom[i].children = [];
}
prevIndex = i;
lastElem = dom[i];
}
return dom;
};
module.exports = exports;
}).call(this);

@@ -1,87 +0,98 @@

(function() {
var exports, render, renderComment, renderDirective, renderTag, renderText, singleTag, tagType, utils, _;
/*
Module dependencies
*/
var _ = require('underscore'),
utils = require('./utils');
/*
Self-enclosing tags (stolen from node-htmlparser)
*/
var singleTag = {
area: 1,
base: 1,
basefont: 1,
br: 1,
col: 1,
frame: 1,
hr: 1,
img: 1,
input: 1,
isindex: 1,
link: 1,
meta: 1,
param: 1,
embed: 1,
include: 1,
yield: 1
};
_ = require("underscore");
/*
Tag types from htmlparser
*/
var tagType = {
tag : 1,
script : 1,
link : 1,
style : 1,
template : 1
};
utils = require("./utils");
var render = exports = module.exports = function(dom, output) {
output = output || [];
if(!_.isArray(dom)) dom = [dom];
var len = dom.length,
elem;
for(var i = 0; i < len; i++) {
elem = dom[i];
if(tagType[elem.type])
output.push(renderTag(elem));
else if(elem.type === 'directive')
output.push(renderDirective(elem));
else if(elem.type === 'comment')
output.puhs(renderComment(elem));
else
output.push(renderText(elem));
if(elem.children)
output.push(render(elem.children));
if(!singleTag[elem.name] && tagType[elem.type])
output.push("</" + elem.name + ">");
}
return output.join('');
};
singleTag = {
area: 1,
base: 1,
basefont: 1,
br: 1,
col: 1,
frame: 1,
hr: 1,
img: 1,
input: 1,
isindex: 1,
link: 1,
meta: 1,
param: 1,
embed: 1,
include: 1,
yield: 1
};
var renderTag = exports.renderTag = function(elem) {
var tag = '<' + elem.name;
if(elem.attribs && _.size(elem.attribs)) {
tag += ' ' + utils.formatAttrs(elem.attribs);
}
if(!singleTag[elem.name]) {
tag += '>';
} else {
tag = tag.trim().replace(/\/$/, '');
tag += '/>';
}
tagType = {
tag: 1,
script: 1,
link: 1,
style: 1,
template: 1
};
return tag;
};
render = exports = module.exports = function(dom, output) {
var elem, str, _i, _len;
if (output == null) output = [];
if (!_.isArray(dom)) dom = [dom];
for (_i = 0, _len = dom.length; _i < _len; _i++) {
elem = dom[_i];
str = elem.name;
if (tagType[elem.type]) {
output.push(renderTag(elem));
} else if (elem.type === "directive") {
output.push(renderDirective(elem));
} else if (elem.type === "comment") {
output.push(renderComment(elem));
} else {
output.push(renderText(elem));
}
if (elem.children) output.push(render(elem.children));
if (!singleTag[elem.name] && tagType[elem.type]) {
output.push("</" + elem.name + ">");
}
}
return output.join("");
};
var renderDirective = exports.renderDirective = function(elem) {
return "<" + elem.data + ">";
};
renderTag = exports.renderTag = function(elem) {
var tag;
tag = "<" + elem.name;
if (elem.attribs && _.size(elem.attribs) > 0) {
tag += " " + utils.formatAttributes(elem.attribs);
}
if (!singleTag[elem.name]) {
tag += ">";
} else {
tag += "/>";
}
return tag;
};
var renderText = exports.renderText = function(elem) {
return elem.data;
};
renderDirective = function(elem) {
return "<" + elem.data + ">";
};
var renderComment = exports.renderComment = function(elem) {
return '<!--' + elem.data + '-->';
};
renderText = function(elem) {
return elem.data;
};
renderComment = function(elem) {
return '<!--' + elem.data + '-->';
};
module.exports = exports;
}).call(this);
module.exports = exports;

@@ -1,72 +0,51 @@

(function() {
var formatAttributes, print, print_r;
/*
Boolean Attributes
*/
var booleanAttributes = {
checked: true,
selected: true,
disabled: true,
readonly: true,
multiple: true,
ismap: true,
defer: true,
declare: true,
noresize: true,
nowrap: true,
noshade: true,
compact: true
};
formatAttributes = exports.formatAttributes = function(attributes) {
var key, output, value;
if (!attributes) return "";
output = [];
for (key in attributes) {
value = attributes[key];
if (key === value) {
output.push(key);
} else {
output.push(key + ' = "' + value + '"');
}
}
return output.join(" ");
};
/*
Tags
*/
var tags = { tag : true, script : true, style : true };
module.exports = exports;
/*
isTag(type) includes <script> and <style> tags
*/
var isTag = exports.isTag = function(type) {
if(type.type) type = type.type;
return tags[type] || false;
};
String.prototype.repeat = function(times) {
return new Array(times + 1).join(this);
};
print = exports.print = function(dom, attr, depth, out) {
var attrs, elem, passback, prop, str, type, val, _i, _j, _len, _len2;
if (attr == null) attr = null;
if (depth == null) depth = 0;
if (out == null) out = [];
for (_i = 0, _len = dom.length; _i < _len; _i++) {
elem = dom[_i];
type = elem.type;
if (type === "tag" || type === "script" || type === "style") continue;
str = '–'.repeat(depth);
if (depth > 0) {
str += str + " " + elem.name;
} else {
str += elem.name;
}
if (attr) {
attrs = attr.split(".");
val = elem;
passback = true;
for (_j = 0, _len2 = attrs.length; _j < _len2; _j++) {
prop = attrs[_j];
val = val[prop];
if (!val) {
passback = false;
break;
}
}
if (passback) str += " ( " + attr + " : " + val + " )";
}
out.push(str);
if (elem.children) print(elem.children, attr, depth + 1, out);
var formatAttrs = exports.formatAttrs = function(attributes) {
if(!attributes) return '';
var output = [],
value;
// Loop through the attributes
for (var key in attributes) {
value = attributes[key];
if (key === value && (booleanAttributes[key] || key === '/')) {
output.push(key);
} else {
output.push(key + ' = "' + value + '"');
}
return out.join("\n");
};
}
return output.join(' ');
};
print_r = exports.print_r = function(arr, attr) {
var attributes, out;
if (attr == null) attr = "name";
out = "[ ";
attributes = arr.map(function(elem) {
return elem[attr];
});
out += attributes.join(", ");
out += " ]";
return out;
};
}).call(this);
module.exports = exports;

@@ -6,3 +6,3 @@ {

"keywords": ["htmlparser", "jquery", "selector", "scraper"],
"version": "0.4.2",
"version": "0.5.0",
"repository": {

@@ -23,8 +23,5 @@ "type": "git",

"mocha" : "0.x",
"should" : "*"
},
"scripts": {
"prepublish": "coffee -o lib/ src/",
"test": "coffee -o lib/ src/ && vows tests/test.cheerio.coffee --spec"
"should" : "*",
"coffee-script": "*"
}
}

@@ -10,3 +10,3 @@ # cheerio

$ = cheerio.load("<h2 class = 'title'>Hello world</h2>");
$('h2.title').text('Hello there!');

@@ -28,3 +28,3 @@ $('h2').addClass('welcome');

__&#10084; Familiar syntax:__
Cheerio implements a subset of core jQuery. Cheerio removes all the DOM inconsistencies and browser cruft from the jQuery library, revealing its truly gorgeous API.
Cheerio implements a subset of core jQuery. Cheerio removes all the DOM inconsistencies and browser cruft from the jQuery library, revealing its truly gorgeous API.

@@ -63,6 +63,6 @@ __&#991; Blazingly fast:__

### Loading
First you need to load in the HTML. This step in jQuery is implicit, since jQuery operates on the one, baked-in DOM. With Cheerio, we need to pass in the HTML document.
First you need to load in the HTML. This step in jQuery is implicit, since jQuery operates on the one, baked-in DOM. With Cheerio, we need to pass in the HTML document.
This is the _preferred_ method:
var cheerio = require('cheerio'),

@@ -85,19 +85,18 @@ $ = cheerio.load('<ul id = "fruits">...</ul>');

#### $( selector, [context], [root] )
`selector` searches within the `context` scope which searches within the `root` scope. `selector` and `context` can be an string expression, DOM Element, array of DOM elements, or cheerio object. `root` is typically the HTML document string.
`selector` searches within the `context` scope which searches within the `root` scope. `selector` and `context` can be an string expression, DOM Element, array of DOM elements, or cheerio object. `root` is typically the HTML document string.
This selector method is the starting point for traversing and manipulating the document. Like jQuery, it's the primary method for selecting elements in the document, but unlike jQuery it's built on top of the soup-select library, not the Sizzle engine.
This selector method is the starting point for traversing and manipulating the document. Like jQuery, it's the primary method for selecting elements in the document, but unlike jQuery it's built on top of the soup-select library, not the Sizzle engine.
$(".apple", '#fruits').text()
=> Apple
$('ul .pear').attr('class')
=> pear
$('li[class=orange]').html()
=> <li class = "orange">Orange</li>
> See https://github.com/harryf/node-soupselect for all available selectors
See [cheerio-soupselect]("https://github.com/MatthewMueller/cheerio-soupselect") for a list of all available selectors,
as well as more detailed documentation regarding what is supported and what isn't.
> See http://api.jquery.com/jQuery/ for more information
### Attributes

@@ -107,3 +106,3 @@ Methods for getting and modifying attributes.

#### .attr( name, value )
Method for getting and setting attributes. Gets the attribute value for only the first element in the matched set. If you set an attribute's value to `null`, you remove that attribute. You may also pass a `map` and `function` like jQuery.
Method for getting and setting attributes. Gets the attribute value for only the first element in the matched set. If you set an attribute's value to `null`, you remove that attribute. You may also pass a `map` and `function` like jQuery.

@@ -135,3 +134,3 @@ $('ul').attr('id')

=> true
#### .addClass( className )

@@ -156,3 +155,3 @@ Adds class(es) to all of the matched elements. Also accepts a `function` like jQuery.

=> <li class = "">Apple</li>
> See http://api.jquery.com/removeClass/ for more information.

@@ -180,3 +179,3 @@

=> true
#### .prev()

@@ -193,3 +192,3 @@ Gets the previous sibling thats an element of the first selected element.

=> 2
#### .children( selector )

@@ -200,3 +199,3 @@ Gets the children of the first selected element.

=> 3
$('#fruits').children('.pear').text()

@@ -209,7 +208,7 @@ => Pear

var fruits = [];
$('li').each(function(i, elem) {
fruits[i] = $(this).text();
});
fruits.join(', ');

@@ -245,5 +244,5 @@ => Apple, Orange, Pear

</ul>
#### .after( content, [content, ...] )
Insert content next to each element in the set of matched elements.
Insert content next to each element in the set of matched elements.

@@ -258,5 +257,5 @@ $('.apple').after('<li class = "plum">Plum</li>')

</ul>
#### .before( content, [content, ...] )
Insert content previous to each element in the set of matched elements.
Insert content previous to each element in the set of matched elements.

@@ -281,3 +280,3 @@ $('.apple').before('<li class = "plum">Plum</li>')

</ul>
#### .empty()

@@ -289,3 +288,3 @@ Empties an element, removing all it's children.

=> <ul id = "fruits"></ul>
#### .html( [htmlString] )

@@ -296,3 +295,3 @@ Gets an html content string from the first selected element. If `htmlString` is specified, each selected element's content is replaced by the new content.

=> <li class = "orange">Orange</li>
$('#fruits').html('<li class = "mango">Mango</li>').html()

@@ -302,3 +301,3 @@ => <ul id="fruits">

</ul>
#### .text( [textString] )

@@ -309,3 +308,3 @@ Get the combined text contents of each element in the set of matched elements, including their descendants.. If `textString` is specified, each selected element's content is replaced by the new text content.

=> Orange
$('ul').text()

@@ -330,3 +329,3 @@ => Apple

=> <li class = "pear">Pear</li>
### Miscellaneous
### Miscellaneous
DOM element methods that don't fit anywhere else

@@ -339,6 +338,6 @@

=> { raw: 'li class="apple"', ... }
$('li').get()
=> [ {...}, {...}, {...} ]
#### .size()

@@ -349,3 +348,3 @@ Return the number of elements in the cheerio object. Same as `length`.

=> 3
#### .toArray()

@@ -367,3 +366,3 @@ Retrieve all the DOM elements contained in the jQuery set, as an array.

attribs: { id: 'fruits' },
children:
children:
[ [Object],

@@ -391,3 +390,3 @@ [Object],

Turns an array-like object (like $) into a native array.
#### $.each( obj, function(index, elem) )

@@ -408,6 +407,6 @@ Generic iterator function.

To run the test suite, download the repository, then within the cheerio directory, run:
npm install
npm test
npm install .
make test
This will download the development packages and run the test suite.

@@ -420,4 +419,4 @@ ## Special Thanks

This HTML parser can parse anything and produces really consistent results, even when the HTML string has errors. This man is a genius.
__&#8226; @harryf's node-soupselect:__
__&#8226; @harryf's node-soupselect:__
What an incredibly fast and precise CSS selector engine. I never really liked the feature-rich selector engines &#8212; I think this engine strikes a great balance.

@@ -430,3 +429,3 @@

The style, the structure, the open-source"-ness" of this library comes from studying TJ's style and using many of his libraries. This dude consistently pumps out high-quality libraries and has always been more than willing to help or answer questions. You rock TJ.
## License
## License

@@ -454,2 +453,2 @@ (The MIT License)

TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

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

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