Comparing version 0.11.0 to 0.12.0
0.12.0 / 2013-06-09 | ||
=================== | ||
* Breaking Change: Changed context from parent to the actual passed one (@swissmanu) | ||
* Fixed: jquery checkbox val behavior (@jhubble) | ||
* Added: output xml with $.xml() (@Maciek416) | ||
* Bumped: htmlparser2 to 3.1.1 | ||
* Fixed: bug in attr(key, val) on empty objects (@farhadi) | ||
* Added: prevAll, nextAll (@lessmind) | ||
* Fixed: Safety check in parents and closest (@zero21xxx) | ||
* Added: .is(sel) (@zero21xxx) | ||
0.11.0 / 2013-04-22 | ||
@@ -3,0 +15,0 @@ ================== |
@@ -25,2 +25,9 @@ var _ = require('underscore'), | ||
var attr = exports.attr = function(name, value) { | ||
// Set the value (with attr map support) | ||
if (typeof name === 'object' || value !== undefined) { | ||
return this.each(function(i, el) { | ||
el.attribs = setAttr(el, name, value); | ||
}); | ||
} | ||
var elem = this[0]; | ||
@@ -42,9 +49,3 @@ | ||
// Set the value (with attr map support) | ||
if (typeof name === 'object' || value !== undefined) { | ||
this.each(function(i, el) { | ||
el.attribs = setAttr(el, name, value); | ||
}); | ||
return this; | ||
} else if (Object.hasOwnProperty.call(elem.attribs, name)) { | ||
if (Object.prototype.hasOwnProperty.call(elem.attribs, name)) { | ||
// Get the (decoded) attribute | ||
@@ -87,8 +88,2 @@ return decode(elem.attribs[name]); | ||
break; | ||
case 'checkbox': | ||
//@todo wwjd (what would jquery do) | ||
if (this.attr().hasOwnProperty('checked')) { | ||
return this.attr('value'); | ||
} | ||
return null; | ||
default: | ||
@@ -223,1 +218,9 @@ return querying ? this.attr('value') : this.each(function() { | ||
}; | ||
var is = exports.is = function (selector) { | ||
if (selector) { | ||
return this.filter(selector).length > 0; | ||
} | ||
return false; | ||
} | ||
@@ -18,8 +18,14 @@ var _ = require('underscore'), | ||
var parents = exports.parents = function(selector) { | ||
var elems = traverseParents(this, this[0].parent, selector, Infinity); | ||
return elems.length ? elems : this; | ||
if (this[0] && this[0].parent) { | ||
var elems = traverseParents(this, this[0].parent, selector, Infinity); | ||
return elems.length ? elems : this; | ||
} | ||
return this; | ||
}; | ||
var closest = exports.closest = function(selector) { | ||
return selector ? traverseParents(this, this[0], selector, 1) : []; | ||
if (this[0] && selector) { | ||
return traverseParents(this, this[0], selector, 1) | ||
} | ||
return []; | ||
}; | ||
@@ -33,2 +39,8 @@ | ||
var nextAll = exports.nextAll = function(selector) { | ||
var elems = [], elem = this[0]; | ||
while ((elem = elem.next)) if (isTag(elem)) elems.push(elem); | ||
return this.make(selector ? select(selector, elems) : elems); | ||
}; | ||
var prev = exports.prev = function() { | ||
@@ -40,2 +52,8 @@ var elem = this[0]; | ||
var prevAll = exports.prevAll = function(selector) { | ||
var elems = [], elem = this[0]; | ||
while ((elem = elem.prev)) if (isTag(elem)) elems.push(elem); | ||
return this.make(selector ? select(selector, elems) : elems); | ||
}; | ||
var siblings = exports.siblings = function(selector) { | ||
@@ -42,0 +60,0 @@ var elems = _.filter( |
@@ -76,3 +76,3 @@ /* | ||
// #id, .class, tag | ||
return context.parent().find(selector); | ||
return context.find(selector); | ||
}; | ||
@@ -79,0 +79,0 @@ |
@@ -78,3 +78,3 @@ /* | ||
if (tagType[elem.type]) | ||
pushVal = renderTag(elem); | ||
pushVal = renderTag(elem, xmlMode); | ||
else if (elem.type === 'directive') | ||
@@ -93,4 +93,7 @@ pushVal = renderDirective(elem); | ||
if ((!singleTag[elem.name] || xmlMode) && tagType[elem.type]) | ||
output.push('</' + elem.name + '>'); | ||
if ((!singleTag[elem.name] || xmlMode) && tagType[elem.type]) { | ||
if (!isClosedTag(elem, xmlMode)) { | ||
output.push('</' + elem.name + '>'); | ||
} | ||
} | ||
}); | ||
@@ -101,3 +104,7 @@ | ||
var renderTag = function(elem) { | ||
var isClosedTag = function(elem, xmlMode){ | ||
return (xmlMode && (!elem.children || elem.children.length === 0)); | ||
} | ||
var renderTag = function(elem, xmlMode) { | ||
var tag = '<' + elem.name; | ||
@@ -108,2 +115,6 @@ | ||
} | ||
if (isClosedTag(elem, xmlMode)) { | ||
tag += '/'; | ||
} | ||
@@ -110,0 +121,0 @@ return tag + '>'; |
@@ -47,2 +47,17 @@ /** | ||
/** | ||
* $.xml([selector | dom]) | ||
*/ | ||
var xml = exports.xml = function(dom) { | ||
if (dom) { | ||
dom = (typeof dom === 'string') ? select(dom, this._root) : dom; | ||
return render(dom, { xmlMode: true }); | ||
} else if (this._root && this._root.children) { | ||
return render(this._root.children, { xmlMode: true }); | ||
} else { | ||
return ''; | ||
} | ||
}; | ||
/** | ||
* $.text(dom) | ||
@@ -49,0 +64,0 @@ */ |
@@ -6,3 +6,3 @@ { | ||
"keywords": ["htmlparser", "jquery", "selector", "scraper"], | ||
"version": "0.11.0", | ||
"version": "0.12.0", | ||
"repository": { | ||
@@ -18,3 +18,3 @@ "type": "git", | ||
"cheerio-select" : "*", | ||
"htmlparser2" : "2.x", | ||
"htmlparser2" : "3.1.1", | ||
"underscore" : "~1.4", | ||
@@ -21,0 +21,0 @@ "entities" : "0.x" |
@@ -204,3 +204,7 @@ # cheerio [![Build Status](https://secure.travis-ci.org/MatthewMueller/cheerio.png?branch=master)](http://travis-ci.org/MatthewMueller/cheerio) | ||
#### .is( selector ) | ||
#### .is( function(index) ) | ||
Checks the current list of elements and returns `true` if _any_ of the elements match the selector. If using a predicate function, the function is executed in the context of the selected element, so `this` refers to the current element. | ||
### Traversing | ||
@@ -255,2 +259,10 @@ | ||
#### .nextAll() | ||
Gets all the following siblings of the first selected element. | ||
```js | ||
$('.apple').nextAll() | ||
//=> [<li class="orange">Orange</li>, <li class="pear">Pear</li>] | ||
``` | ||
#### .prev() | ||
@@ -264,2 +276,10 @@ Gets the previous sibling of the first selected element. | ||
#### .prevAll() | ||
Gets all the preceding siblings of the first selected element. | ||
```js | ||
$('.pear').prevAll() | ||
//=> [<li class="orange">Orange</li>, <li class="apple">Apple</li>] | ||
``` | ||
#### .slice( start, [end] ) | ||
@@ -491,3 +511,3 @@ Gets the elements matching the specified range | ||
### Rendering | ||
When you're ready to render the document, you can use `html` utility function: | ||
When you're ready to render the document, you can use the `html` utility function: | ||
@@ -510,2 +530,16 @@ ```js | ||
By default, `html` will leave some tags open. Sometimes you may instead want to render a valid XML document. For example, you might parse the following XML snippet: | ||
```xml | ||
$ = cheerio.load('<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>'); | ||
``` | ||
... and later want to render to XML. To do this, you can use the 'xml' utility function: | ||
```js | ||
$.xml() | ||
//=> <media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/> | ||
``` | ||
### Miscellaneous | ||
@@ -570,23 +604,28 @@ DOM element methods that don't fit anywhere else | ||
project : cheerio | ||
repo age : 1 year, 4 months ago | ||
commits : 416 | ||
active : 118 days | ||
files : 26 | ||
repo age : 1 year, 7 months ago | ||
commits : 474 | ||
active : 141 days | ||
files : 27 | ||
authors : | ||
278 Matt Mueller 66.8% | ||
68 Matthew Mueller 16.3% | ||
27 David Chambers 6.5% | ||
15 Siddharth Mahendraker 3.6% | ||
7 ironchefpython 1.7% | ||
5 Jos Shepherd 1.2% | ||
5 Ben Sheldon 1.2% | ||
2 alexbardas 0.5% | ||
2 Rob Ashton 0.5% | ||
286 Matt Mueller 60.3% | ||
80 Matthew Mueller 16.9% | ||
42 David Chambers 8.9% | ||
15 Siddharth Mahendraker 3.2% | ||
7 Adam Bretz 1.5% | ||
7 ironchefpython 1.5% | ||
6 Mike Pennisi 1.3% | ||
5 Jos Shepherd 1.1% | ||
5 Ryan Schmukler 1.1% | ||
5 Ben Sheldon 1.1% | ||
3 jeremy.dentel 0.6% | ||
2 alexbardas 0.4% | ||
2 Rob Ashton 0.4% | ||
2 Wayne Larsen 0.4% | ||
1 mattym 0.2% | ||
1 Ben Atkin 0.2% | ||
1 Chris O'Hara 0.2% | ||
1 Mike Pennisi 0.2% | ||
1 Felix Böhm 0.2% | ||
1 Rob "Hurricane" Ashton 0.2% | ||
1 Simon Boudrias 0.2% | ||
1 Sindre Sorhus 0.2% | ||
1 Wayne Larsen 0.2% | ||
1 Ben Atkin 0.2% | ||
``` | ||
@@ -593,0 +632,0 @@ |
@@ -34,2 +34,8 @@ var expect = require('expect.js'); | ||
it('(key, value) : should return an empty object for an empty object', function() { | ||
var $src = $().attr('key', 'value'); | ||
expect($src.length).to.equal(0); | ||
expect($src[0]).to.be(undefined); | ||
}); | ||
it('(map) : object map should set multiple attributes', function() { | ||
@@ -57,3 +63,3 @@ var $fruits = $(fruits); | ||
}); | ||
it('(key, value) : should coerce values to a string', function() { | ||
@@ -64,3 +70,3 @@ var $apple = $('.apple', fruits); | ||
expect($apple.attr('data-test')).to.equal('1'); | ||
}); | ||
}); | ||
}); | ||
@@ -81,5 +87,5 @@ | ||
}); | ||
it('.val(): on unchecked checkbox should get null', function() { | ||
it('.val(): on unchecked checkbox should get value', function() { | ||
var val = $('input[name="checkbox_off"]', inputs).val(); | ||
expect(val).to.equal(null); | ||
expect(val).to.equal('off'); | ||
}); | ||
@@ -116,3 +122,3 @@ it('.val(): on radio should get value', function() { | ||
var $fruits = $(fruits); | ||
expect($('ul', $fruits).attr('id')).to.not.be(undefined); | ||
expect($('ul', $fruits.parent()).attr('id')).to.not.be(undefined); | ||
$('ul', $fruits).removeAttr('id'); | ||
@@ -161,4 +167,4 @@ expect($('ul', $fruits).attr('id')).to.be(undefined); | ||
var $fruits = $(fruits); | ||
$('#fruits', $fruits).addClass('fruits'); | ||
var cls = $('#fruits', $fruits).hasClass('fruits'); | ||
$fruits.addClass('fruits'); | ||
var cls = $fruits.hasClass('fruits'); | ||
expect(cls).to.be.ok(); | ||
@@ -266,2 +272,26 @@ }); | ||
describe('.is', function () { | ||
it('() should return false', function () { | ||
expect($('li.apple', fruits).is()).to.be(false) | ||
}) | ||
it('(true selector) should return true', function () { | ||
expect($('#vegetables', vegetables).is('ul')).to.be(true) | ||
}) | ||
it('(false selector) should return false', function () { | ||
expect($('#vegetables', vegetables).is('div')).to.be(false) | ||
}) | ||
it('(true predicate) should return true', function () { | ||
var result = $('li', fruits).is(function() { | ||
return this.hasClass('pear') | ||
}) | ||
expect(result).to.be(true) | ||
}) | ||
it('(false predicate) should return false', function () { | ||
var result = $('li', fruits).last().is(function() { | ||
return this.name === 'ul' | ||
}) | ||
expect(result).to.be(false) | ||
}) | ||
}) | ||
}); |
@@ -15,4 +15,4 @@ var expect = require('expect.js'), | ||
var $fruits = $(fruits); | ||
$('#fruits', $fruits).append('<li class="plum">Plum</li>'); | ||
expect($('#fruits', $fruits).children(3).hasClass('plum')).to.be.ok(); | ||
$fruits.append('<li class="plum">Plum</li>'); | ||
expect($fruits.children(3).hasClass('plum')).to.be.ok(); | ||
}); | ||
@@ -23,4 +23,4 @@ | ||
var $plum = $('<li class="plum">Plum</li>'); | ||
$('#fruits', $fruits).append($plum); | ||
expect($('#fruits', $fruits).children(3).hasClass('plum')).to.be.ok(); | ||
$fruits.append($plum); | ||
expect($fruits.children(3).hasClass('plum')).to.be.ok(); | ||
}); | ||
@@ -32,5 +32,5 @@ | ||
var grape = '<li class="grape">Grape</li>'; | ||
$('#fruits', $fruits).append($plum, grape); | ||
expect($('#fruits', $fruits).children(3).hasClass('plum')).to.be.ok(); | ||
expect($('#fruits', $fruits).children(4).hasClass('grape')).to.be.ok(); | ||
$fruits.append($plum, grape); | ||
expect($fruits.children(3).hasClass('plum')).to.be.ok(); | ||
expect($fruits.children(4).hasClass('grape')).to.be.ok(); | ||
}); | ||
@@ -59,4 +59,4 @@ | ||
var $fruits = $(fruits); | ||
$('#fruits', $fruits).prepend('<li class="plum">Plum</li>'); | ||
expect($('#fruits', $fruits).children(0).hasClass('plum')).to.be.ok(); | ||
$fruits.prepend('<li class="plum">Plum</li>'); | ||
expect($fruits.children(0).hasClass('plum')).to.be.ok(); | ||
}); | ||
@@ -67,4 +67,4 @@ | ||
var $plum = $('<li class="plum">Plum</li>'); | ||
$('#fruits', $fruits).prepend($plum); | ||
expect($('#fruits', $fruits).children(0).hasClass('plum')).to.be.ok(); | ||
$fruits.prepend($plum); | ||
expect($fruits.children(0).hasClass('plum')).to.be.ok(); | ||
}); | ||
@@ -76,5 +76,5 @@ | ||
var grape = '<li class="grape">Grape</li>'; | ||
$('#fruits', $fruits).prepend($plum, grape); | ||
expect($('#fruits', $fruits).children(0).hasClass('plum')).to.be.ok(); | ||
expect($('#fruits', $fruits).children(1).hasClass('grape')).to.be.ok(); | ||
$fruits.prepend($plum, grape); | ||
expect($fruits.children(0).hasClass('plum')).to.be.ok(); | ||
expect($fruits.children(1).hasClass('grape')).to.be.ok(); | ||
}); | ||
@@ -220,3 +220,3 @@ | ||
var $fruits = $(fruits); | ||
expect($('#fruits', $fruits).html()).to.equal([ | ||
expect($fruits.html()).to.equal([ | ||
'<li class="apple">Apple</li>', | ||
@@ -240,4 +240,4 @@ '<li class="orange">Orange</li>', | ||
var $fruits = $(fruits); | ||
$('#fruits', $fruits).html('<li class="durian">Durian</li>'); | ||
var html = $('#fruits', $fruits).html(); | ||
$fruits.html('<li class="durian">Durian</li>'); | ||
var html = $fruits.html(); | ||
expect(html).to.equal('<li class="durian">Durian</li>'); | ||
@@ -248,4 +248,4 @@ }); | ||
var $fruits = $(fruits); | ||
$('#fruits', $fruits).html($('<li class="durian">Durian</li>')); | ||
var html = $('#fruits', $fruits).html(); | ||
$fruits.html($('<li class="durian">Durian</li>')); | ||
var html = $fruits.html(); | ||
expect(html).to.equal('<li class="durian">Durian</li>'); | ||
@@ -252,0 +252,0 @@ }); |
@@ -82,2 +82,17 @@ var expect = require('expect.js'), | ||
describe('.nextAll', function() { | ||
it('() : should return all following siblings', function() { | ||
var elems = $('.apple', fruits).nextAll(); | ||
expect(elems).to.have.length(2); | ||
expect(elems[0].attribs['class']).to.equal('orange'); | ||
expect(elems[1].attribs['class']).to.equal('pear'); | ||
}); | ||
it('(no next) : should return empty for last child', function() { | ||
expect($('.pear', fruits).nextAll()).to.have.length(0); | ||
}); | ||
}); | ||
describe('.prev', function() { | ||
@@ -96,2 +111,17 @@ | ||
describe('.prevAll', function() { | ||
it('() : should return all preceding siblings', function() { | ||
var elems = $('.pear', fruits).prevAll(); | ||
expect(elems).to.have.length(2); | ||
expect(elems[0].attribs['class']).to.equal('orange'); | ||
expect(elems[1].attribs['class']).to.equal('apple'); | ||
}); | ||
it('(no prev) : should return empty for first child', function() { | ||
expect($('.apple', fruits).prevAll()).to.have.length(0); | ||
}); | ||
}); | ||
describe('.siblings', function() { | ||
@@ -138,2 +168,6 @@ | ||
}) | ||
it('() : should not break if the selector does not have any results', function() { | ||
var result = $('.saladbar', food).parents(); | ||
expect(result).to.have.length(0); | ||
}) | ||
}); | ||
@@ -158,2 +192,7 @@ | ||
it('() : should not break if the selector does not have any results', function() { | ||
var result = $('.saladbar', food).closest('ul'); | ||
expect(result).to.have.length(0); | ||
}) | ||
}); | ||
@@ -160,0 +199,0 @@ |
var expect = require('expect.js'), | ||
_ = require('underscore'), | ||
$ = require('../'), | ||
fruits = require('./fixtures').fruits; | ||
fixtures = require('./fixtures'), | ||
fruits = fixtures.fruits, | ||
food = fixtures.food; | ||
@@ -90,2 +92,10 @@ // HTML | ||
it('should select only elements inside given context (Issue #193)', function() { | ||
var q = $.load(food), | ||
fruits = q('#fruits'), | ||
fruitElements = q('li', fruits); | ||
expect(fruitElements).to.have.length(3); | ||
}); | ||
it('should be able to select multiple tags', function() { | ||
@@ -131,3 +141,3 @@ var $fruits = $('li', null, fruits); | ||
}); | ||
testAppleSelect($($apple)); | ||
testAppleSelect($apple); | ||
expect($fruits[0].attribs.id).to.equal('fruits'); | ||
@@ -143,5 +153,6 @@ }); | ||
it('should be able to select immediate children: $("#fruits > .pear")', function() { | ||
var $fruitsWithMorePear = $('.pear', fruits).append('<li class="pear">Another Pear!</li>'); | ||
expect($('#fruits .pear', $fruitsWithMorePear)).to.have.length(2); | ||
var $elem = $('#fruits > .pear', $fruitsWithMorePear); | ||
var $food = $(food); | ||
$('.pear', $food).append('<li class="pear">Another Pear!</li>'); | ||
expect($('#fruits .pear', $food)).to.have.length(2); | ||
var $elem = $('#fruits > .pear', $food); | ||
expect($elem).to.have.length(1); | ||
@@ -148,0 +159,0 @@ expect($elem.attr('class')).to.equal('pear'); |
109900
27
2252
664
+ Addedcore-util-is@1.0.3(transitive)
+ Addeddomutils@1.1.6(transitive)
+ Addedhtmlparser2@3.1.1(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedisarray@0.0.1(transitive)
+ Addedreadable-stream@1.0.34(transitive)
+ Addedstring_decoder@0.10.31(transitive)
- Removeddomutils@1.0.1(transitive)
- Removedhtmlparser2@2.6.0(transitive)
Updatedhtmlparser2@3.1.1