Socket
Socket
Sign inDemoInstall

cheerio

Package Overview
Dependencies
13
Maintainers
4
Versions
69
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0-rc.5 to 1.0.0-rc.6

lib/load.js

4

History.md

@@ -354,3 +354,3 @@ Starting with 1.0.0-rc.4, release notes are exclusively tracked in

- Fix select with context in Cheerio function (@jugglinmike)
- Remove unecessary DOM maintenance logic (@jugglinmike)
- Remove unnecessary DOM maintenance logic (@jugglinmike)
- Deprecate support for node 0.6

@@ -528,3 +528,3 @@

- Updated CSS parser to use FB55/CSSselect. Cheerio now supports most CSS3 psuedo selectors thanks to @FB55.
- Updated CSS parser to use FB55/CSSselect. Cheerio now supports most CSS3 pseudo selectors thanks to @FB55.
- ignoreWhitespace now on by default again. See #55 for context.

@@ -531,0 +531,0 @@ - Changed $(':root') to $.root(), cleaned up \$.clone()

@@ -0,4 +1,5 @@

'use strict';
/**
* @module cheerio
* @borrows static.load as load
* @borrows load.load as load
* @borrows static.html as html

@@ -8,6 +9,7 @@ * @borrows static.text as text

*/
exports = module.exports = require('./lib/cheerio');
var staticMethods = require('./lib/static');
var loadMethod = require('./lib/load');
exports = module.exports = require('./lib/cheerio');
/**

@@ -20,3 +22,3 @@ * An identifier describing the version of Cheerio which has been executed.

exports.load = staticMethods.load;
exports.load = loadMethod.load;
exports.html = staticMethods.html;

@@ -27,13 +29,13 @@ exports.text = staticMethods.text;

/**
* In order to promote consistency with the jQuery library, users are
* encouraged to instead use the static method of the same name.
* In order to promote consistency with the jQuery library, users are encouraged
* to instead use the static method of the same name.
*
* @deprecated
* @example
* var $ = cheerio.load('<div><p></p></div>');
* $.contains($('div').get(0), $('p').get(0)); // true
* $.contains($('p').get(0), $('div').get(0)); // false
* var $ = cheerio.load('<div><p></p></div>');
* $.contains($('div').get(0), $('p').get(0)); // true
* $.contains($('p').get(0), $('div').get(0)); // false
*
* @function
* @returns {boolean}
* @deprecated
*/

@@ -43,11 +45,11 @@ exports.contains = staticMethods.contains;

/**
* In order to promote consistency with the jQuery library, users are
* encouraged to instead use the static method of the same name.
* In order to promote consistency with the jQuery library, users are encouraged
* to instead use the static method of the same name.
*
* @deprecated
* @example
* var $ = cheerio.load('');
* $.merge([1, 2], [3, 4]) // [1, 2, 3, 4]
* var $ = cheerio.load('');
* $.merge([1, 2], [3, 4]); // [1, 2, 3, 4]
*
* @function
* @deprecated
*/

@@ -57,12 +59,12 @@ exports.merge = staticMethods.merge;

/**
* In order to promote consistency with the jQuery library, users are
* encouraged to instead use the static method of the same name as it is
* defined on the "loaded" Cheerio factory function.
* In order to promote consistency with the jQuery library, users are encouraged
* to instead use the static method of the same name as it is defined on the
* "loaded" Cheerio factory function.
*
* @deprecated See {@link static/parseHTML}.
* @example
* var $ = cheerio.load('');
* $.parseHTML('<b>markup</b>');
* var $ = cheerio.load('');
* $.parseHTML('<b>markup</b>');
*
* @function
* @deprecated See {@link static/parseHTML}.
*/

@@ -75,9 +77,9 @@ exports.parseHTML = staticMethods.parseHTML;

*
* @deprecated
* @example
* var $ = cheerio.load('');
* $.root();
* var $ = cheerio.load('');
* $.root();
*
* @function
* @deprecated
*/
exports.root = staticMethods.root;

@@ -0,1 +1,2 @@

'use strict';
/**

@@ -26,5 +27,16 @@ * Methods for getting and modifying attributes.

// Matches strings that look like JSON objects or arrays
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/;
var rbrace = /^(?:{[\w\W]*}|\[[\w\W]*])$/;
var getAttr = function (elem, name) {
/**
* Gets a node's attribute. For boolean attributes, it will return the value's
* name should it be set.
*
* Also supports getting the `value` of several form elements.
*
* @private
* @param {Element} elem - Elenent to get the attribute of.
* @param {string} name - Name of the attribute.
* @returns {object | string | undefined} The attribute's value.
*/
function getAttr(elem, name) {
if (!elem || !isTag(elem)) return;

@@ -59,5 +71,13 @@

}
};
}
var setAttr = function (el, name, value) {
/**
* Sets the value of an attribute. The attribute will be deleted if the value is `null`.
*
* @private
* @param {Element} el - The element to set the attribute on.
* @param {string} name - The attribute's name.
* @param {string | null} value - The attribute's value.
*/
function setAttr(el, name, value) {
if (value === null) {

@@ -68,3 +88,3 @@ removeAttribute(el, name);

}
};
}

@@ -78,13 +98,13 @@ /**

* @example
* $('ul').attr('id');
* //=> fruits
*
* $('ul').attr('id')
* //=> fruits
* $('.apple').attr('id', 'favorite').html();
* //=> <li class="apple" id="favorite">Apple</li>
*
* $('.apple').attr('id', 'favorite').html()
* //=> <li class="apple" id="favorite">Apple</li>
*
* @param {string} name - Name of the attribute.
* @param {string} [value] - If specified sets the value of the attribute.
*
* @see {@link http://api.jquery.com/attr/}
* @param {string | Function} [value] - If specified sets the value of the attribute.
* @returns {string | Cheerio} If `value` is specified the instance itself,
* otherwise the attribute's value.
* @see {@link https://api.jquery.com/attr/}
*/

@@ -113,6 +133,14 @@ exports.attr = function (name, value) {

return getAttr(this[0], name);
return arguments.length > 1 ? this : getAttr(this[0], name);
};
var getProp = function (el, name) {
/**
* Gets a node's prop.
*
* @private
* @param {Node} el - Elenent to get the prop of.
* @param {string} name - Name of the prop.
* @returns {string | undefined} The prop's value.
*/
function getProp(el, name) {
if (!el || !isTag(el)) return;

@@ -125,7 +153,19 @@

: getAttr(el, name);
};
}
var setProp = function (el, name, value) {
el[name] = rboolean.test(name) ? !!value : value;
};
/**
* Sets the value of a prop.
*
* @private
* @param {Element} el - The element to set the prop on.
* @param {string} name - The prop's name.
* @param {string | null} value - The prop's value.
*/
function setProp(el, name, value) {
if (name in el) {
el[name] = value;
} else {
setAttr(el, name, rboolean.test(name) ? (value ? '' : null) : value);
}
}

