cheerio
Advanced tools
Comparing version 1.0.0-rc.5 to 1.0.0-rc.6
@@ -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() |
50
index.js
@@ -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; |
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
153959
6
19
3315
0
1
+ Addedcheerio-select@^1.3.0
+ Addedcheerio-select@1.6.0(transitive)
+ Addedcss-select@4.3.0(transitive)
+ Addedcss-what@6.1.0(transitive)
+ Addeddom-serializer@1.4.1(transitive)
+ Addedentities@2.2.0(transitive)
- Removedcheerio-select-tmp@^0.1.0
- Removedentities@~2.1.0
- Removedcheerio-select-tmp@0.1.1(transitive)
- Removedcss-select@3.1.2(transitive)
- Removedcss-what@4.0.0(transitive)
- Removeddom-serializer@1.2.0(transitive)
- Removedentities@2.1.0(transitive)
Updateddom-serializer@^1.3.1
Updateddomhandler@^4.1.0
Updatedhtmlparser2@^6.1.0
Updatedparse5@^6.0.1