Permalink
Browse files

Complete `$.prototype.find`

Implement the two absent signatures of the `find` method.
  • Loading branch information...
1 parent 99d44da commit 1429e2117f7ff8ac5dac2bd6d60cfb00f4cfe5ee @jugglinmike jugglinmike committed Jun 28, 2014
Showing with 68 additions and 3 deletions.
  1. +5 −1 Readme.md
  2. +21 −2 lib/api/traversing.js
  3. +42 −0 test/api.traversing.js
View
@@ -242,11 +242,15 @@ Checks the current list of elements and returns `true` if _any_ of the elements
### Traversing
#### .find(selector)
-Get a set of descendants filtered by `selector` of each element in the current set of matched elements.
+#### .find(selection)
+#### .find(node)
+Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
```js
$('#fruits').find('li').length
//=> 3
+$('#fruits').find($('.apple')).length
+//=> 1
```
#### .parent([selector])
View
@@ -5,12 +5,31 @@ var _ = require('lodash'),
uniqueSort = require('htmlparser2').DomUtils.uniqueSort,
isTag = utils.isTag;
-exports.find = function(selector) {
+exports.find = function(selectorOrHaystack) {
var elems = _.reduce(this, function(memo, elem) {
return memo.concat(_.filter(elem.children, isTag));
}, []);
+ var contains = this.constructor.contains;
+ var haystack;
+
+ if (selectorOrHaystack && typeof selectorOrHaystack !== 'string') {
+ if (selectorOrHaystack.cheerio) {
+ haystack = selectorOrHaystack.get();
+ } else {
+ haystack = [selectorOrHaystack];
+ }
+
+ return this._make(haystack.filter(function(elem) {
+ var idx, len;
+ for (idx = 0, len = this.length; idx < len; ++idx) {
+ if (contains(this[idx], elem)) {
+ return true;
+ }
+ }
+ }, this));
+ }
- return this._make(select(selector, elems, this.options));
+ return this._make(select(selectorOrHaystack, elems, this.options));
};
// Get the parent of each element in the current set of matched elements,
View
@@ -63,6 +63,48 @@ describe('$(...)', function() {
});
});
+ describe('(cheerio object) :', function() {
+ it('returns only those nodes contained within the current selection', function() {
+ var $ = cheerio.load(food);
+ var $selection = $('#fruits').find($('li'));
+
+ expect($selection).to.have.length(3);
+ expect($selection[0]).to.be($('.apple')[0]);
+ expect($selection[1]).to.be($('.orange')[0]);
+ expect($selection[2]).to.be($('.pear')[0]);
+ });
+ it('returns only those nodes contained within any element in the current selection', function() {
+ var $ = cheerio.load(food);
+ var $selection = $('.apple, #vegetables').find($('li'));
+
+ expect($selection).to.have.length(2);
+ expect($selection[0]).to.be($('.carrot')[0]);
+ expect($selection[1]).to.be($('.sweetcorn')[0]);
+ });
+ });
+
+ describe('(node) :', function() {
+ it('returns node when contained within the current selection', function() {
+ var $ = cheerio.load(food);
+ var $selection = $('#fruits').find($('.apple')[0]);
+
+ expect($selection).to.have.length(1);
+ expect($selection[0]).to.be($('.apple')[0]);
+ });
+ it('returns node when contained within any element the current selection', function() {
+ var $ = cheerio.load(food);
+ var $selection = $('#fruits, #vegetables').find($('.carrot')[0]);
+
+ expect($selection).to.have.length(1);
+ expect($selection[0]).to.be($('.carrot')[0]);
+ });
+ it('does not return node that is not contained within the current selection', function() {
+ var $ = cheerio.load(food);
+ var $selection = $('#fruits').find($('.carrot')[0]);
+
+ expect($selection).to.have.length(0);
+ });
+ });
});
describe('.children', function() {

0 comments on commit 1429e21

Please sign in to comment.