@@ -137,42 +177,41 @@ /**

* @example
* $('input[type="checkbox"]').prop('checked');
* //=> false
*
* $('input[type="checkbox"]').prop('checked')
* //=> false
* $('input[type="checkbox"]').prop('checked', true).val();
* //=> ok
*
* $('input[type="checkbox"]').prop('checked', true).val()
* //=> ok
*
* @param {string} name - Name of the property.
* @param {any} [value] - If specified set the property to this.
*
* @see {@link http://api.jquery.com/prop/}
* @returns {string | Cheerio} If `value` is specified the instance itself,
* otherwise the prop's value.
* @see {@link https://api.jquery.com/prop/}
*/
exports.prop = function (name, value) {
var i = 0;
var property;
if (typeof name === 'string' && value === undefined) {
switch (name) {
case 'style':
property = this.css();
Object.keys(property).forEach(function (p) {
property[i++] = p;
case 'style': {
var property = this.css();
var keys = Object.keys(property);
keys.forEach(function (p, i) {
property[i] = p;
});
property.length = i;
property.length = keys.length;
break;
return property;
}
case 'tagName':
case 'nodeName':
property = this[0].name.toUpperCase();
break;
return this[0].name.toUpperCase();
case 'outerHTML':
property = this.clone().wrap('<container />').parent().html();
break;
return this.clone().wrap('<container />').parent().html();
case 'innerHTML':
return this.html();
default:
property = getProp(this[0], name);
return getProp(this[0], name);
}
return property;
}

@@ -202,3 +241,11 @@

var setData = function (el, name, value) {
/**
* Sets the value of a data attribute.
*
* @private
* @param {Element} el - The element to set the data attribute on.
* @param {string | object} name - The data attribute's name.
* @param {string | null} value - The data attribute's value.
*/
function setData(el, name, value) {
if (!el.data) {

@@ -208,21 +255,23 @@ el.data = {};

if (typeof name === 'object') return Object.assign(el.data, name);
if (typeof name === 'string' && value !== undefined) {
if (typeof name === 'object') Object.assign(el.data, name);
else if (typeof name === 'string' && value !== undefined) {
el.data[name] = value;
}
};
}
// Read the specified attribute from the equivalent HTML5 `data-*` attribute,
// and (if present) cache the value in the node's internal data store. If no
// attribute name is specified, read *all* HTML5 `data-*` attributes in this
// manner.
var readData = function (el, name) {
/**
* Read the specified attribute from the equivalent HTML5 `data-*` attribute,
* and (if present) cache the value in the node's internal data store. If no
* attribute name is specified, read *all* HTML5 `data-*` attributes in this manner.
*
* @private
* @param {Element} el - Elenent to get the data attribute of.
* @param {string} [name] - Name of the data attribute.
* @returns {any} The data attribute's value, or a map with all of the data attribute.
*/
function readData(el, name) {
var readAll = arguments.length === 1;
var domNames;
var domName;
var jsNames;
var jsName;
var value;
var idx;
var length;

@@ -241,5 +290,5 @@ if (readAll) {

for (idx = 0, length = domNames.length; idx < length; ++idx) {
domName = domNames[idx];
jsName = jsNames[idx];
for (var idx = 0; idx < domNames.length; ++idx) {
var domName = domNames[idx];
var jsName = jsNames[idx];
if (hasOwn.call(el.attribs, domName) && !hasOwn.call(el.data, jsName)) {

@@ -265,3 +314,3 @@ value = el.attribs[domName];

return readAll ? el.data : value;
};
}

@@ -273,17 +322,17 @@ /**

* @example
* $('<div data-apple-color="red"></div>').data();
* //=> { appleColor: 'red' }
*
* $('<div data-apple-color="red"></div>').data()
* //=> { appleColor: 'red' }
* $('<div data-apple-color="red"></div>').data('apple-color');
* //=> 'red'
*
* $('<div data-apple-color="red"></div>').data('apple-color')
* //=> 'red'
* const apple = $('.apple').data('kind', 'mac');
* apple.data('kind');
* //=> 'mac'
*
* const apple = $('.apple').data('kind', 'mac')
* apple.data('kind')
* //=> 'mac'
*
* @param {string} name - Name of the attribute.
* @param {any} [value] - If specified new value.
*
* @see {@link http://api.jquery.com/data/}
* @returns {string | Cheerio | undefined} If `value` is specified the instance
* itself, otherwise the data attribute's value.
* @see {@link https://api.jquery.com/data/}
*/

@@ -310,3 +359,4 @@ exports.data = function (name, value) {

return this;
} else if (hasOwn.call(elem.data, name)) {
}
if (hasOwn.call(elem.data, name)) {
return elem.data[name];

@@ -323,12 +373,12 @@ }

* @example
* $('input[type="text"]').val();
* //=> input_text
*
* $('input[type="text"]').val()
* //=> input_text
* $('input[type="text"]').val('test').html();
* //=> <input type="text" value="test"/>
*
* $('input[type="text"]').val('test').html()
* //=> <input type="text" value="test"/>
*
* @param {string} [value] - If specified new value.
*
* @see {@link http://api.jquery.com/val/}
* @param {string | string[]} [value] - If specified new value.
* @returns {string | Cheerio | undefined} If a new `value` is specified the
* instance itself, otherwise the value.
* @see {@link https://api.jquery.com/val/}
*/

@@ -344,22 +394,10 @@ exports.val = function (value) {

return this.text(value);
case 'input':
if (this.attr('type') === 'radio') {
if (querying) {
return this.attr('value');
}
this.attr('value', value);
return this;
}
return this.attr('value', value);
case 'select':
case 'select': {
var option = this.find('option:selected');
var returnValue;
if (option === undefined) return undefined;
if (!option) return;
if (!querying) {
if (!hasOwn.call(this.attr(), 'multiple') && typeof value == 'object') {
if (this.attr('multiple') == null && typeof value === 'object') {
return this;
}
if (typeof value != 'object') {
if (typeof value !== 'object') {
value = [value];

@@ -373,16 +411,12 @@ }

}
returnValue = option.attr('value');
if (hasOwn.call(this.attr(), 'multiple')) {
returnValue = [];
domEach(option, function (__, el) {
returnValue.push(getAttr(el, 'value'));
});
}
return returnValue;
return this.attr('multiple')
? option.toArray().map(function (el) {
return getAttr(el, 'value');
})
: option.attr('value');
}
case 'input':
case 'option':
if (!querying) {
this.attr('value', value);
return this;
}
return this.attr('value');
return querying ? this.attr('value') : this.attr('value', value);
}

@@ -395,21 +429,20 @@ };

* @private
* @param {node} elem - Node to remove attribute from.
* @param {Element} elem - Node to remove attribute from.
* @param {string} name - Name of the attribute to remove.
*/
var removeAttribute = function (elem, name) {
function removeAttribute(elem, name) {
if (!elem.attribs || !hasOwn.call(elem.attribs, name)) return;
delete elem.attribs[name];
};
}
/**
* Splits a space-separated list of names to individual
* names.
* Splits a space-separated list of names to individual names.
*
* @param {string} names - Names to split.
* @param {string} names - Names to split.
* @returns {string[]} - Split names.
*/
var splitNames = function (names) {
function splitNames(names) {
return names ? names.trim().split(rspace) : [];
};
}

@@ -420,13 +453,12 @@ /**

* @example
* $('.pear').removeAttr('class').html();
* //=> <li>Pear</li>
*
* $('.pear').removeAttr('class').html()
* //=> <li>Pear</li>
* $('.apple').attr('id', 'favorite');
* $('.apple').removeAttr('id class').html();
* //=> <li>Apple</li>
*
* $('.apple').attr('id', 'favorite')
* $('.apple').removeAttr('id class').html()
* //=> <li>Apple</li>
*
* @param {string} name - Name of the attribute.
*
* @see {@link http://api.jquery.com/removeAttr/}
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/removeAttr/}
*/

@@ -437,3 +469,3 @@ exports.removeAttr = function (name) {

for (var i = 0; i < attrNames.length; i++) {
domEach(this, function (j, elem) {
domEach(this, function (_, elem) {
removeAttribute(elem, attrNames[i]);

@@ -450,26 +482,23 @@ });

* @example
* $('.pear').hasClass('pear');
* //=> true
*
* $('.pear').hasClass('pear')
* //=> true
* $('apple').hasClass('fruit');
* //=> false
*
* $('apple').hasClass('fruit')
* //=> false
* $('li').hasClass('pear');
* //=> true
*
* $('li').hasClass('pear')
* //=> true
*
* @param {string} className - Name of the class.
*
* @see {@link http://api.jquery.com/hasClass/}
* @returns {boolean} Indicates if an element has the given `className`.
* @see {@link https://api.jquery.com/hasClass/}
*/
exports.hasClass = function (className) {
return this.toArray().some(function (elem) {
var attrs = elem.attribs;
var clazz = attrs && attrs['class'];
var clazz = elem.attribs && elem.attribs['class'];
var idx = -1;
var end;
if (clazz && className.length) {
while ((idx = clazz.indexOf(className, idx + 1)) > -1) {
end = idx + className.length;
var end = idx + className.length;

@@ -484,2 +513,4 @@ if (

}
return false;
});

@@ -489,16 +520,14 @@ };

/**
* Adds class(es) to all of the matched elements. Also accepts a `function`
* like jQuery.
* Adds class(es) to all of the matched elements. Also accepts a `function` like jQuery.
*
* @example
* $('.pear').addClass('fruit').html();
* //=> <li class="pear fruit">Pear</li>
*
* $('.pear').addClass('fruit').html()
* //=> <li class="pear fruit">Pear</li>
* $('.apple').addClass('fruit red').html();
* //=> <li class="apple fruit red">Apple</li>
*
* $('.apple').addClass('fruit red').html()
* //=> <li class="apple fruit red">Apple</li>
*
* @param {string} value - Name of new class.
*
* @see {@link http://api.jquery.com/addClass/}
* @param {string | Function} value - Name of new class.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/addClass/}
*/

@@ -526,4 +555,2 @@ exports.addClass = function (value) {

var className = getAttr(this[i], 'class');
var numClasses;
var setClass;

@@ -533,7 +560,6 @@ if (!className) {

} else {
setClass = ' ' + className + ' ';
numClasses = classNames.length;
var setClass = ' ' + className + ' ';
// Check if class already exists
for (var j = 0; j < numClasses; j++) {
for (var j = 0; j < classNames.length; j++) {
var appendClass = classNames[j] + ' ';

@@ -551,22 +577,18 @@ if (setClass.indexOf(' ' + appendClass) < 0) setClass += appendClass;

/**
* Removes one or more space-separated classes from the selected elements. If
* no `className` is defined, all classes will be removed. Also accepts a
* Removes one or more space-separated classes from the selected elements. If no
* `className` is defined, all classes will be removed. Also accepts a
* `function` like jQuery.
*
* @example
* $('.pear').removeClass('pear').html();
* //=> <li class="">Pear</li>
*
* $('.pear').removeClass('pear').html()
* //=> <li class="">Pear</li>
* $('.apple').addClass('red').removeClass().html();
* //=> <li class="">Apple</li>
*
* $('.apple').addClass('red').removeClass().html()
* //=> <li class="">Apple</li>
* @param {string} value - Name of the class.
*
* @see {@link http://api.jquery.com/removeClass/}
* @param {string | Function} value - Name of the class.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/removeClass/}
*/
exports.removeClass = function (value) {
var classes;
var numClasses;
var removeAll;
// Handle if value is a function

@@ -582,7 +604,7 @@ if (typeof value === 'function') {

classes = splitNames(value);
numClasses = classes.length;
removeAll = arguments.length === 0;
var classes = splitNames(value);
var numClasses = classes.length;
var removeAll = arguments.length === 0;
return domEach(this, function (i, el) {
return domEach(this, function (_, el) {
if (!isTag(el)) return;

@@ -595,7 +617,6 @@

var elClasses = splitNames(el.attribs.class);
var index;
var changed;
var changed = false;
for (var j = 0; j < numClasses; j++) {
index = elClasses.indexOf(classes[j]);
var index = elClasses.indexOf(classes[j]);

@@ -624,13 +645,12 @@ if (index >= 0) {

* @example
* $('.apple.green').toggleClass('fruit green red').html();
* //=> <li class="apple fruit red">Apple</li>
*
* $('.apple.green').toggleClass('fruit green red').html()
* //=> <li class="apple fruit red">Apple</li>
* $('.apple.green').toggleClass('fruit green red', true).html();
* //=> <li class="apple green fruit red">Apple</li>
*
* $('.apple.green').toggleClass('fruit green red', true).html()
* //=> <li class="apple green fruit red">Apple</li>
*
* @param {(string|Function)} value - Name of the class. Can also be a function.
* @param {string | Function} value - Name of the class. Can also be a function.
* @param {boolean} [stateVal] - If specified the state of the class.
*
* @see {@link http://api.jquery.com/toggleClass/}
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/toggleClass/}
*/

@@ -656,4 +676,2 @@ exports.toggleClass = function (value, stateVal) {

var numElements = this.length;
var elementClasses;
var index;

@@ -664,3 +682,3 @@ for (var i = 0; i < numElements; i++) {

elementClasses = splitNames(this[i].attribs.class);
var elementClasses = splitNames(this[i].attribs.class);

@@ -670,3 +688,3 @@ // Check if class already exists

// Check if the class name is currently defined
index = elementClasses.indexOf(classNames[j]);
var index = elementClasses.indexOf(classNames[j]);

@@ -691,9 +709,9 @@ // Add if stateValue === true or we are toggling and there is no value

* elements match the selector. If using an element or Cheerio selection,
* returns `true` if _any_ of the elements match. If using a predicate
* function, the function is executed in the context of the selected element,
* so `this` refers to the current element.
* returns `true` if _any_ of the elements match. If using a predicate function,
* the function is executed in the context of the selected element, so `this`
* refers to the current element.
*
* @param {string|Function|cheerio|node} selector - Selector for the selection.
*
* @see {@link http://api.jquery.com/is/}
* @param {string | Function | Cheerio | Node} selector - Selector for the selection.
* @returns {boolean} Whether or not the selector matches an element of the instance.
* @see {@link https://api.jquery.com/is/}
*/

@@ -700,0 +718,0 @@ exports.is = function (selector) {

@@ -1,4 +0,3 @@

/**
* @module cheerio/css
*/
'use strict';
/** @module cheerio/css */

@@ -10,11 +9,9 @@ var domEach = require('../utils').domEach;

/**
* Get the value of a style property for the first element in the set of
* matched elements or set one or more CSS properties for every matched
* element.
* Get the value of a style property for the first element in the set of matched
* elements or set one or more CSS properties for every matched element.
*
* @param {string|object} prop - The name of the property.
* @param {string | object} prop - The name of the property.
* @param {string} [val] - If specified the new value.
* @returns {self}
*
* @see {@link http://api.jquery.com/css/}
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/css/}
*/

@@ -37,11 +34,10 @@ exports.css = function (prop, val) {

*
* @param {object} el - Element to set style of.
* @param {string|object} prop - Name of property.
* @param {string} val - Value to set property to.
* @private
* @param {Element} el - Element to set style of.
* @param {string | object} prop - Name of property.
* @param {string | Function} val - Value to set property to.
* @param {number} [idx] - Optional index within the selection.
* @returns {self}
* @private
*/
function setCss(el, prop, val, idx) {
if ('string' == typeof prop) {
if (typeof prop === 'string') {
var styles = getCss(el);

@@ -59,3 +55,3 @@ if (typeof val === 'function') {

el.attribs.style = stringify(styles);
} else if ('object' == typeof prop) {
} else if (typeof prop === 'object') {
Object.keys(prop).forEach(function (k) {

@@ -70,11 +66,9 @@ setCss(el, k, prop[k]);

*
* @param {node} el - Element to get styles from.
* @param {string} prop - Name of the prop.
* @returns {object}
* @private
* @param {Element} el - Element to get styles from.
* @param {string | string[]} [prop] - Name of the prop.
* @returns {object | undefined} The parsed styles.
*/
function getCss(el, prop) {
if (!el || !el.attribs) {
return undefined;
}
if (!el || !el.attribs) return;

@@ -84,3 +78,4 @@ var styles = parse(el.attribs.style);

return styles[prop];
} else if (Array.isArray(prop)) {
}
if (Array.isArray(prop)) {
var newStyles = {};

@@ -100,5 +95,5 @@ prop.forEach(function (item) {

*
* @private
* @param {object} obj - Object to stringify.
* @returns {object}
* @private
* @returns {string} The serialized styles.
*/

@@ -114,5 +109,5 @@ function stringify(obj) {

*
* @private
* @param {string} styles - Styles to be parsed.
* @returns {object}
* @private
* @returns {object} The parsed styles.
*/

@@ -119,0 +114,0 @@ function parse(styles) {

@@ -1,4 +0,3 @@

/**
* @module cheerio/forms
*/
'use strict';
/** @module cheerio/forms */

@@ -14,3 +13,4 @@ // https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js

*
* @see {@link http://api.jquery.com/serialize/}
* @returns {string} The serialized form.
* @see {@link https://api.jquery.com/serialize/}
*/

@@ -34,6 +34,8 @@ exports.serialize = function () {

* @example
* $('<form><input name="foo" value="bar" /></form>').serializeArray()
* //=> [ { name: 'foo', value: 'bar' } ]
* $('<form><input name="foo" value="bar" /></form>').serializeArray();
* //=> [ { name: 'foo', value: 'bar' } ]
*
* @see {@link http://api.jquery.com/serializeArray/}
* @returns {object[]} The serialized form.
* @this {Cheerio}
* @see {@link https://api.jquery.com/serializeArray/}
*/

@@ -43,4 +45,3 @@ exports.serializeArray = function () {

var Cheerio = this.constructor;
return this.map(function () {
var elem = this;
return this.map(function (_, elem) {
var $elem = Cheerio(elem);

@@ -53,4 +54,4 @@ if (elem.name === 'form') {

.filter(
// Verify elements have a name (`attr.name`) and are not disabled (`:disabled`)
'[name!=""]:not(:disabled)' +
// Verify elements have a name (`attr.name`) and are not disabled (`:enabled`)
'[name!=""]:enabled' +
// and cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`)

@@ -62,3 +63,3 @@ ':not(:submit, :button, :image, :reset, :file)' +

)
.map(function (i, elem) {
.map(function (_, elem) {
var $elem = Cheerio(elem);

@@ -65,0 +66,0 @@ var name = $elem.attr('name');

@@ -0,1 +1,2 @@

'use strict';
/**

@@ -20,8 +21,8 @@ * Methods for modifying the DOM structure.

/**
* Create an array of nodes, recursing into arrays and parsing strings if
* necessary.
* Create an array of nodes, recursing into arrays and parsing strings if necessary.
*
* @param {cheerio|string|cheerio[]|string[]} [elem] - Elements to make an array of.
* @private
* @param {Cheerio | string | Cheerio[] | string[]} [elem] - Elements to make an array of.
* @param {boolean} [clone] - Optionally clone nodes.
* @private
* @returns {Node[]} The array of nodes.
*/

@@ -31,5 +32,7 @@ exports._makeDomArray = function makeDomArray(elem, clone) {

return [];
} else if (elem.cheerio) {
return clone ? cloneDom(elem.get(), elem.options) : elem.get();
} else if (Array.isArray(elem)) {
}
if (elem.cheerio) {
return clone ? cloneDom(elem.get()) : elem.get();
}
if (Array.isArray(elem)) {
return elem.reduce(

@@ -41,3 +44,4 @@ function (newElems, el) {

);
} else if (typeof elem === 'string') {
}
if (typeof elem === 'string') {
return parse(elem, this.options, false).children;

@@ -48,3 +52,3 @@ }

var _insert = function (concatenator) {
function _insert(concatenator) {
return function () {

@@ -55,44 +59,36 @@ var elems = slice.call(arguments);

return domEach(this, function (i, el) {
var dom;
var domSrc;
var domSrc =
typeof elems[0] === 'function'
? elems[0].call(el, i, html(el.children))
: elems;
if (typeof elems[0] === 'function') {
domSrc = elems[0].call(el, i, html(el.children));
} else {
domSrc = elems;
}
dom = this._makeDomArray(domSrc, i < lastIdx);
var dom = this._makeDomArray(domSrc, i < lastIdx);
concatenator(dom, el.children, el);
});
};
};
}
/*
/**
* Modify an array in-place, removing some number of elements and adding new
* elements directly following them.
*
* @param {Array} array Target array to splice.
* @param {Number} spliceIdx Index at which to begin changing the array.
* @param {Number} spliceCount Number of elements to remove from the array.
* @param {Array} newElems Elements to insert into the array.
*
* @private
* @param {Node[]} array - Target array to splice.
* @param {number} spliceIdx - Index at which to begin changing the array.
* @param {number} spliceCount - Number of elements to remove from the array.
* @param {Node[]} newElems - Elements to insert into the array.
* @param {NodeWithChildren} parent - The parent of the node.
* @returns {Node[]} The spliced array.
*/
var uniqueSplice = function (array, spliceIdx, spliceCount, newElems, parent) {
function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent) {
var spliceArgs = [spliceIdx, spliceCount].concat(newElems);
var prev = array[spliceIdx - 1] || null;
var next = array[spliceIdx + spliceCount] || null;
var idx;
var len;
var prevIdx;
var node;
var oldParent;
// Before splicing in new elements, ensure they do not already appear in the
// current array.
for (idx = 0, len = newElems.length; idx < len; ++idx) {
node = newElems[idx];
oldParent = node.parent;
prevIdx = oldParent && oldParent.children.indexOf(newElems[idx]);
for (var idx = 0; idx < newElems.length; ++idx) {
var node = newElems[idx];
var oldParent = node.parent;
var prevIdx = oldParent && oldParent.children.indexOf(newElems[idx]);

@@ -127,22 +123,20 @@ if (oldParent && prevIdx > -1) {

return array.splice.apply(array, spliceArgs);
};
}
/**
* Insert every element in the set of matched elements to the end of the
* target.
* Insert every element in the set of matched elements to the end of the target.
*
* @param {string|cheerio} target - Element to append elements to.
*
* @example
* $('<li class="plum">Plum</li>').appendTo('#fruits');
* $.html();
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // <li class="plum">Plum</li>
* // </ul>
*
* $('<li class="plum">Plum</li>').appendTo('#fruits')
* $.html()
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // <li class="plum">Plum</li>
* // </ul>
*
* @see {@link http://api.jquery.com/appendTo/}
* @param {string | Cheerio} target - Element to append elements to.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/appendTo/}
*/

@@ -165,19 +159,17 @@ exports.appendTo = function (target) {

/**
* Insert every element in the set of matched elements to the beginning of the
* target.
* Insert every element in the set of matched elements to the beginning of the target.
*
* @param {string|cheerio} target - Element to prepend elements to.
*
* @example
* $('<li class="plum">Plum</li>').prependTo('#fruits');
* $.html();
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* $('<li class="plum">Plum</li>').prependTo('#fruits')
* $.html()
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* @see {@link http://api.jquery.com/prependTo/}
* @param {string | Cheerio} target - Element to prepend elements to.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/prependTo/}
*/

@@ -202,16 +194,14 @@ exports.prependTo = function (target) {

*
* @function
*
* @example
* $('ul').append('<li class="plum">Plum</li>');
* $.html();
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // <li class="plum">Plum</li>
* // </ul>
*
* $('ul').append('<li class="plum">Plum</li>')
* $.html()
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // <li class="plum">Plum</li>
* // </ul>
*
* @see {@link http://api.jquery.com/append/}
* @function
* @see {@link https://api.jquery.com/append/}
*/

@@ -225,16 +215,14 @@ exports.append = _insert(function (dom, children, parent) {

*
* @function
*
* @example
* $('ul').prepend('<li class="plum">Plum</li>');
* $.html();
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* $('ul').prepend('<li class="plum">Plum</li>')
* $.html()
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* @see {@link http://api.jquery.com/prepend/}
* @function
* @see {@link https://api.jquery.com/prepend/}
*/

@@ -253,5 +241,2 @@ exports.prepend = _insert(function (dom, children, parent) {

var el = this[i];
var wrapperDom;
var elInsertLocation;
var j;

@@ -266,13 +251,13 @@ if (wrapperFn) {

wrapperDom = this._makeDomArray(wrapper, i < lastIdx).slice(0, 1);
elInsertLocation = wrapperDom[0];
var wrapperDom = this._makeDomArray(wrapper, i < lastIdx).slice(0, 1);
var elInsertLocation = wrapperDom[0];
// Find the deepest child. Only consider the first tag child of each node
// (ignore text); stop if no children are found.
j = 0;
var j = 0;
while (elInsertLocation && elInsertLocation.children) {
if (j >= elInsertLocation.children.length) {
break;
}
while (
elInsertLocation &&
elInsertLocation.children &&
j < elInsertLocation.children.length
) {
if (elInsertLocation.children[j].type === 'tag') {

@@ -297,37 +282,37 @@ elInsertLocation = elInsertLocation.children[j];

* nested several levels deep, but should contain only one inmost element. A
* copy of this structure will be wrapped around each of the elements in the
* set of matched elements. This method returns the original set of elements
* for chaining purposes.
* copy of this structure will be wrapped around each of the elements in the set
* of matched elements. This method returns the original set of elements for
* chaining purposes.
*
* @param {cheerio} wrapper - The DOM structure to wrap around each element in the selection.
*
* @example
* const redFruit = $('<div class="red-fruit"></div>');
* $('.apple').wrap(redFruit);
*
* const redFruit = $('<div class="red-fruit"></div>')
* $('.apple').wrap(redFruit)
* //=> <ul id="fruits">
* // <div class="red-fruit">
* // <li class="apple">Apple</li>
* // </div>
* // <li class="orange">Orange</li>
* // <li class="plum">Plum</li>
* // </ul>
*
* //=> <ul id="fruits">
* // <div class="red-fruit">
* // <li class="apple">Apple</li>
* // </div>
* // <li class="orange">Orange</li>
* // <li class="plum">Plum</li>
* // </ul>
* const healthy = $('<div class="healthy"></div>');
* $('li').wrap(healthy);
*
* const healthy = $('<div class="healthy"></div>')
* $('li').wrap(healthy)
* //=> <ul id="fruits">
* // <div class="healthy">
* // <li class="apple">Apple</li>
* // </div>
* // <div class="healthy">
* // <li class="orange">Orange</li>
* // </div>
* // <div class="healthy">
* // <li class="plum">Plum</li>
* // </div>
* // </ul>
*
* //=> <ul id="fruits">
* // <div class="healthy">
* // <li class="apple">Apple</li>
* // </div>
* // <div class="healthy">
* // <li class="orange">Orange</li>
* // </div>
* // <div class="healthy">
* // <li class="plum">Plum</li>
* // </div>
* // </ul>
*
* @see {@link http://api.jquery.com/wrap/}
* @function
* @param {Cheerio} wrapper - The DOM structure to wrap around each element in
* the selection.
* @see {@link https://api.jquery.com/wrap/}
*/

@@ -347,39 +332,39 @@ exports.wrap = _wrap(function (el, elInsertLocation, wrapperDom) {

/**
* The .wrapInner() function can take any string or object that could be passed to
* the $() factory function to specify a DOM structure. This structure may be
* The .wrapInner() function can take any string or object that could be passed
* to the $() factory function to specify a DOM structure. This structure may be
* nested several levels deep, but should contain only one inmost element. The
* structure will be wrapped around the content of each of the elements in the set
* of matched elements.
* structure will be wrapped around the content of each of the elements in the
* set of matched elements.
*
* @param {cheerio} wrapper - The DOM structure to wrap around the content of each element in the selection.
*
* @example
* const redFruit = $('<div class="red-fruit"></div>');
* $('.apple').wrapInner(redFruit);
*
* const redFruit = $('<div class="red-fruit"></div>')
* $('.apple').wrapInner(redFruit)
* //=> <ul id="fruits">
* // <li class="apple">
* // <div class="red-fruit">Apple</div>
* // </li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* //=> <ul id="fruits">
* // <li class="apple">
* // <div class="red-fruit">Apple</div>
* // </li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
* const healthy = $('<div class="healthy"></div>');
* $('li').wrapInner(healthy);
*
* const healthy = $('<div class="healthy"></div>')
* $('li').wrapInner(healthy)
* //=> <ul id="fruits">
* // <li class="apple">
* // <div class="healthy">Apple</div>
* // </li>
* // <li class="orange">
* // <div class="healthy">Orange</div>
* // </li>
* // <li class="pear">
* // <div class="healthy">Pear</div>
* // </li>
* // </ul>
*
* //=> <ul id="fruits">
* // <li class="apple">
* // <div class="healthy">Apple</div>
* // </li>
* // <li class="orange">
* // <div class="healthy">Orange</div>
* // </li>
* // <li class="pear">
* // <div class="healthy">Pear</div>
* // </li>
* // </ul>
*
* @see {@link http://api.jquery.com/wrapInner/}
* @function
* @param {Cheerio} wrapper - The DOM structure to wrap around the content of
* each element in the selection.
* @see {@link https://api.jquery.com/wrapInner/}
*/

@@ -392,16 +377,138 @@ exports.wrapInner = _wrap(function (el, elInsertLocation, wrapperDom) {

/**
* The .unwrap() function, removes the parents of the set of matched elements
* from the DOM, leaving the matched elements in their place.
*
* @example <caption>without selector</caption>
* const $ = cheerio.load(
* '<div id=test>\n <div><p>Hello</p></div>\n <div><p>World</p></div>\n</div>'
* );
* $('#test p').unwrap();
*
* //=> <div id=test>
* // <p>Hello</p>
* // <p>World</p>
* // </div>
*
* @example <caption>with selector</caption>
* const $ = cheerio.load(
* '<div id=test>\n <p>Hello</p>\n <b><p>World</p></b>\n</div>'
* );
* $('#test p').unwrap('b');
*
* //=> <div id=test>
* // <p>Hello</p>
* // <p>World</p>
* // </div>
*
* @param {string} [selector] - A selector to check the parent element against.
* If an element's parent does not match the selector, the element won't be unwrapped.
* @returns {Cheerio} The instance itself, for chaining.
* @see {@link https://api.jquery.com/unwrap/}
*/
exports.unwrap = function (selector) {
var self = this;
this.parent(selector)
.not('body')
.each(function (i, el) {
self._make(el).replaceWith(el.children);
});
return this;
};
/**
* The .wrapAll() function can take any string or object that could be passed to
* the $() function to specify a DOM structure. This structure may be nested
* several levels deep, but should contain only one inmost element. The
* structure will be wrapped around all of the elements in the set of matched
* elements, as a single group.
*
* @example <caption>With markup passed to `wrapAll`</caption>
* const $ = cheerio.load(
* '<div class="container"><div class="inner">First</div><div class="inner">Second</div></div>'
* );
* $('.inner').wrapAll("<div class='new'></div>");
*
* //=> <div class="container">
* // <div class='new'>
* // <div class="inner">First</div>
* // <div class="inner">Second</div>
* // </div>
* // </div>
*
* @example <caption>With an existing cheerio instance</caption>
* const $ = cheerio.load(
* '<span>Span 1</span><strong>Strong</strong><span>Span 2</span>'
* );
* const wrap = $('<div><p><em><b></b></em></p></div>');
* $('span').wrapAll(wrap);
*
* //=> <div>
* // <p>
* // <em>
* // <b>
* // <span>Span 1</span>
* // <span>Span 2</span>
* // </b>
* // </em>
* // </p>
* // </div>
* // <strong>Strong</strong>
*
* @param {Cheerio | string | Element | Element[] | Function} wrapper - The DOM
* structure to wrap around all matched elements in the selection.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/wrapAll/}
*/
exports.wrapAll = function (wrapper) {
if (this[0]) {
if (typeof wrapper === 'function') {
wrapper = wrapper.call(this[0]);
}
var wrap = this._make(wrapper).insertBefore(this[0]);
// if html is given as wrapper, wrap may contain text elements
var elInsertLocation = { children: wrap };
var j = 0;
// Find the deepest child. Only consider the first tag child of each node
// (ignore text); stop if no children are found.
while (
elInsertLocation &&
elInsertLocation.children &&
j < elInsertLocation.children.length
) {
if (elInsertLocation.children[j].type === 'tag') {
elInsertLocation = elInsertLocation.children[j];
j = 0;
} else {
j++;
}
}
this._make(elInsertLocation).append(this);
}
return this;
};
/*eslint-disable jsdoc/check-param-names*/
/**
* Insert content next to each element in the set of matched elements.
*
* @example
* $('.apple').after('<li class="plum">Plum</li>');
* $.html();
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="plum">Plum</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* $('.apple').after('<li class="plum">Plum</li>')
* $.html()
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="plum">Plum</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* @see {@link http://api.jquery.com/after/}
* @param {...(string | Element | Element[] | Cheerio | Function)} content -
* HTML string, DOM element, array of DOM elements or Cheerio to insert after
* each element in the set of matched elements.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/after/}
*/

@@ -412,3 +519,3 @@ exports.after = function () {

domEach(this, function (i, el) {
return domEach(this, function (i, el) {
var parent = el.parent;

@@ -421,22 +528,21 @@ if (!parent) {

var index = siblings.indexOf(el);
var domSrc;
var dom;
// If not found, move on
/* istanbul ignore next */
if (index < 0) return;
if (typeof elems[0] === 'function') {
domSrc = elems[0].call(el, i, html(el.children));
} else {
domSrc = elems;
}
dom = this._makeDomArray(domSrc, i < lastIdx);
var domSrc =
typeof elems[0] === 'function'
? elems[0].call(el, i, html(el.children))
: elems;
var dom = this._makeDomArray(domSrc, i < lastIdx);
// Add element after `this` element
uniqueSplice(siblings, index + 1, 0, dom, parent);
});
return this;
};
/*eslint-enable jsdoc/check-param-names*/
/**

@@ -446,15 +552,14 @@ * Insert every element in the set of matched elements after the target.

* @example
* $('<li class="plum">Plum</li>').insertAfter('.apple');
* $.html();
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="plum">Plum</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* $('<li class="plum">Plum</li>').insertAfter('.apple')
* $.html()
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="plum">Plum</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* @param {string|cheerio} target - Element to insert elements after.
*
* @see {@link http://api.jquery.com/insertAfter/}
* @param {string | Cheerio} target - Element to insert elements after.
* @returns {Cheerio} The set of newly inserted elements.
* @see {@link https://api.jquery.com/insertAfter/}
*/

@@ -485,2 +590,3 @@ exports.insertAfter = function (target) {

// If not found, move on
/* istanbul ignore next */
if (index < 0) return;

@@ -495,2 +601,4 @@

/*eslint-disable jsdoc/check-param-names*/
/**

@@ -500,13 +608,16 @@ * Insert content previous to each element in the set of matched elements.

* @example
* $('.apple').before('<li class="plum">Plum</li>');
* $.html();
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* $('.apple').before('<li class="plum">Plum</li>')
* $.html()
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* @see {@link http://api.jquery.com/before/}
* @param {...(string | Element | Element[] | Cheerio | Function)} content -
* HTML string, DOM element, array of DOM elements or Cheerio to insert before
* each element in the set of matched elements.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/before/}
*/

@@ -517,3 +628,3 @@ exports.before = function () {

domEach(this, function (i, el) {
return domEach(this, function (i, el) {
var parent = el.parent;

@@ -526,15 +637,13 @@ if (!parent) {

var index = siblings.indexOf(el);
var domSrc;
var dom;
// If not found, move on
/* istanbul ignore next */
if (index < 0) return;
if (typeof elems[0] === 'function') {
domSrc = elems[0].call(el, i, html(el.children));
} else {
domSrc = elems;
}
var domSrc =
typeof elems[0] === 'function'
? elems[0].call(el, i, html(el.children))
: elems;
dom = this._makeDomArray(domSrc, i < lastIdx);
var dom = this._makeDomArray(domSrc, i < lastIdx);

@@ -544,6 +653,6 @@ // Add element before `el` element

});
return this;
};
/*eslint-enable jsdoc/check-param-names*/
/**

@@ -553,15 +662,14 @@ * Insert every element in the set of matched elements before the target.

* @example
* $('<li class="plum">Plum</li>').insertBefore('.apple');
* $.html();
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* $('<li class="plum">Plum</li>').insertBefore('.apple')
* $.html()
* //=> <ul id="fruits">
* // <li class="plum">Plum</li>
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="pear">Pear</li>
* // </ul>
*
* @param {string|cheerio} target - Element to insert elements before.
*
* @see {@link http://api.jquery.com/insertBefore/}
* @param {string | Cheerio} target - Element to insert elements before.
* @returns {Cheerio} The set of newly inserted elements.
* @see {@link https://api.jquery.com/insertBefore/}
*/

@@ -581,3 +689,3 @@ exports.insertBefore = function (target) {

self.remove();
domEach(target, function (i, el) {
domEach(target, function (_, el) {
var clonedSelf = self._makeDomArray(self.clone());

@@ -593,2 +701,3 @@ var parent = el.parent;

// If not found, move on
/* istanbul ignore next */
if (index < 0) return;

@@ -608,21 +717,18 @@

* @example
* $('.pear').remove();
* $.html();
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // </ul>
*
* $('.pear').remove()
* $.html()
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // </ul>
*
* @param {string} [selector] - Optional selector for elements to remove.
*
* @see {@link http://api.jquery.com/remove/}
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/remove/}
*/
exports.remove = function (selector) {
var elems = this;
// Filter if we have selector
if (selector) elems = elems.filter(selector);
var elems = selector ? this.filter(selector) : this;
domEach(elems, function (i, el) {
domEach(elems, function (_, el) {
DomUtils.removeElement(el);

@@ -639,20 +745,17 @@ el.prev = el.next = el.parent = null;

* @example
* const plum = $('<li class="plum">Plum</li>');
* $('.pear').replaceWith(plum);
* $.html();
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="plum">Plum</li>
* // </ul>
*
* const plum = $('<li class="plum">Plum</li>')
* $('.pear').replaceWith(plum)
* $.html()
* //=> <ul id="fruits">
* // <li class="apple">Apple</li>
* // <li class="orange">Orange</li>
* // <li class="plum">Plum</li>
* // </ul>
*
* @param {cheerio|Function} content - Replacement for matched elements.
*
* @see {@link http://api.jquery.com/replaceWith/}
* @param {Cheerio | Function} content - Replacement for matched elements.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/replaceWith/}
*/
exports.replaceWith = function (content) {
var self = this;
domEach(this, function (i, el) {
return domEach(this, function (i, el) {
var parent = el.parent;

@@ -664,6 +767,5 @@ if (!parent) {

var siblings = parent.children;
var dom = self._makeDomArray(
var dom = this._makeDomArray(
typeof content === 'function' ? content.call(el, i, el) : content
);
var index;

@@ -674,10 +776,11 @@ // In the case that `dom` contains nodes that already exist in other

index = siblings.indexOf(el);
var index = siblings.indexOf(el);
// Completely remove old element
uniqueSplice(siblings, index, 1, dom, parent);
el.parent = el.prev = el.next = null;
if (dom.indexOf(el) < 0) {
el.parent = el.prev = el.next = null;
}
});
return this;
};

@@ -689,11 +792,11 @@

* @example
* $('ul').empty();
* $.html();
* //=> <ul id="fruits"></ul>
*
* $('ul').empty()
* $.html()
* //=> <ul id="fruits"></ul>
*
* @see {@link http://api.jquery.com/empty/}
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/empty/}
*/
exports.empty = function () {
domEach(this, function (i, el) {
return domEach(this, function (_, el) {
el.children.forEach(function (child) {

@@ -705,3 +808,2 @@ child.next = child.prev = child.parent = null;

});
return this;
};

@@ -711,16 +813,14 @@

* 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.
* is specified, each selected element's content is replaced by the new content.
*
* @param {string} str - If specified used to replace selection's contents.
*
* @example
* $('.orange').html();
* //=> Orange
*
* $('.orange').html()
* //=> Orange
* $('#fruits').html('<li class="mango">Mango</li>').html();
* //=> <li class="mango">Mango</li>
*
* $('#fruits').html('<li class="mango">Mango</li>').html()
* //=> <li class="mango">Mango</li>
*
* @see {@link http://api.jquery.com/html/}
* @param {string | Cheerio} str - If specified used to replace selection's contents.
* @returns {Cheerio} The instance itself.
* @see {@link https://api.jquery.com/html/}
*/

@@ -733,5 +833,5 @@ exports.html = function (str) {

var opts = this.options;
var opts = Object.apply({}, this.options); // keep main options
domEach(this, function (i, el) {
return domEach(this, function (_, el) {
el.children.forEach(function (child) {

@@ -741,2 +841,4 @@ child.next = child.prev = child.parent = null;

opts.context = el;
var content = str.cheerio

@@ -748,6 +850,9 @@ ? str.clone().get()

});
return this;
};
/**
* Turns the collection to a string. Alias for `.html()`.
*
* @returns {string} The rendered document.
*/
exports.toString = function () {

@@ -762,15 +867,16 @@ return html(this, this.options);

*
* @param {string} [str] - If specified replacement for the selected element's contents.
*
* @example
* $('.orange').text();
* //=> Orange
*
* $('.orange').text()
* //=> Orange
* $('ul').text();
* //=> Apple
* // Orange
* // Pear
*
* $('ul').text()
* //=> Apple
* // Orange
* // Pear
*
* @see {@link http://api.jquery.com/text/}
* @param {string | Function} [str] - If specified replacement for the selected
* element's contents.
* @returns {Cheerio | string} The instance itself when setting text, otherwise
* the rendered document.
* @see {@link https://api.jquery.com/text/}
*/

@@ -781,7 +887,7 @@ exports.text = function (str) {

return text(this);
} else if (typeof str === 'function') {
}
if (typeof str === 'function') {
// Function support
var self = this;
return domEach(this, function (i, el) {
return exports.text.call(self._make(el), str.call(el, i, text([el])));
return exports.text.call(this._make(el), str.call(el, i, text([el])));
});

@@ -791,3 +897,3 @@ }

// Append text node to each selected elements
domEach(this, function (i, el) {
return domEach(this, function (_, el) {
el.children.forEach(function (child) {

@@ -801,4 +907,2 @@ child.next = child.prev = child.parent = null;

});
return this;
};

@@ -810,9 +914,9 @@

* @example
* const moreFruit = $('#fruits').clone();
*
* const moreFruit = $('#fruits').clone()
*
* @see {@link http://api.jquery.com/clone/}
* @returns {Cheerio} The cloned object.
* @see {@link https://api.jquery.com/clone/}
*/
exports.clone = function () {
return this._make(cloneDom(this.get(), this.options));
return this._make(cloneDom(this.get()));
};

@@ -0,1 +1,2 @@

'use strict';
/**

@@ -7,3 +8,3 @@ * Methods for traversing the DOM structure.

var select = require('cheerio-select-tmp');
var select = require('cheerio-select');
var utils = require('../utils');

@@ -13,2 +14,4 @@ var domEach = utils.domEach;

var isTag = utils.isTag;
var slice = Array.prototype.slice;
var reSiblingSelector = /^\s*[~+]/;

@@ -20,42 +23,44 @@ /**

* @example
* $('#fruits').find('li').length;
* //=> 3
* $('#fruits').find($('.apple')).length;
* //=> 1
*
* $('#fruits').find('li').length
* //=> 3
* $('#fruits').find($('.apple')).length
* //=> 1
*
* @param {string|cheerio|node} selectorOrHaystack - Element to look for.
*
* @see {@link http://api.jquery.com/find/}
* @param {string | Cheerio | Node} selectorOrHaystack - Element to look for.
* @returns {Cheerio} The found elements.
* @see {@link https://api.jquery.com/find/}
*/
exports.find = function (selectorOrHaystack) {
var elems = this.toArray().reduce(function (newElems, elem) {
return newElems.concat(elem.children.filter(isTag));
}, []);
var contains = this.constructor.contains;
var haystack;
if (!selectorOrHaystack) {
return this._make([]);
}
if (selectorOrHaystack && typeof selectorOrHaystack !== 'string') {
if (selectorOrHaystack.cheerio) {
haystack = selectorOrHaystack.get();
} else {
haystack = [selectorOrHaystack];
}
var context = this.toArray();
if (typeof selectorOrHaystack !== 'string') {
var contains = this.constructor.contains;
var haystack = selectorOrHaystack.cheerio
? selectorOrHaystack.get()
: [selectorOrHaystack];
return this._make(
haystack.filter(function (elem) {
var idx;
var len;
for (idx = 0, len = this.length; idx < len; ++idx) {
if (contains(this[idx], elem)) {
return true;
}
}
}, this)
return context.some(function (node) {
return contains(node, elem);
});
})
);
}
var options = { __proto__: this.options, context: this.toArray() };
var elems = reSiblingSelector.test(selectorOrHaystack)
? context
: context.reduce(function (newElems, elem) {
return Array.isArray(elem.children)
? newElems.concat(elem.children.filter(isTag))
: newElems;
}, []);
return this._make(select.select(selectorOrHaystack || '', elems, options));
var options = Object.assign({ context: context }, this.options);
return this._make(select.select(selectorOrHaystack, elems, options));
};

@@ -68,9 +73,8 @@

* @example
* $('.pear').parent().attr('id');
* //=> fruits
*
* $('.pear').parent().attr('id')
* //=> fruits
*
* @param {string} [selector] - If specified filter for parent.
*
* @see {@link http://api.jquery.com/parent/}
* @returns {Cheerio} The parents.
* @see {@link https://api.jquery.com/parent/}
*/

@@ -80,3 +84,3 @@ exports.parent = function (selector) {

domEach(this, function (idx, elem) {
domEach(this, function (_, elem) {
var parentElem = elem.parent;

@@ -92,3 +96,3 @@ if (

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

@@ -105,11 +109,10 @@ }

* @example
* $('.orange').parents().length;
* // => 2
* $('.orange').parents('#fruits').length;
* // => 1
*
* $('.orange').parents().length
* // => 2
* $('.orange').parents('#fruits').length
* // => 1
*
* @param {string} [selector] - If specified filter for parents.
*
* @see {@link http://api.jquery.com/parents/}
* @returns {Cheerio} The parents.
* @see {@link https://api.jquery.com/parents/}
*/

@@ -139,14 +142,12 @@ exports.parents = function (selector) {

* Get the ancestors of each element in the current set of matched elements, up
* to but not including the element matched by the selector, DOM node, or
* cheerio object.
* to but not including the element matched by the selector, DOM node, or cheerio object.
*
* @example
* $('.orange').parentsUntil('#food').length;
* // => 1
*
* $('.orange').parentsUntil('#food').length
* // => 1
*
* @param {string|node|cheerio} selector - Selector for element to stop at.
* @param {string|Function} [filter] - Optional filter for parents.
*
* @see {@link http://api.jquery.com/parentsUntil/}
* @param {string | Node | Cheerio} selector - Selector for element to stop at.
* @param {string | Function} [filter] - Optional filter for parents.
* @returns {Cheerio} The parents.
* @see {@link https://api.jquery.com/parentsUntil/}
*/

@@ -159,7 +160,3 @@ exports.parentsUntil = function (selector, filter) {

if (typeof selector === 'string') {
untilNode = select.select(
selector,
this.parents().toArray(),
this.options
)[0];
untilNodes = this.parents(selector).toArray();
} else if (selector && selector.cheerio) {

@@ -193,5 +190,5 @@ untilNodes = selector.toArray();

return this._make(
filter ? select.select(filter, parentNodes, this.options) : parentNodes
);
return filter
? exports.filter.call(parentNodes, filter, this)
: this._make(parentNodes);
};

@@ -201,19 +198,17 @@

* For each element in the set, get the first element that matches the selector
* by testing the element itself and traversing up through its ancestors in
* the DOM tree.
* by testing the element itself and traversing up through its ancestors in the DOM tree.
*
* @example
* $('.orange').closest();
* // => []
* $('.orange').closest('.apple');
* // => []
* $('.orange').closest('li');
* // => [<li class="orange">Orange</li>]
* $('.orange').closest('#fruits');
* // => [<ul id="fruits"> ... </ul>]
*
* $('.orange').closest()
* // => []
* $('.orange').closest('.apple')
* // => []
* $('.orange').closest('li')
* // => [<li class="orange">Orange</li>]
* $('.orange').closest('#fruits')
* // => [<ul id="fruits"> ... </ul>]
*
* @param {string} [selector] - Selector for the element to find.
*
* @see {@link http://api.jquery.com/closest/}
* @returns {Cheerio} The closest nodes.
* @see {@link https://api.jquery.com/closest/}
*/

@@ -227,3 +222,3 @@ exports.closest = function (selector) {

domEach(this, function (idx, elem) {
domEach(this, function (_, elem) {
var closestElem = traverseParents(this, elem, selector, 1)[0];

@@ -241,13 +236,11 @@

/**
* Gets the next sibling of the first selected element, optionally filtered by
* a selector.
* Gets the next sibling of the first selected element, optionally filtered by a selector.
*
* @example
* $('.apple').next().hasClass('orange');
* //=> true
*
* $('.apple').next().hasClass('orange')
* //=> true
*
* @param {string} [selector] - If specified filter for sibling.
*
* @see {@link http://api.jquery.com/next/}
* @returns {Cheerio} The next nodes.
* @see {@link https://api.jquery.com/next/}
*/

@@ -260,3 +253,3 @@ exports.next = function (selector) {

this.toArray().forEach(function (elem) {
domEach(this, function (_, elem) {
while ((elem = elem.next)) {

@@ -280,11 +273,10 @@ if (isTag(elem)) {

* @example
* $('.apple').nextAll();
* //=> [<li class="orange">Orange</li>, <li class="pear">Pear</li>]
* $('.apple').nextAll('.orange');
* //=> [<li class="orange">Orange</li>]
*
* $('.apple').nextAll()
* //=> [<li class="orange">Orange</li>, <li class="pear">Pear</li>]
* $('.apple').nextAll('.orange')
* //=> [<li class="orange">Orange</li>]
*
* @param {string} [selector] - If specified filter for siblings.
*
* @see {@link http://api.jquery.com/nextAll/}
* @returns {Cheerio} The next nodes.
* @see {@link https://api.jquery.com/nextAll/}
*/

@@ -297,3 +289,3 @@ exports.nextAll = function (selector) {

this.toArray().forEach(function (elem) {
domEach(this, function (_, elem) {
while ((elem = elem.next)) {

@@ -316,10 +308,9 @@ if (isTag(elem) && elems.indexOf(elem) === -1) {

* @example
* $('.apple').nextUntil('.pear');
* //=> [<li class="orange">Orange</li>]
*
* $('.apple').nextUntil('.pear')
* //=> [<li class="orange">Orange</li>]
*
* @param {string|cheerio|node} selector - Selector for element to stop at.
* @param {string | Cheerio | Node} selector - Selector for element to stop at.
* @param {string} [filterSelector] - If specified filter for siblings.
*
* @see {@link http://api.jquery.com/nextUntil/}
* @returns {Cheerio} The next nodes.
* @see {@link https://api.jquery.com/nextUntil/}
*/

@@ -335,3 +326,3 @@ exports.nextUntil = function (selector, filterSelector) {

if (typeof selector === 'string') {
untilNode = select.select(selector, this.nextAll().get(), this.options)[0];
untilNodes = this.nextAll(selector).toArray();
} else if (selector && selector.cheerio) {

@@ -343,3 +334,3 @@ untilNodes = selector.get();

this.toArray().forEach(function (elem) {
domEach(this, function (_, elem) {
while ((elem = elem.next)) {

@@ -370,9 +361,8 @@ if (

* @example
* $('.orange').prev().hasClass('apple');
* //=> true
*
* $('.orange').prev().hasClass('apple')
* //=> true
*
* @param {string} [selector] - If specified filter for siblings.
*
* @see {@link http://api.jquery.com/prev/}
* @returns {Cheerio} The previous nodes.
* @see {@link https://api.jquery.com/prev/}
*/

@@ -385,3 +375,3 @@ exports.prev = function (selector) {

this.toArray().forEach(function (elem) {
domEach(this, function (_, elem) {
while ((elem = elem.prev)) {

@@ -405,11 +395,10 @@ if (isTag(elem)) {

* @example
* $('.pear').prevAll();
* //=> [<li class="orange">Orange</li>, <li class="apple">Apple</li>]
* $('.pear').prevAll('.orange');
* //=> [<li class="orange">Orange</li>]
*
* $('.pear').prevAll()
* //=> [<li class="orange">Orange</li>, <li class="apple">Apple</li>]
* $('.pear').prevAll('.orange')
* //=> [<li class="orange">Orange</li>]
*
* @param {string} [selector] - If specified filter for siblings.
*
* @see {@link http://api.jquery.com/prevAll/}
* @returns {Cheerio} The previous nodes.
* @see {@link https://api.jquery.com/prevAll/}
*/

@@ -422,3 +411,3 @@ exports.prevAll = function (selector) {

this.toArray().forEach(function (elem) {
domEach(this, function (_, elem) {
while ((elem = elem.prev)) {

@@ -441,10 +430,9 @@ if (isTag(elem) && elems.indexOf(elem) === -1) {

* @example
* $('.pear').prevUntil('.apple');
* //=> [<li class="orange">Orange</li>]
*
* $('.pear').prevUntil('.apple')
* //=> [<li class="orange">Orange</li>]
*
* @param {string|cheerio|node} selector - Selector for element to stop at.
* @param {string | Cheerio | Node} selector - Selector for element to stop at.
* @param {string} [filterSelector] - If specified filter for siblings.
*
* @see {@link http://api.jquery.com/prevUntil/}
* @returns {Cheerio} The previous nodes.
* @see {@link https://api.jquery.com/prevUntil/}
*/

@@ -460,3 +448,3 @@ exports.prevUntil = function (selector, filterSelector) {

if (typeof selector === 'string') {
untilNode = select.select(selector, this.prevAll().get(), this.options)[0];
untilNodes = this.prevAll(selector).toArray();
} else if (selector && selector.cheerio) {

@@ -468,3 +456,3 @@ untilNodes = selector.get();

this.toArray().forEach(function (elem) {
domEach(this, function (_, elem) {
while ((elem = elem.prev)) {

@@ -494,12 +482,11 @@ if (

* @example
* $('.pear').siblings().length;
* //=> 2
*
* $('.pear').siblings().length
* //=> 2
* $('.pear').siblings('.orange').length;
* //=> 1
*
* $('.pear').siblings('.orange').length
* //=> 1
*
* @param {string} [selector] - If specified filter for siblings.
*
* @see {@link http://api.jquery.com/siblings/}
* @returns {Cheerio} The siblings.
* @see {@link https://api.jquery.com/siblings/}
*/

@@ -525,12 +512,11 @@ exports.siblings = function (selector) {

* @example
* $('#fruits').children().length;
* //=> 3
*
* $('#fruits').children().length
* //=> 3
* $('#fruits').children('.pear').text();
* //=> Pear
*
* $('#fruits').children('.pear').text()
* //=> Pear
*
* @param {string} [selector] - If specified filter for children.
*
* @see {@link http://api.jquery.com/children/}
* @returns {Cheerio} The children.
* @see {@link https://api.jquery.com/children/}
*/

@@ -552,7 +538,7 @@ exports.children = function (selector) {

* @example
* $('#fruits').contents().length;
* //=> 3
*
* $('#fruits').contents().length
* //=> 3
*
* @see {@link http://api.jquery.com/contents/}
* @returns {Cheerio} The children.
* @see {@link https://api.jquery.com/contents/}
*/

@@ -569,20 +555,19 @@ exports.contents = function () {

* element. When the callback is fired, the function is fired in the context of
* the DOM element, so `this` refers to the current element, which is
* equivalent to the function parameter `element`. To break out of the `each`
* loop early, return with `false`.
* the DOM element, so `this` refers to the current element, which is equivalent
* to the function parameter `element`. To break out of the `each` loop early,
* return with `false`.
*
* @example
* const fruits = [];
*
* const fruits = [];
* $('li').each(function (i, elem) {
* fruits[i] = $(this).text();
* });
*
* $('li').each(function(i, elem) {
* fruits[i] = $(this).text();
* });
* fruits.join(', ');
* //=> Apple, Orange, Pear
*
* fruits.join(', ');
* //=> Apple, Orange, Pear
*
* @param {Function} fn - Function to execute.
*
* @see {@link http://api.jquery.com/each/}
* @returns {Cheerio} The instance itself, useful for chaining.
* @see {@link https://api.jquery.com/each/}
*/

@@ -605,12 +590,14 @@ exports.each = function (fn) {

* @example
* $('li')
* .map(function (i, el) {
* // this === el
* return $(this).text();
* })
* .get()
* .join(' ');
* //=> "apple orange pear"
*
* $('li').map(function(i, el) {
* // this === el
* return $(this).text();
* }).get().join(' ');
* //=> "apple orange pear"
*
* @param {Function} fn - Function to execute.
*
* @see {@link http://api.jquery.com/map/}
* @returns {Cheerio} The mapped elements, wrapped in a Cheerio collection.
* @see {@link https://api.jquery.com/map/}
*/

@@ -634,3 +621,4 @@ exports.map = function (fn) {

};
} else if (match.cheerio) {
}
if (match.cheerio) {
return match.is.bind(match);

@@ -646,26 +634,26 @@ }

* those that match the selector or pass the function's test. When a Cheerio
* selection is specified, return only the elements contained in that
* selection. When an element is specified, return only that element (if it is
* contained in the original selection). If using the function method, the
* function is executed in the context of the selected element, so `this`
* refers to the current element.
* selection is specified, return only the elements contained in that selection.
* When an element is specified, return only that element (if it is contained in
* the original selection). If using the function method, the function is
* executed in the context of the selected element, so `this` refers to the
* current element.
*
* @function
* @param {string | Function} match - Value to look for, following the rules above.
* @param {node[]} container - Optional node to filter instead.
*
* @example <caption>Selector</caption>
* $('li').filter('.orange').attr('class');
* //=> orange
*
* $('li').filter('.orange').attr('class');
* //=> orange
*
* @example <caption>Function</caption>
* $('li')
* .filter(function (i, el) {
* // this === el
* return $(this).attr('class') === 'orange';
* })
* .attr('class');
* //=> orange
*
* $('li').filter(function(i, el) {
* // this === el
* return $(this).attr('class') === 'orange';
* }).attr('class')
* //=> orange
*
* @see {@link http://api.jquery.com/filter/}
* @function
* @param {string | Function} match - Value to look for, following the rules above.
* @param {Cheerio} [container] - Optional node to filter instead.
* @returns {Cheerio} The filtered collection.
* @see {@link https://api.jquery.com/filter/}
*/

@@ -676,7 +664,6 @@ exports.filter = function (match, container) {

if (typeof match === 'string') {
elements = select.filter(match, elements, container.options);
} else {
elements = elements.filter(getFilterFn(match));
}
elements =
typeof match === 'string'
? select.filter(match, elements, container.options)
: elements.filter(getFilterFn(match));

@@ -688,28 +675,26 @@ return container._make(elements);

* 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
* 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.
*
* @function
* @param {string | Function} match - Value to look for, following the rules above.
* @param {node[]} container - Optional node to filter instead.
*
* @example <caption>Selector</caption>
* $('li').not('.apple').length;
* //=> 2
*
* $('li').not('.apple').length;
* //=> 2
*
* @example <caption>Function</caption>
* $('li').not(function (i, el) {
* // this === el
* return $(this).attr('class') === 'orange';
* }).length;
* //=> 2
*
* $('li').not(function(i, el) {
* // this === el
* return $(this).attr('class') === 'orange';
* }).length;
* //=> 2
*
* @see {@link http://api.jquery.com/not/}
* @function
* @param {string | Function} match - Value to look for, following the rules above.
* @param {Node[] | Cheerio} [container] - Optional node to filter instead.
* @returns {Cheerio} The filtered collection.
* @see {@link https://api.jquery.com/not/}
*/

@@ -719,7 +704,5 @@ exports.not = function (match, container) {

var elements = container.toArray ? container.toArray() : container;
var matches;
var filterFn;
if (typeof match === 'string') {
matches = new Set(select.filter(match, elements, this.options));
var matches = new Set(select.filter(match, elements, this.options));
elements = elements.filter(function (el) {

@@ -729,3 +712,3 @@ return !matches.has(el);

} else {
filterFn = getFilterFn(match);
var filterFn = getFilterFn(match);
elements = elements.filter(function (el, i) {

@@ -745,19 +728,17 @@ return !filterFn(el, i);

* @example <caption>Selector</caption>
* $('ul').has('.pear').attr('id');
* //=> fruits
*
* $('ul').has('.pear').attr('id');
* //=> fruits
*
* @example <caption>Element</caption>
* $('ul').has($('.pear')[0]).attr('id');
* //=> fruits
*
* $('ul').has($('.pear')[0]).attr('id');
* //=> fruits
*
* @param {string|cheerio|node} selectorOrHaystack - Element to look for.
*
* @see {@link http://api.jquery.com/has/}
* @param {string | Cheerio | Node} selectorOrHaystack - Element to look for.
* @returns {Cheerio} The filtered collection.
* @see {@link https://api.jquery.com/has/}
*/
exports.has = function (selectorOrHaystack) {
var that = this;
return exports.filter.call(this, function () {
return that._make(this).find(selectorOrHaystack).length > 0;
return exports.filter.call(this, function (_, el) {
return that._make(el).find(selectorOrHaystack).length > 0;
});

@@ -770,7 +751,7 @@ };

* @example
* $('#fruits').children().first().text();
* //=> Apple
*
* $('#fruits').children().first().text()
* //=> Apple
*
* @see {@link http://api.jquery.com/first/}
* @returns {Cheerio} The first element.
* @see {@link https://api.jquery.com/first/}
*/

@@ -785,7 +766,7 @@ exports.first = function () {

* @example
* $('#fruits').children().last().text();
* //=> Pear
*
* $('#fruits').children().last().text()
* //=> Pear
*
* @see {@link http://api.jquery.com/last/}
* @returns {Cheerio} The last element.
* @see {@link https://api.jquery.com/last/}
*/

@@ -801,12 +782,11 @@ exports.last = function () {

* @example
* $('li').eq(0).text();
* //=> Apple
*
* $('li').eq(0).text()
* //=> Apple
* $('li').eq(-1).text();
* //=> Pear
*
* $('li').eq(-1).text()
* //=> Pear
*
* @param {number} i - Index of the element to select.
*
* @see {@link http://api.jquery.com/eq/}
* @returns {Cheerio} The element at the `i`th position.
* @see {@link https://api.jquery.com/eq/}
*/

@@ -828,20 +808,18 @@ exports.eq = function (i) {

* @example
* $('li').get(0).tagName
* //=> li
*
* $('li').get(0).tagName
* //=> li
* If no index is specified, retrieve all elements matched by the Cheerio object:
*
* If no index is specified, retrieve all elements matched by the Cheerio object:
*
* @example
* $('li').get().length;
* //=> 3
*
* $('li').get().length
* //=> 3
*
* @param {number} [i] - Element to retrieve.
*
* @see {@link http://api.jquery.com/get/}
* @returns {Node} The node at the `i`th position.
* @see {@link https://api.jquery.com/get/}
*/
exports.get = function (i) {
if (i == null) {
return Array.prototype.slice.call(this);
return slice.call(this);
}

@@ -855,13 +833,12 @@ return this[i < 0 ? this.length + i : i];

* @example
* $('.pear').index();
* //=> 2
* $('.orange').index('li');
* //=> 1
* $('.apple').index($('#fruit, li'));
* //=> 1
*
* $('.pear').index()
* //=> 2
* $('.orange').index('li')
* //=> 1
* $('.apple').index($('#fruit, li'))
* //=> 1
*
* @param {string|cheerio|node} [selectorOrNeedle] - Element to look for.
*
* @see {@link http://api.jquery.com/index/}
* @param {string | Cheerio | Node} [selectorOrNeedle] - Element to look for.
* @returns {number} The index of the element.
* @see {@link https://api.jquery.com/index/}
*/

@@ -887,16 +864,21 @@ exports.index = function (selectorOrNeedle) {

/**
* Gets the elements matching the specified range.
* Gets the elements matching the specified range (0-based position).
*
* @example
* $('li').slice(1).eq(0).text();
* //=> 'Orange'
*
* $('li').slice(1).eq(0).text()
* //=> 'Orange'
* $('li').slice(1, 2).length;
* //=> 1
*
* $('li').slice(1, 2).length
* //=> 1
*
* @see {@link http://api.jquery.com/slice/}
* @param {number} [start] - An position at which the elements begin to be
* selected. If negative, it indicates an offset from the end of the set.
* @param {number} [end] - An position at which the elements stop being
* selected. If negative, it indicates an offset from the end of the set. If
* omitted, the range continues until the end of the set.
* @returns {Cheerio} The elements matching the specified range.
* @see {@link https://api.jquery.com/slice/}
*/
exports.slice = function () {
return this._make([].slice.apply(this, arguments));
exports.slice = function (start, end) {
return this._make(slice.call(this, start, end));
};

@@ -920,7 +902,7 @@

* @example
* $('li').eq(0).end().length;
* //=> 3
*
* $('li').eq(0).end().length
* //=> 3
*
* @see {@link http://api.jquery.com/end/}
* @returns {Cheerio} The previous state of the set of matched elements.
* @see {@link https://api.jquery.com/end/}
*/

@@ -935,21 +917,14 @@ exports.end = function () {

* @example
* $('.apple').add('.orange').length;
* //=> 2
*
* $('.apple').add('.orange').length
* //=> 2
*
* @param {string|cheerio} other - Elements to add.
* @param {cheerio} [context] - Optionally the context of the new selection.
*
* @see {@link http://api.jquery.com/add/}
* @param {string | Cheerio} other - Elements to add.
* @param {Cheerio} [context] - Optionally the context of the new selection.
* @returns {Cheerio} The combined set.
* @see {@link https://api.jquery.com/add/}
*/
exports.add = function (other, context) {
var selection = this._make(other, context);
var contents = uniqueSort(selection.get().concat(this.get()));
for (var i = 0; i < contents.length; ++i) {
selection[i] = contents[i];
}
selection.length = contents.length;
return selection;
var contents = uniqueSort(this.get().concat(selection.get()));
return this._make(contents);
};

@@ -962,9 +937,8 @@

* @example
* $('li').eq(0).addBack('.orange').length;
* //=> 2
*
* $('li').eq(0).addBack('.orange').length
* //=> 2
*
* @param {string} selector - Selector for the elements to add.
*
* @see {@link http://api.jquery.com/addBack/}
* @returns {Cheerio} The combined set.
* @see {@link https://api.jquery.com/addBack/}
*/

@@ -971,0 +945,0 @@ exports.addBack = function (selector) {

@@ -0,1 +1,2 @@

'use strict';
/*

@@ -22,12 +23,11 @@ Module dependencies

/**
* Instance of cheerio. Methods are specified in the modules.
* Usage of this constructor is not recommended. Please use $.load instead.
* Instance of cheerio. Methods are specified in the modules. Usage of this
* constructor is not recommended. Please use $.load instead.
*
* @class
* @param {string | Cheerio | Node | Node[]} selector - The new selection.
* @param {string | Cheerio | Node | Node[]} [context] - Context of the selection.
* @param {string | Cheerio | Node | Node[]} [root] - Sets the root node.
* @param {object} [options] - Options for the instance.
* @hideconstructor
* @param {string|cheerio|node|node[]} selector - The new selection.
* @param {string|cheerio|node|node[]} [context] - Context of the selection.
* @param {string|cheerio|node|node[]} [root] - Sets the root node.
* @param {object} [options] - Options for the instance.
*
* @mixes module:cheerio/attributes

@@ -44,2 +44,3 @@ * @mixes module:cheerio/css

this.length = 0;
this.options = Object.assign(

@@ -60,2 +61,7 @@ {},

// $(<html>)
if (typeof selector === 'string' && isHtml(selector)) {
selector = parse(selector, this.options, false).children;
}
// $($)

@@ -76,7 +82,2 @@ if (selector.cheerio) return selector;

// $(<html>)
if (typeof selector === 'string' && isHtml(selector)) {
return Cheerio.call(this, parse(selector, this.options, false).children);
}
// If we don't have a context, maybe we have a root, from loading

@@ -92,3 +93,3 @@ if (!context) {

// $('li', 'ul')
selector = [context, selector].join(' ');
selector = context + ' ' + selector;
context = this._root;

@@ -108,5 +109,3 @@ }

/*
* Set a signature of the object
*/
/** Set a signature of the object. */
Cheerio.prototype.cheerio = '[cheerio object]';

@@ -117,9 +116,11 @@

*/
Cheerio.prototype.length = 0;
Cheerio.prototype.splice = Array.prototype.splice;
/*
* Make a cheerio object
/**
* Make a cheerio object.
*
* @private
* @param {Node[]} dom - The contents of the new object.
* @param {Node[]} [context] - The context of the new object.
* @returns {Cheerio} The new cheerio object.
*/

@@ -136,4 +137,5 @@ Cheerio.prototype._make = function (dom, context) {

* @example
* $('li').toArray()
* //=> [ {...}, {...}, {...} ]
* $('li').toArray(); //=> [ {...}, {...}, {...} ]
*
* @returns {Node[]} The contained items.
*/

@@ -145,5 +147,3 @@ Cheerio.prototype.toArray = function () {

// Support for (const element of $(...)) iteration:
if (typeof Symbol !== 'undefined') {
Cheerio.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
}
Cheerio.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

@@ -155,3 +155,3 @@ // Plug in the API

var isNode = function (obj) {
function isNode(obj) {
return (

@@ -163,2 +163,2 @@ obj.name ||

);
};
}

@@ -1,5 +0,3 @@

/*
* Cheerio default options
*/
'use strict';
/** Cheerio default options. */
exports.default = {

@@ -6,0 +4,0 @@ xml: false,

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

'use strict';
/*
Module Dependencies
*/
var htmlparser = require('htmlparser2');
var parse5 = require('parse5');
var htmlparser2Adapter = require('parse5-htmlparser2-tree-adapter');
var domhandler = require('domhandler');
var DomUtils = htmlparser.DomUtils;
var DomUtils = require('htmlparser2').DomUtils;
var parseWithHtmlparser2 = require('./parsers/htmlparser2').parse;
var parseWithParse5 = require('./parsers/parse5').parse;
var Document = require('domhandler').Document;

@@ -14,6 +14,2 @@ /*

exports = module.exports = function parse(content, options, isDocument) {
// options = options || $.fn.options;
var dom;
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(content)) {

@@ -24,40 +20,32 @@ content = content.toString();

if (typeof content === 'string') {
var useHtmlParser2 = options.xmlMode || options._useHtmlParser2;
dom = useHtmlParser2
? htmlparser.parseDocument(content, options)
return options.xmlMode || options._useHtmlParser2
? parseWithHtmlparser2(content, options)
: parseWithParse5(content, options, isDocument);
} else {
if (
typeof content === 'object' &&
content != null &&
content.type === 'root'
) {
dom = content;
} else {
// Generic root element
var root = new domhandler.Document(content);
content.forEach(function (node) {
node.parent = root;
});
}
dom = root;
}
if (
typeof content === 'object' &&
content != null &&
content.type === 'root'
) {
// If `content` is already a root, just return it
return content;
}
return dom;
};
// Add conent to new root element
var root = new Document(content);
function parseWithParse5(content, options, isDocument) {
var parse = isDocument ? parse5.parse : parse5.parseFragment;
// Update the DOM using the root
exports.update(content, root);
return parse(content, {
treeAdapter: htmlparser2Adapter,
sourceCodeLocationInfo: options.sourceCodeLocationInfo,
});
}
return root;
};
/*
Update the dom structure, for one changed layer
*/
/**
* Update the dom structure, for one changed layer.
*
* @param {Node[] | Node} arr - The new children.
* @param {NodeWithChildren} parent - The new parent.
* @returns {Node} The parent node.
*/
exports.update = function (arr, parent) {

@@ -64,0 +52,0 @@ // normalize

@@ -1,3 +0,2 @@

var htmlparser2Adapter = require('parse5-htmlparser2-tree-adapter');
'use strict';
/**

@@ -7,71 +6,16 @@ * @module cheerio/static

*/
var serialize = require('dom-serializer').default;
var defaultOptions = require('./options').default;
var flattenOptions = require('./options').flatten;
var select = require('cheerio-select-tmp').select;
var parse5 = require('parse5');
var parse = require('./parse');
var select = require('cheerio-select').select;
var renderWithParse5 = require('./parsers/parse5').render;
var renderWithHtmlparser2 = require('./parsers/htmlparser2').render;
/**
* Create a querying function, bound to a document created from the provided
* markup. Note that similar to web browser contexts, this operation may
* introduce `<html>`, `<head>`, and `<body>` elements; set `isDocument` to `false`
* to switch to fragment mode and disable this.
* Helper function to render a DOM.
*
* See the README section titled "Loading" for additional usage information.
*
* @param {string} content - Markup to be loaded.
* @param {object} [options] - Options for the created instance.
* @param {boolean} [isDocument] - Allows parser to be switched to fragment mode.
*
* @param {Cheerio} that - Cheerio instance to render.
* @param {Node[] | undefined} dom - The DOM to render. Defaults to `that`'s root.
* @param {object} options - Options for rendering.
* @returns {string} The rendered document.
*/
exports.load = function (content, options, isDocument) {
if (content === null || content === undefined) {
throw new Error('cheerio.load() expects a string');
}
var Cheerio = require('./cheerio');
options = Object.assign({}, defaultOptions, flattenOptions(options));
if (isDocument === void 0) isDocument = true;
var root = parse(content, options, isDocument);
var initialize = function (selector, context, r, opts) {
if (!(this instanceof initialize)) {
return new initialize(selector, context, r, opts);
}
opts = Object.assign({}, options, 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 = Object.create(Cheerio.prototype);
initialize.prototype.constructor = initialize;
// Mimic jQuery's prototype alias for plugin authors.
initialize.fn = initialize.prototype;
// Keep a reference to the top-level scope so we can chain methods that implicitly
// resolve selectors; e.g. $("<span>").(".bar"), which otherwise loses ._root
initialize.prototype._originalRoot = root;
// Add in the static methods
Object.assign(initialize, exports);
// Add in the root
initialize._root = root;
// store options
initialize._options = options;
return initialize;
};
/*
* Helper function
*/
function render(that, dom, options) {

@@ -88,20 +32,5 @@ if (!dom) {

if (options.xmlMode || options._useHtmlParser2) {
return serialize(dom, options);
}
// `dom-serializer` passes over the special "root" node and renders the
// node's children in its place. To mimic this behavior with `parse5`, an
// equivalent operation must be applied to the input array.
var nodes = 'length' in dom ? dom : [dom];
for (var index = 0; index < nodes.length; index += 1) {
if (nodes[index].type === 'root') {
nodes.splice.apply(nodes, [index, 1].concat(nodes[index].children));
}
}
return parse5.serialize(
{ children: nodes },
{ treeAdapter: htmlparser2Adapter }
);
return options.xmlMode || options._useHtmlParser2
? renderWithHtmlparser2(dom, options)
: renderWithParse5(dom);
}

@@ -112,4 +41,5 @@

*
* @param {string|cheerio|node} [dom] - Element to render.
* @param {string | Cheerio | Node | object} [dom] - Element to render.
* @param {object} [options] - Options for the renderer.
* @returns {string} The rendered document.
*/

@@ -131,8 +61,8 @@ exports.html = function (dom, options) {

// sometimes $.html() used without preloading html
// so fallback non existing options to the default ones
// Sometimes `$.html()` is used without preloading html,
// so fallback non-existing options to the default ones.
options = Object.assign(
{},
defaultOptions,
this._options,
this ? this._options : {},
flattenOptions(options || {})

@@ -147,3 +77,4 @@ );

*
* @param {string|cheerio|node} [dom] - Element to render.
* @param {string | Cheerio | Node} [dom] - Element to render.
* @returns {string} THe rendered document.
*/

@@ -159,3 +90,4 @@ exports.xml = function (dom) {

*
* @param {string|cheerio|node} [elems] - Elements to render.
* @param {Cheerio | Node[]} [elems] - Elements to render.
* @returns {string} The rendered document.
*/

@@ -169,6 +101,5 @@ exports.text = function (elems) {

var len = elems.length;
var elem;
for (var i = 0; i < len; i++) {
elem = elems[i];
var elem = elems[i];
if (elem.type === 'text') ret += elem.data;

@@ -193,5 +124,6 @@ else if (

* @param {string} data - Markup that will be parsed.
* @param {any|boolean} [context] - Will be ignored. If it is a boolean it will be used as the value of `keepScripts`.
* @param {any | boolean} [context] - Will be ignored. If it is a boolean it
* will be used as the value of `keepScripts`.
* @param {boolean} [keepScripts] - If false all scripts will be removed.
*
* @returns {Node[]} The parsed DOM.
* @alias Cheerio.parseHTML

@@ -201,4 +133,2 @@ * @see {@link https://api.jquery.com/jQuery.parseHTML/}

exports.parseHTML = function (data, context, keepScripts) {
var parsed;
if (!data || typeof data !== 'string') {

@@ -212,3 +142,3 @@ return null;

parsed = this.load(data, defaultOptions, false);
var parsed = this.load(data, defaultOptions, false);
if (!keepScripts) {

@@ -230,7 +160,8 @@ parsed('script').remove();

*
* @example
* $.root().append('<ul id="vegetables"></ul>').html();
* //=> <ul id="fruits">...</ul><ul id="vegetables"></ul>
*
* @returns {Cheerio} Cheerio instance wrapping the root node.
* @alias Cheerio.root
*
* @example
* $.root().append('<ul id="vegetables"></ul>').html();
* //=> <ul id="fruits">...</ul><ul id="vegetables"></ul>
*/

@@ -245,8 +176,7 @@ exports.root = function () {

*
* @param {node} container - Potential parent node.
* @param {node} contained - Potential child node.
* @returns {boolean}
*
* @param {Node} container - Potential parent node.
* @param {Node} contained - Potential child node.
* @returns {boolean} Indicates if the nodes contain one another.
* @alias Cheerio.contains
* @see {@link https://api.jquery.com/jQuery.contains}
* @see {@link https://api.jquery.com/jQuery.contains/}
*/

@@ -274,7 +204,7 @@ exports.contains = function (container, contained) {

*
* @param {Array|cheerio} arr1 - First array.
* @param {Array|cheerio} arr2 - Second array.
*
* @param {Array | Cheerio} arr1 - First array.
* @param {Array | Cheerio} arr2 - Second array.
* @returns {Array | Cheerio} `arr1`, with elements of `arr2` inserted.
* @alias Cheerio.merge
* @see {@link https://api.jquery.com/jQuery.merge}
* @see {@link https://api.jquery.com/jQuery.merge/}
*/

@@ -285,5 +215,7 @@ exports.merge = function (arr1, arr2) {

}
var newLength = arr1.length + arr2.length;
for (var i = 0; i < arr2.length; i++) {
arr1[i + arr1.length] = arr2[i];
var newLength = arr1.length;
var len = +arr2.length;
for (var i = 0; i < len; i++) {
arr1[newLength++] = arr2[i];
}

@@ -294,2 +226,6 @@ arr1.length = newLength;

/**
* @param {any} item - Item to check.
* @returns {boolean} Indicates if the item is array-like.
*/
function isArrayLike(item) {

@@ -296,0 +232,0 @@ if (Array.isArray(item)) {

@@ -0,1 +1,2 @@

'use strict';
var htmlparser2 = require('htmlparser2');

@@ -9,6 +10,5 @@ var domhandler = require('domhandler');

*
* @param {node} type - DOM node to check.
* @private
* @param {Node} type - DOM node to check.
* @returns {boolean}
*
* @private
*/

@@ -20,6 +20,5 @@ exports.isTag = htmlparser2.DomUtils.isTag;

*
* @param {string} str - String to be converted.
* @returns {string} String in camel case notation.
*
* @private
* @param {string} str - String to be converted.
* @returns {string} String in camel case notation.
*/

@@ -36,6 +35,5 @@ exports.camelCase = function (str) {

*
* @param {string} str - String to be converted.
* @returns {string} String in "CSS case".
*
* @private
* @param {string} str - String to be converted.
* @returns {string} String in "CSS case".
*/

@@ -47,4 +45,3 @@ exports.cssCase = function (str) {

/**
* Iterate over each DOM element without creating intermediary Cheerio
* instances.
* Iterate over each DOM element without creating intermediary Cheerio instances.
*

@@ -54,4 +51,5 @@ * This is indented for use internally to avoid otherwise unnecessary memory

*
* @param {cheerio} cheerio - Cheerio object.
* @param {Cheerio} cheerio - Cheerio object.
* @param {Function} fn - Function to call.
* @returns {Cheerio} The original instance.
*/

@@ -66,7 +64,8 @@ exports.domEach = function (cheerio, fn) {

/**
* Create a deep copy of the given DOM structure.
* Sets the parents of the copies of the passed nodes to `null`.
* Create a deep copy of the given DOM structure. Sets the parents of the copies
* of the passed nodes to `null`.
*
* @param {object} dom - The htmlparser2-compliant DOM structure.
* @private
* @param {Node | Node[]} dom - The htmlparser2-compliant DOM structure.
* @returns {Node[]} - The cloned DOM.
*/

@@ -90,6 +89,9 @@ exports.cloneDom = function (dom) {

/*
* A simple way to check for HTML strings or ID strings
/**
* A simple way to check for HTML strings. Tests for a `<` within a string,
* immediate followed by a letter and eventually followed by a `>`.
*
* @private
*/
var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w-]*)$)/;
var quickExpr = /<[a-zA-Z][^]*>/;

@@ -99,19 +101,9 @@ /**

*
* @private
* @param {string} str - String to check.
*
* @private
* @returns {boolean} Indicates if `str` is HTML.
*/
exports.isHtml = function (str) {
// Faster than running regex, if str starts with `<` and ends with `>`, assume it's HTML
if (
str.charAt(0) === '<' &&
str.charAt(str.length - 1) === '>' &&
str.length >= 3
) {
return true;
}
// Run the regex
var match = quickExpr.exec(str);
return !!(match && match[1]);
return quickExpr.test(str);
};
{
"name": "cheerio",
"version": "1.0.0-rc.5",
"version": "1.0.0-rc.6",
"description": "Tiny, fast, and elegant implementation of core jQuery designed specifically for the server",

@@ -19,2 +19,6 @@ "author": "Matt Mueller <mattmuelle@gmail.com> (mat.io)",

},
"bugs": {
"url": "https://github.com/cheeriojs/cheerio/issues"
},
"homepage": "https://cheerio.js.org/",
"main": "./index.js",

@@ -31,35 +35,35 @@ "types": "types/index.d.ts",

"dependencies": {
"cheerio-select-tmp": "^0.1.0",
"dom-serializer": "~1.2.0",
"domhandler": "^4.0.0",
"entities": "~2.1.0",
"htmlparser2": "^6.0.0",
"parse5": "^6.0.0",
"parse5-htmlparser2-tree-adapter": "^6.0.0"
"cheerio-select": "^1.3.0",
"dom-serializer": "^1.3.1",
"domhandler": "^4.1.0",
"htmlparser2": "^6.1.0",
"parse5": "^6.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1"
},
"devDependencies": {
"@types/node": "^14.14.10",
"@types/node": "^14.14.37",
"benchmark": "^2.1.4",
"coveralls": "^3.0.2",
"eslint": "^7.10.0",
"eslint-config-prettier": "^7.0.0",
"eslint-plugin-jsdoc": "^30.6.2",
"expect.js": "~0.3.1",
"husky": "^4.2.5",
"jquery": "^3.0.0",
"clean-jsdoc-theme": "^3.1.2",
"eslint": "^7.23.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-jest": "^24.3.4",
"eslint-plugin-jsdoc": "^32.3.0",
"eslint-plugin-node": "^11.1.0",
"husky": "^4.3.8",
"jest": "^26.6.3",
"jquery": "^3.6.0",
"jsdoc": "^3.6.6",
"jsdom": "^16.2.2",
"lint-staged": "^10.2.2",
"mocha": "^8.1.1",
"nyc": "^15.0.1",
"prettier": "^2.1.1",
"tsd": "^0.14.0",
"xyz": "~4.0.0"
"jsdom": "^16.5.2",
"lint-staged": "^10.5.4",
"prettier": "^2.2.1",
"prettier-plugin-jsdoc": "0.3.14",
"tsd": "^0.14.0"
},
"scripts": {
"test": "npm run lint && npm run test:mocha && npm run test:types",
"test:mocha": "mocha --recursive --reporter dot --parallel",
"test": "npm run lint && npm run test:jest && npm run test:types",
"test:jest": "jest",
"test:jest:cov": "npm run test:jest -- --coverage",
"test:types": "tsd",
"lint": "npm run lint:es && npm run lint:prettier",
"lint:es": "eslint --ignore-path .prettierignore .",
"lint:es": "eslint --ignore-path .gitignore .",
"lint:prettier": "npm run format:prettier:raw -- --check",

@@ -69,4 +73,6 @@ "format": "npm run format:es && npm run format:prettier",

"format:prettier": "npm run format:prettier:raw -- --write",
"format:prettier:raw": "prettier '**/*.{js,ts,md,json,yml}' --ignore-path .prettierignore",
"format:prettier:raw": "prettier \"**/*.{js,ts,md,json,yml}\" --ignore-path .gitignore",
"build:docs": "jsdoc --configure jsdoc-config.json",
"benchmark": "node benchmark/benchmark.js --regex \"^(?!.*highmem)\"",
"bench": "npm run benchmark",
"pre-commit": "lint-staged"

@@ -86,3 +92,12 @@ },

]
},
"jest": {
"testEnvironment": "node",
"testMatch": [
"<rootDir>/test/**/*.js"
],
"testPathIgnorePatterns": [
"/__fixtures__/"
]
}
}

@@ -6,20 +6,20 @@ <h1 align="center">cheerio</h1>

<div align="center">
<a href="http://travis-ci.org/cheeriojs/cheerio">
<img src="https://secure.travis-ci.org/cheeriojs/cheerio.svg?branch=master" alt="Travis CI" />
<a href="https://github.com/cheeriojs/cheerio/actions?query=workflow%3ACI+branch%3Amain">
<img src="https://img.shields.io/github/workflow/status/cheeriojs/cheerio/CI/main" alt="Build Status">
</a>
<a href="https://coveralls.io/r/cheeriojs/cheerio">
<img src="http://img.shields.io/coveralls/cheeriojs/cheerio.svg?branch=master&style=flat" alt="Coverage" />
<a href="https://coveralls.io/github/cheeriojs/cheerio">
<img src="https://img.shields.io/coveralls/github/cheeriojs/cheerio/main" alt="Coverage">
</a>
<a href="https://gitter.im/cheeriojs/cheerio?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge">
<img src="https://badges.gitter.im/Join%20Chat.svg" alt="Join the chat at https://gitter.im/cheeriojs/cheerio" />
<a href="https://gitter.im/cheeriojs/cheerio">
<img src="https://img.shields.io/gitter/room/cheeriojs/cheerio?color=%2348b293" alt="Join the chat at https://gitter.im/cheeriojs/cheerio">
</a>
<a href="#backers">
<img src="https://opencollective.com/cheerio/backers/badge.svg" alt="OpenCollective backers"/>
<img src="https://img.shields.io/opencollective/backers/cheerio" alt="OpenCollective backers">
</a>
<a href="#sponsors">
<img src="https://opencollective.com/cheerio/sponsors/badge.svg" alt="OpenCollective sponsors"/>
<img src="https://img.shields.io/opencollective/sponsors/cheerio" alt="OpenCollective sponsors">
</a>
</div>
<br />
<br>

@@ -60,3 +60,3 @@ [中文文档 (Chinese Readme)](https://github.com/cheeriojs/cheerio/wiki/Chinese-README)

Cheerio parses markup and provides an API for traversing/manipulating the resulting data structure. It does not interpret the result as a web browser does. Specifically, it does _not_ produce a visual rendering, apply CSS, load external resources, or execute JavaScript. If your use case requires any of this functionality, you should consider projects like [PhantomJS](http://phantomjs.org/) or [JSDom](https://github.com/tmpvar/jsdom).
Cheerio parses markup and provides an API for traversing/manipulating the resulting data structure. It does not interpret the result as a web browser does. Specifically, it does _not_ produce a visual rendering, apply CSS, load external resources, or execute JavaScript. If your use case requires any of this functionality, you should consider projects like [Puppeteer](https://github.com/puppeteer/puppeteer) or [JSDom](https://github.com/jsdom/jsdom).

@@ -264,3 +264,3 @@ ## API

http://vimeo.com/31950192
[https://vimeo.com/31950192](https://vimeo.com/31950192)

@@ -267,0 +267,0 @@ > This video tutorial is a follow-up to Nettut's "How to Scrape Web Pages with Node.js and jQuery", using cheerio instead of JSDOM + jQuery. This video shows how easy it is to use cheerio and how much faster cheerio is than JSDOM + jQuery.

@@ -5,3 +5,4 @@ import { Document, Element, DomHandlerOptions } from 'domhandler';

declare namespace cheerio {
type AttrFunction = (el: Element, i: number, currentValue: string) => any;
type AttrFunction = (this: Element, i: number, currentValue: string) => any;
type WrapFunction = (this: Element) => any;

@@ -11,3 +12,3 @@ interface Cheerio {

// Cheerio https://github.com/cheeriojs/cheerio
// JQuery http://api.jquery.com
// JQuery https://api.jquery.com

@@ -17,2 +18,3 @@ [index: number]: Element;

length: number;
[Symbol.iterator](): IterableIterator<Element>;

@@ -72,3 +74,3 @@ // Attributes

find(selector: string): Cheerio;
find(element: Cheerio): Cheerio;
find(element: Cheerio | Element): Cheerio;

@@ -130,4 +132,4 @@ parent(selector?: string): Cheerio;

get(): any[];
get(index: number): any;
get(): Element[];
get(index: number): Element | undefined;

@@ -201,2 +203,6 @@ index(): number;

wrapAll(
wrapper: Cheerio | string | Element | Element[] | WrapFunction
): Cheerio;
css(propertyName: string): string;

@@ -236,2 +242,5 @@ css(propertyNames: string[]): string[];

sourceCodeLocationInfo?: boolean;
/** Disable scripting in parse5, so noscript tags would be parsed */
scriptingEnabled?: boolean;
}

@@ -255,3 +264,3 @@

// Cheerio https://github.com/cheeriojs/cheerio
// JQuery http://api.jquery.com
// JQuery https://api.jquery.com
root(): Cheerio;

@@ -277,10 +286,11 @@ contains(container: Element, contained: Element): boolean;

load(
html: string | { toString(): string },
options?: CheerioParserOptions
html: string | Buffer | { toString(): string },
options?: CheerioParserOptions | null,
isDocument?: boolean
): Root;
load(element: Element, options?: CheerioParserOptions): Root;
load(element: Element | Element[], options?: CheerioParserOptions): Root;
}
}
declare const cheerioModule: cheerio.CheerioAPI;
export = cheerioModule;
declare const cheerio: cheerio.CheerioAPI;
export = cheerio;
SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc