Comparing version 0.14.0 to 0.15.0
0.15.0 / 2014-04-08 | ||
================== | ||
* Update callbacks to pass element per docs (@kpdecker) | ||
* preserve options (@fb55) | ||
* Use SVG travis badge (@t3chnoboy) | ||
* only use static requires (@fb55) | ||
* Optimize manipulation methods (@kpdecker) | ||
* Optimize add and remove class cases (@kpdecker) | ||
* accept dom of DomHandler to cheerio.load (@nleush) | ||
* added parentsUntil method (@finspin) | ||
* Add performance optimization and bug fix `empty` method (@kpdecker) | ||
0.14.0 / 2014-04-01 | ||
@@ -3,0 +16,0 @@ ================== |
@@ -5,5 +5,3 @@ /** | ||
exports = module.exports = process.env.CHEERIO_COV | ||
? require('./lib-cov/cheerio') | ||
: require('./lib/cheerio'); | ||
exports = module.exports = require('./lib/cheerio'); | ||
@@ -10,0 +8,0 @@ /* |
@@ -53,4 +53,4 @@ var _ = require('lodash'), | ||
if (_.isFunction(value)) { | ||
return this.each(function(i, el) { | ||
setAttr(el, name, value.call(this, i, el.attribs[name])); | ||
return domEach(this, function(i, el) { | ||
setAttr(el, name, value.call(el, i, el.attribs[name])); | ||
}); | ||
@@ -135,5 +135,3 @@ } | ||
case 'textarea': | ||
return querying ? this.text() : this.each(function() { | ||
this.text(value); | ||
}); | ||
return this.text(value); | ||
case 'input': | ||
@@ -161,5 +159,3 @@ switch (this.attr('type')) { | ||
default: | ||
return querying ? this.attr('value') : this.each(function() { | ||
this.attr('value', value); | ||
}); | ||
return this.attr('value', value); | ||
} | ||
@@ -187,4 +183,4 @@ return; | ||
returnValue = []; | ||
option.each(function() { | ||
returnValue.push(this.attr('value')); | ||
domEach(option, function(i, el) { | ||
returnValue.push(el.attribs.value); | ||
}); | ||
@@ -207,3 +203,3 @@ } | ||
var removeAttribute = function(elem, name) { | ||
if (!elem.attribs || !Object.hasOwnProperty.call(elem.attribs, name)) | ||
if (!elem.attribs || !hasOwn.call(elem.attribs, name)) | ||
return; | ||
@@ -236,5 +232,5 @@ | ||
if (_.isFunction(value)) { | ||
this.each(function(i) { | ||
var className = this.attr('class') || ''; | ||
this.addClass(value.call(this[0], i, className)); | ||
return domEach(this, function(i, el) { | ||
var className = el.attribs['class'] || ''; | ||
addClass.call([el], value.call(el, i, className)); | ||
}); | ||
@@ -267,4 +263,5 @@ } | ||
for (var j = 0; j < numClasses; j++) { | ||
if (!~setClass.indexOf(' ' + classNames[j] + ' ')) | ||
setClass += classNames[j] + ' '; | ||
var appendClass = classNames[j] + ' '; | ||
if (!~setClass.indexOf(' ' + appendClass)) | ||
setClass += appendClass; | ||
} | ||
@@ -284,8 +281,10 @@ | ||
var removeClass = exports.removeClass = function(value) { | ||
var classes, removeAll; | ||
var classes, | ||
numClasses, | ||
removeAll; | ||
// Handle if value is a function | ||
if (_.isFunction(value)) { | ||
return this.each(function(i, el) { | ||
this.removeClass(value.call(this[0], i, el.attribs['class'] || '')); | ||
return domEach(this, function(i, el) { | ||
removeClass.call([el], value.call(el, i, el.attribs['class'] || '')); | ||
}); | ||
@@ -295,2 +294,3 @@ } | ||
classes = splitClass(value); | ||
numClasses = classes.length; | ||
removeAll = arguments.length === 0; | ||
@@ -301,5 +301,26 @@ | ||
el.attribs.class = removeAll ? | ||
'' : | ||
_.difference(splitClass(el.attribs.class), classes).join(' '); | ||
if (removeAll) { | ||
// Short circuit the remove all case as this is the nice one | ||
el.attribs.class = ''; | ||
} else { | ||
var elClasses = splitClass(el.attribs.class), | ||
index, | ||
changed; | ||
for (var j = 0; j < numClasses; j++) { | ||
index = elClasses.indexOf(classes[j]); | ||
if (index >= 0) { | ||
elClasses.splice(index, 1); | ||
changed = true; | ||
// We have to do another pass to ensure that there are not duplicate | ||
// classes listed | ||
j--; | ||
} | ||
} | ||
if (changed) { | ||
el.attribs.class = elClasses.join(' '); | ||
} | ||
} | ||
}); | ||
@@ -311,4 +332,4 @@ }; | ||
if (_.isFunction(value)) { | ||
return this.each(function(i, el) { | ||
this.toggleClass(value.call(this, i, el.attribs['class'] || '', stateVal), stateVal); | ||
return domEach(this, function(i, el) { | ||
toggleClass.call([el], value.call(el, i, el.attribs['class'] || '', stateVal), stateVal); | ||
}); | ||
@@ -315,0 +336,0 @@ } |
@@ -1,2 +0,3 @@ | ||
var _ = require('lodash'); | ||
var _ = require('lodash'), | ||
domEach = require('../utils').domEach; | ||
var toString = Object.prototype.toString; | ||
@@ -17,7 +18,7 @@ | ||
(toString.call(prop) === '[object Object]')) { | ||
return this.each(function(idx) { | ||
this._setCss(prop, val, idx); | ||
return domEach(this, function(idx, el) { | ||
setCss(el, prop, val, idx); | ||
}); | ||
} else { | ||
return this._getCss(prop); | ||
return getCss(this[0], prop); | ||
} | ||
@@ -36,7 +37,7 @@ }; | ||
exports._setCss = function(prop, val, idx) { | ||
function setCss(el, prop, val, idx) { | ||
if ('string' == typeof prop) { | ||
var styles = this._getCss(); | ||
var styles = getCss(el); | ||
if (_.isFunction(val)) { | ||
val = val.call(this[0], idx, this[0]); | ||
val = val.call(el, idx, el); | ||
} | ||
@@ -50,10 +51,9 @@ | ||
return this.attr('style', stringify(styles)); | ||
el.attribs.style = stringify(styles); | ||
} else if ('object' == typeof prop) { | ||
Object.keys(prop).forEach(function(k){ | ||
this._setCss(k, prop[k]); | ||
}, this); | ||
return this; | ||
setCss(el, k, prop[k]); | ||
}); | ||
} | ||
}; | ||
} | ||
@@ -68,4 +68,4 @@ /** | ||
exports._getCss = function(prop) { | ||
var styles = parse(this.attr('style')); | ||
function getCss(el, prop) { | ||
var styles = parse(el.attribs.style); | ||
if (typeof prop === 'string') { | ||
@@ -78,3 +78,3 @@ return styles[prop]; | ||
} | ||
}; | ||
} | ||
@@ -81,0 +81,0 @@ /** |
@@ -10,5 +10,6 @@ var _ = require('lodash'), | ||
slice = Array.prototype.slice; | ||
// Create an array of nodes, recursing into arrays and parsing strings if | ||
// necessary | ||
var makeDomArray = function(elem) { | ||
exports._makeDomArray = function makeDomArray(elem) { | ||
if (elem == null) { | ||
@@ -19,5 +20,5 @@ return []; | ||
} else if (_.isArray(elem)) { | ||
return _.flatten(elem.map(makeDomArray)); | ||
return _.flatten(elem.map(makeDomArray, this)); | ||
} else if (_.isString(elem)) { | ||
return evaluate(elem); | ||
return evaluate(elem, this.options); | ||
} else { | ||
@@ -30,15 +31,14 @@ return [elem]; | ||
return function() { | ||
var elems = slice.call(arguments), | ||
dom = makeDomArray(elems); | ||
var self = this, | ||
elems = slice.call(arguments), | ||
dom = this._makeDomArray(elems); | ||
if (_.isFunction(elems[0])) { | ||
return this.each(function(i, el) { | ||
dom = makeDomArray(elems[0].call(el, i, this.html())); | ||
concatenator(dom, el.children); | ||
updateDOM(el.children, el); | ||
return domEach(this, function(i, el) { | ||
dom = self._makeDomArray(elems[0].call(el, i, $.html(el.children))); | ||
concatenator(dom, el.children, el); | ||
}); | ||
} else { | ||
return domEach(this, function(i, el) { | ||
concatenator(dom, el.children); | ||
updateDOM(el.children, el); | ||
concatenator(dom, el.children, el); | ||
}); | ||
@@ -60,5 +60,7 @@ } | ||
*/ | ||
var uniqueSplice = function(array, spliceIdx, spliceCount, newElems) { | ||
var spliceArgs = [spliceIdx, spliceCount].concat(newElems); | ||
var idx, len, prevIdx; | ||
var uniqueSplice = function(array, spliceIdx, spliceCount, newElems, parent) { | ||
var spliceArgs = [spliceIdx, spliceCount].concat(newElems), | ||
prev = array[spliceIdx - 1] || null, | ||
next = array[spliceIdx] || null; | ||
var idx, len, prevIdx, node; | ||
@@ -68,17 +70,33 @@ // Before splicing in new elements, ensure they do not already appear in the | ||
for (idx = 0, len = newElems.length; idx < len; ++idx) { | ||
prevIdx = array.indexOf(newElems[idx]); | ||
if (prevIdx > -1) { | ||
node = newElems[idx]; | ||
prevIdx = node.parent && array.indexOf(newElems[idx]); | ||
if (node.parent && prevIdx > -1) { | ||
array.splice(prevIdx, 1); | ||
if (spliceIdx > prevIdx) { | ||
spliceArgs[0]--; | ||
} | ||
} | ||
node.parent = parent; | ||
node.prev = newElems[idx - 1] || prev; | ||
node.next = newElems[idx + 1] || next; | ||
} | ||
if (prev) { | ||
prev.next = newElems[0]; | ||
} | ||
if (next) { | ||
next.prev = newElems[newElems.length - 1]; | ||
} | ||
return array.splice.apply(array, spliceArgs); | ||
}; | ||
var append = exports.append = _insert(function(dom, children) { | ||
uniqueSplice(children, children.length, 0, dom); | ||
var append = exports.append = _insert(function(dom, children, parent) { | ||
uniqueSplice(children, children.length, 0, dom, parent); | ||
}); | ||
var prepend = exports.prepend = _insert(function(dom, children) { | ||
uniqueSplice(children, 0, 0, dom); | ||
var prepend = exports.prepend = _insert(function(dom, children, parent) { | ||
uniqueSplice(children, 0, 0, dom, parent); | ||
}); | ||
@@ -88,3 +106,4 @@ | ||
var elems = slice.call(arguments), | ||
dom = makeDomArray(elems); | ||
dom = this._makeDomArray(elems), | ||
self = this; | ||
@@ -100,10 +119,7 @@ domEach(this, function(i, el) { | ||
if (_.isFunction(elems[0])) { | ||
dom = makeDomArray(elems[0].call(el, i)); | ||
dom = self._makeDomArray(elems[0].call(el, i)); | ||
} | ||
// Add element after `this` element | ||
uniqueSplice(siblings, ++index, 0, dom); | ||
// Update next, prev, and parent pointers | ||
updateDOM(siblings, parent); | ||
uniqueSplice(siblings, ++index, 0, dom, parent); | ||
}); | ||
@@ -116,3 +132,4 @@ | ||
var elems = slice.call(arguments), | ||
dom = makeDomArray(elems); | ||
dom = this._makeDomArray(elems), | ||
self = this; | ||
@@ -128,10 +145,7 @@ domEach(this, function(i, el) { | ||
if (_.isFunction(elems[0])) { | ||
dom = makeDomArray(elems[0].call(el, i)); | ||
dom = self._makeDomArray(elems[0].call(el, i)); | ||
} | ||
// Add element before `el` element | ||
uniqueSplice(siblings, index, 0, dom); | ||
// Update next, prev, and parent pointers | ||
updateDOM(siblings, parent); | ||
uniqueSplice(siblings, index, 0, dom, parent); | ||
}); | ||
@@ -159,6 +173,11 @@ | ||
siblings.splice(index, 1); | ||
// Update next, prev, and parent pointers | ||
updateDOM(siblings, parent); | ||
if (el.prev) { | ||
el.prev.next = el.next; | ||
} | ||
if (el.next) { | ||
el.next.prev = el.prev; | ||
} | ||
el.prev = el.next = el.parent = null; | ||
}); | ||
@@ -170,6 +189,8 @@ | ||
var replaceWith = exports.replaceWith = function(content) { | ||
var self = this; | ||
domEach(this, function(i, el) { | ||
var parent = el.parent || el.root, | ||
siblings = parent.children, | ||
dom = makeDomArray(_.isFunction(content) ? content.call(el, i, el) : content), | ||
dom = self._makeDomArray(_.isFunction(content) ? content.call(el, i, el) : content), | ||
index; | ||
@@ -184,6 +205,4 @@ | ||
// Completely remove old element | ||
siblings.splice.apply(siblings, [index, 1].concat(dom)); | ||
uniqueSplice(siblings, index, 1, dom, parent); | ||
el.parent = el.prev = el.next = null; | ||
updateDOM(siblings, parent); | ||
}); | ||
@@ -196,3 +215,7 @@ | ||
domEach(this, function(i, el) { | ||
el.children = []; | ||
_.each(el.children, function(el) { | ||
el.next = el.prev = el.parent = null; | ||
}); | ||
el.children.length = 0; | ||
}); | ||
@@ -211,7 +234,10 @@ return this; | ||
str = str.cheerio ? str.get() : evaluate(str); | ||
str = str.cheerio ? str.get() : evaluate(str, this.options); | ||
domEach(this, function(i, el) { | ||
el.children = str; | ||
updateDOM(el.children, el); | ||
_.each(el.children, function(el) { | ||
el.next = el.prev = el.parent = null; | ||
}); | ||
updateDOM(str, el); | ||
}); | ||
@@ -232,4 +258,5 @@ | ||
// Function support | ||
return this.each(function(i, el) { | ||
return this.text(str.call(el, i, this.text())); | ||
return domEach(this, function(i, el) { | ||
var $el = [el]; | ||
return text.call($el, str.call(el, i, $.text($el))); | ||
}); | ||
@@ -249,4 +276,7 @@ } | ||
domEach(this, function(i, el) { | ||
el.children = elem; | ||
updateDOM(el.children, el); | ||
_.each(el.children, function(el) { | ||
el.next = el.prev = el.parent = null; | ||
}); | ||
updateDOM(elem, el); | ||
}); | ||
@@ -253,0 +283,0 @@ |
@@ -54,2 +54,32 @@ var _ = require('lodash'), | ||
var parentsUntil = exports.parentsUntil = function(selector, filter) { | ||
var parentNodes = [], untilNode, untilNodes; | ||
if (typeof selector === 'string') { | ||
untilNode = select(selector, this.parents().toArray())[0]; | ||
} else if (selector && selector.cheerio) { | ||
untilNodes = selector.toArray(); | ||
} else if (selector) { | ||
untilNode = selector; | ||
} | ||
// When multiple DOM elements are in the original set, the resulting set will | ||
// be in *reverse* order of the original elements as well, with duplicates | ||
// removed. | ||
this.toArray().reverse().forEach(function(elem) { | ||
while ((elem = elem.parent)) { | ||
if ((untilNode && elem !== untilNode) || | ||
(untilNodes && untilNodes.indexOf(elem) === -1) || | ||
(!untilNode && !untilNodes)) { | ||
if (isTag(elem) && parentNodes.indexOf(elem) === -1) { parentNodes.push(elem); } | ||
} else { | ||
break; | ||
} | ||
} | ||
}, this); | ||
return this._make(filter ? select(filter, parentNodes) : parentNodes); | ||
}; | ||
// For each element in the set, get the first element that matches the selector | ||
@@ -238,3 +268,3 @@ // by testing the element itself and traversing up through its ancestors in the | ||
var i = 0, len = this.length; | ||
while (i < len && fn.call(this._make(this[i]), i, this[i]) !== false) ++i; | ||
while (i < len && fn.call(this[i], i, this[i]) !== false) ++i; | ||
return this; | ||
@@ -260,3 +290,3 @@ }; | ||
filterFn = function(el, i) { | ||
return match.call(make(el), i, el); | ||
return match.call(el, i, el); | ||
}; | ||
@@ -263,0 +293,0 @@ } else if (match.cheerio) { |
@@ -7,3 +7,2 @@ /* | ||
parse = require('./parse'), | ||
evaluate = parse.evaluate, | ||
_ = require('lodash'); | ||
@@ -15,3 +14,8 @@ | ||
var api = ['attributes', 'traversing', 'manipulation', 'css']; | ||
var api = [ | ||
require('./api/attributes'), | ||
require('./api/traversing'), | ||
require('./api/manipulation'), | ||
require('./api/css') | ||
]; | ||
@@ -34,5 +38,7 @@ /* | ||
var Cheerio = module.exports = function(selector, context, root) { | ||
if (!(this instanceof Cheerio)) return new Cheerio(selector, context, root); | ||
var Cheerio = module.exports = function(selector, context, root, options) { | ||
if (!(this instanceof Cheerio)) return new Cheerio(selector, context, root, options); | ||
this.options = _.defaults(options || {}, this.options); | ||
// $(), $(null), $(undefined), $(false) | ||
@@ -42,3 +48,3 @@ if (!selector) return this; | ||
if (root) { | ||
if (typeof root === 'string') root = parse(root); | ||
if (typeof root === 'string') root = parse(root, this.options); | ||
this._root = Cheerio.call(this, root); | ||
@@ -65,3 +71,3 @@ } | ||
if (typeof selector === 'string' && isHtml(selector)) { | ||
return Cheerio.call(this, parse(selector).children); | ||
return Cheerio.call(this, parse(selector, this.options).children); | ||
} | ||
@@ -75,3 +81,3 @@ | ||
// $('li', '<ul>...</ul>') | ||
context = parse(context); | ||
context = parse(context, this.options); | ||
context = Cheerio.call(this, context); | ||
@@ -83,4 +89,6 @@ } else { | ||
} | ||
} else if (isNode(context)) | ||
// $('li', node), $('li', [nodes]) | ||
} else if (!context.cheerio) { | ||
context = Cheerio.call(this, context); | ||
} | ||
@@ -113,3 +121,3 @@ // If we still don't have a context, return | ||
xmlMode: false, | ||
lowerCaseTags: false | ||
decodeEntities: false | ||
}; | ||
@@ -143,3 +151,3 @@ | ||
Cheerio.prototype._make = function(dom) { | ||
var cheerio = new Cheerio(dom); | ||
var cheerio = new Cheerio(dom, undefined, undefined, this.options); | ||
cheerio.prevObject = this; | ||
@@ -163,3 +171,3 @@ return cheerio; | ||
api.forEach(function(mod) { | ||
_.extend(Cheerio.prototype, require('./api/' + mod)); | ||
_.extend(Cheerio.prototype, mod); | ||
}); | ||
@@ -166,0 +174,0 @@ |
@@ -36,11 +36,13 @@ /* | ||
var handler = new htmlparser.DomHandler(options), | ||
parser = new htmlparser.Parser(handler, options); | ||
var dom; | ||
parser.write(content); | ||
parser.done(); | ||
if (_.isString(content)) { | ||
dom = htmlparser.parseDOM(content, options); | ||
} else { | ||
dom = content; | ||
} | ||
_.forEach(handler.dom, parseData); | ||
_.forEach(dom, parseData); | ||
return handler.dom; | ||
return dom; | ||
}; | ||
@@ -78,4 +80,8 @@ | ||
node.prev = arr[i - 1] || null; | ||
node.next = arr[i + 1] || null; | ||
if (parent) { | ||
node.prev = arr[i - 1] || null; | ||
node.next = arr[i + 1] || null; | ||
} else { | ||
node.prev = node.next = null; | ||
} | ||
@@ -82,0 +88,0 @@ if (parent && parent.type === 'root') { |
@@ -8,3 +8,4 @@ /** | ||
render = require('./render'), | ||
decode = require('./utils').decode; | ||
decode = require('./utils').decode, | ||
_ = require('lodash'); | ||
@@ -15,8 +16,12 @@ /** | ||
var load = exports.load = function(str, options) { | ||
var Cheerio = require('./cheerio'), | ||
root = parse(str, options); | ||
var load = exports.load = function(content, options) { | ||
var Cheerio = require('./cheerio'); | ||
var initialize = function(selector, context, r) { | ||
return new Cheerio(selector, context, r || root); | ||
options = _.defaults(options || {}, Cheerio.prototype.options); | ||
var root = parse(content, options); | ||
var initialize = function(selector, context, r, opts) { | ||
opts = _.defaults(opts || {}, options); | ||
return new Cheerio(selector, context, r || root, opts); | ||
}; | ||
@@ -23,0 +28,0 @@ |
{ | ||
"author": "Matt Mueller <mattmuelle@gmail.com> (mattmueller.me)", | ||
"name": "cheerio", | ||
"version": "0.15.0", | ||
"description": "Tiny, fast, and elegant implementation of core jQuery designed specifically for the server", | ||
"author": "Matt Mueller <mattmuelle@gmail.com> (mat.io)", | ||
"keywords": [ | ||
@@ -13,3 +14,2 @@ "htmlparser", | ||
], | ||
"version": "0.14.0", | ||
"repository": { | ||
@@ -39,2 +39,2 @@ "type": "git", | ||
} | ||
} | ||
} |
107
Readme.md
@@ -1,2 +0,2 @@ | ||
# cheerio [![Build Status](https://secure.travis-ci.org/MatthewMueller/cheerio.png?branch=master)](http://travis-ci.org/MatthewMueller/cheerio) | ||
# cheerio [![Build Status](https://secure.travis-ci.org/MatthewMueller/cheerio.svg?branch=master)](http://travis-ci.org/MatthewMueller/cheerio) | ||
@@ -267,2 +267,9 @@ Fast, flexible, and lean implementation of core jQuery designed specifically for the server. | ||
#### .parentsUntil([selector][,filter]) | ||
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. | ||
```js | ||
$('.orange').parentsUntil('#food').length | ||
// => 1 | ||
``` | ||
#### .closest(selector) | ||
@@ -678,43 +685,59 @@ 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. | ||
project : cheerio | ||
repo age : 2 years, 1 month | ||
active : 196 days | ||
commits : 591 | ||
files : 32 | ||
authors : | ||
293 Matt Mueller 49.6% | ||
102 Matthew Mueller 17.3% | ||
52 Mike Pennisi 8.8% | ||
47 David Chambers 8.0% | ||
15 Siddharth Mahendraker 2.5% | ||
11 Adam Bretz 1.9% | ||
7 ironchefpython 1.2% | ||
6 Jarno Leppänen 1.0% | ||
5 Ben Sheldon 0.8% | ||
5 Ryan Schmukler 0.8% | ||
5 Jos Shepherd 0.8% | ||
4 Maciej Adwent 0.7% | ||
4 Amir Abu Shareb 0.7% | ||
3 Felix Böhm 0.5% | ||
3 jeremy.dentel@brandingbrand.com 0.5% | ||
3 Andi Neck 0.5% | ||
2 alexbardas 0.3% | ||
2 Ali Farhadi 0.3% | ||
2 Thomas Heymann 0.3% | ||
2 Wayne Larsen 0.3% | ||
2 Rob Ashton 0.3% | ||
2 Chris Khoo 0.3% | ||
1 xiaohwan 0.2% | ||
1 Chris O'Hara 0.2% | ||
1 Felix Böhm 0.2% | ||
1 Jeremy Hubble 0.2% | ||
1 Manuel Alabor 0.2% | ||
1 Matt Liegey 0.2% | ||
1 Ben Atkin 0.2% | ||
1 Rich Trott 0.2% | ||
1 Rob "Hurricane" Ashton 0.2% | ||
1 Simon Boudrias 0.2% | ||
1 Sindre Sorhus 0.2% | ||
1 Timm Preetz 0.2% | ||
1 mattym 0.2% | ||
1 nevermind 0.2% | ||
repo age : 2 years, 6 months | ||
active : 285 days | ||
commits : 762 | ||
files : 36 | ||
authors : | ||
293 Matt Mueller 38.5% | ||
133 Matthew Mueller 17.5% | ||
92 Mike Pennisi 12.1% | ||
54 David Chambers 7.1% | ||
30 kpdecker 3.9% | ||
19 Felix Böhm 2.5% | ||
17 fb55 2.2% | ||
15 Siddharth Mahendraker 2.0% | ||
11 Adam Bretz 1.4% | ||
8 Nazar Leush 1.0% | ||
7 ironchefpython 0.9% | ||
6 Jarno Leppänen 0.8% | ||
5 Ben Sheldon 0.7% | ||
5 Jos Shepherd 0.7% | ||
5 Ryan Schmukler 0.7% | ||
5 Steven Vachon 0.7% | ||
4 Maciej Adwent 0.5% | ||
4 Amir Abu Shareb 0.5% | ||
3 jeremy.dentel@brandingbrand.com 0.4% | ||
3 Andi Neck 0.4% | ||
2 steve 0.3% | ||
2 alexbardas 0.3% | ||
2 finspin 0.3% | ||
2 Ali Farhadi 0.3% | ||
2 Chris Khoo 0.3% | ||
2 Rob Ashton 0.3% | ||
2 Thomas Heymann 0.3% | ||
2 Jaro Spisak 0.3% | ||
2 Dan Dascalescu 0.3% | ||
2 Torstein Thune 0.3% | ||
2 Wayne Larsen 0.3% | ||
1 Timm Preetz 0.1% | ||
1 Xavi 0.1% | ||
1 Alex Shaindlin 0.1% | ||
1 mattym 0.1% | ||
1 Felix Böhm 0.1% | ||
1 Farid Neshat 0.1% | ||
1 Dmitry Mazuro 0.1% | ||
1 Jeremy Hubble 0.1% | ||
1 nevermind 0.1% | ||
1 Manuel Alabor 0.1% | ||
1 Matt Liegey 0.1% | ||
1 Chris O'Hara 0.1% | ||
1 Michael Holroyd 0.1% | ||
1 Michiel De Mey 0.1% | ||
1 Ben Atkin 0.1% | ||
1 Rich Trott 0.1% | ||
1 Rob "Hurricane" Ashton 0.1% | ||
1 Robin Gloster 0.1% | ||
1 Simon Boudrias 0.1% | ||
1 Sindre Sorhus 0.1% | ||
1 xiaohwan 0.1% | ||
``` | ||
@@ -721,0 +744,0 @@ |
@@ -569,3 +569,3 @@ var expect = require('expect.js'); | ||
var result = $('li', fruits).is(function() { | ||
return this.hasClass('pear'); | ||
return this.name === 'li' && $(this).hasClass('pear'); | ||
}); | ||
@@ -572,0 +572,0 @@ expect(result).to.be(true); |
@@ -650,9 +650,42 @@ var expect = require('expect.js'), | ||
describe('.empty', function() { | ||
it('() : should remove all children from selected elements', function() { | ||
var $fruits = $(fruits); | ||
$('#fruits', $fruits).empty(); | ||
expect($('#fruits', $fruits).children()).to.have.length(0); | ||
expect($fruits.children()).to.have.length(3); | ||
$fruits.empty(); | ||
expect($fruits.children()).to.have.length(0); | ||
}); | ||
it('() : should allow element reinsertion', function() { | ||
var $fruits = $(fruits), | ||
$children = $fruits.children(); | ||
$fruits.empty(); | ||
expect($fruits.children()).to.have.length(0); | ||
expect($children).to.have.length(3); | ||
$fruits.append($('<div></div><div></div>')); | ||
var $remove = $fruits.children().eq(0), | ||
$keep = $fruits.children().eq(1); | ||
$remove.replaceWith($children); | ||
expect($fruits.children()).to.have.length(4); | ||
}); | ||
it('() : should destroy children\'s references to the parent', function() { | ||
var $fruits = $(fruits); | ||
var $children = $fruits.children(); | ||
$fruits.empty(); | ||
expect($children.eq(0).parent()).to.have.length(0); | ||
expect($children.eq(0).next()).to.have.length(0); | ||
expect($children.eq(0).prev()).to.have.length(0); | ||
expect($children.eq(1).parent()).to.have.length(0); | ||
expect($children.eq(1).next()).to.have.length(0); | ||
expect($children.eq(1).prev()).to.have.length(0); | ||
expect($children.eq(2).parent()).to.have.length(0); | ||
expect($children.eq(2).next()).to.have.length(0); | ||
expect($children.eq(2).prev()).to.have.length(0); | ||
}); | ||
}); | ||
@@ -695,2 +728,14 @@ | ||
it('() : should allow element reinsertion', function() { | ||
var $fruits = $(fruits), | ||
$children = $fruits.children(); | ||
$fruits.html('<div></div><div></div>'); | ||
expect($fruits.children()).to.have.length(2); | ||
var $remove = $fruits.children().eq(0), | ||
$keep = $fruits.children().eq(1); | ||
$remove.replaceWith($children); | ||
expect($fruits.children()).to.have.length(4); | ||
}); | ||
}); | ||
@@ -697,0 +742,0 @@ |
@@ -402,2 +402,3 @@ var expect = require('expect.js'), | ||
describe('.parents', function() { | ||
it('() : should get all of the parents in logical order', function(){ | ||
@@ -412,2 +413,3 @@ var result = $('.orange', food).parents(); | ||
}); | ||
it('(selector) : should get all of the parents that match the selector in logical order', function() { | ||
@@ -422,2 +424,3 @@ var result = $('.orange', food).parents('#fruits'); | ||
}); | ||
it('() : should not break if the selector does not have any results', function() { | ||
@@ -427,2 +430,3 @@ var result = $('.saladbar', food).parents(); | ||
}); | ||
it('() : should return an empty set for top-level elements', function() { | ||
@@ -432,2 +436,3 @@ var result = $('#food', food).parents(); | ||
}); | ||
it('() : should return the parents of every element in the *reveresed* collection, omitting duplicates', function() { | ||
@@ -442,4 +447,64 @@ var $food = $(food); | ||
}); | ||
}); | ||
describe('.parentsUntil', function() { | ||
it('() : should get all of the parents in logical order', function() { | ||
var result = $('.orange', food).parentsUntil(); | ||
expect(result).to.have.length(2); | ||
expect(result[0].attribs.id).to.be('fruits'); | ||
expect(result[1].attribs.id).to.be('food'); | ||
}); | ||
it('() : should get all of the parents in reversed order, omitting duplicates', function() { | ||
var result = $('.apple, .sweetcorn', food).parentsUntil(); | ||
expect(result).to.have.length(3); | ||
expect(result[0].attribs.id).to.be('vegetables'); | ||
expect(result[1].attribs.id).to.be('food'); | ||
expect(result[2].attribs.id).to.be('fruits'); | ||
}); | ||
it('(selector) : should get all of the parents until selector', function() { | ||
var result = $('.orange', food).parentsUntil('#food'); | ||
expect(result).to.have.length(1); | ||
expect(result[0].attribs.id).to.be('fruits'); | ||
result = $('.orange', food).parentsUntil('#fruits'); | ||
expect(result).to.have.length(0); | ||
}); | ||
it('(selector not parent) : should return all parents', function() { | ||
var result = $('.orange', food).parentsUntil('.apple'); | ||
expect(result).to.have.length(2); | ||
expect(result[0].attribs.id).to.be('fruits'); | ||
expect(result[1].attribs.id).to.be('food'); | ||
}); | ||
it('(selector, filter) : should get all of the parents that match the filter', function() { | ||
var result = $('.apple, .sweetcorn', food).parentsUntil('.saladbar', '#vegetables'); | ||
expect(result).to.have.length(1); | ||
expect(result[0].attribs.id).to.be('vegetables'); | ||
}); | ||
it('() : should return empty object when called on an empty object', function() { | ||
var result = $('.saladbar', food).parentsUntil(); | ||
expect(result).to.have.length(0); | ||
}); | ||
it('() : should return an empty set for top-level elements', function() { | ||
var result = $('#food', food).parentsUntil(); | ||
expect(result).to.have.length(0); | ||
}); | ||
it('(cheerio object) : should return all parents until any member of the cheerio object', function() { | ||
var $food = $(food); | ||
var $fruits = $(fruits); | ||
var $until = $($food[0]); | ||
var result = $fruits.children().eq(1).parentsUntil($until); | ||
expect(result).to.have.length(1); | ||
expect(result[0].attribs.id).to.be('fruits'); | ||
}); | ||
}); | ||
describe('.parent', function() { | ||
@@ -515,3 +580,3 @@ | ||
items[idx] = elem; | ||
expect(this[0].attribs['class']).to.equal(classes[idx]); | ||
expect(this.attribs['class']).to.equal(classes[idx]); | ||
}); | ||
@@ -636,6 +701,6 @@ expect(items[0].attribs['class']).to.equal('apple'); | ||
var orange = $('li', fruits).filter(function(i, el) { | ||
expect(this[0]).to.be(el); | ||
expect(this).to.be(el); | ||
expect(el.name).to.be('li'); | ||
expect(i).to.be.a('number'); | ||
return this.attr('class') === 'orange'; | ||
return $(this).attr('class') === 'orange'; | ||
}).text(); | ||
@@ -642,0 +707,0 @@ |
var expect = require('expect.js'), | ||
_ = require('lodash'), | ||
htmlparser2 = require('htmlparser2'), | ||
$ = require('../'), | ||
@@ -104,2 +105,12 @@ fixtures = require('./fixtures'), | ||
it('should accept a node reference as a context', function() { | ||
var $elems = $('<div><span></span></div>'); | ||
expect($('span', $elems[0])).to.have.length(1); | ||
}); | ||
it('should accept an array of node references as a context', function() { | ||
var $elems = $('<div><span></span></div>'); | ||
expect($('span', $elems.toArray())).to.have.length(1); | ||
}); | ||
it('should select only elements inside given context (Issue #193)', function() { | ||
@@ -113,2 +124,9 @@ var q = $.load(food), | ||
it('should allow loading a pre-parsed DOM', function() { | ||
var dom = htmlparser2.parseDOM(food), | ||
q = $.load(dom); | ||
expect(q('ul')).to.have.length(3); | ||
}); | ||
it('should be able to select multiple tags', function() { | ||
@@ -115,0 +133,0 @@ var $fruits = $('li', null, fruits); |
@@ -11,2 +11,7 @@ var expect = require('expect.js'), | ||
var dom = function(str, options) { | ||
var $ = cheerio.load('', options); | ||
return $(str).html(); | ||
}; | ||
describe('render', function() { | ||
@@ -28,2 +33,24 @@ | ||
describe('(dom)', function () { | ||
it('should keep camelCase for new nodes', function() { | ||
var str = '<g><someElem someAttribute="something">hello</someElem></g>'; | ||
expect(dom(str, {xmlMode: false})).to.equal('<someelem someattribute="something">hello</someelem>'); | ||
}); | ||
it('should keep camelCase for new nodes', function() { | ||
var str = '<g><someElem someAttribute="something">hello</someElem></g>'; | ||
expect(dom(str, {xmlMode: true})).to.equal('<someElem someAttribute="something">hello</someElem>'); | ||
}); | ||
it('should maintain the parsing options of distinct contexts independently', function() { | ||
var str = '<g><someElem someAttribute="something">hello</someElem></g>'; | ||
var $x = cheerio.load('', { xmlMode: false }); | ||
var $h = cheerio.load('', { xmlMode: true }); | ||
expect($x(str).html()).to.equal('<someelem someattribute="something">hello</someelem>'); | ||
}); | ||
}); | ||
}); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
191122
4045
780
0
0