Skip to content

Commit

Permalink
fix fn.closest() and add context argument
Browse files Browse the repository at this point in the history
old implementation started from the parent, while the correct
implementation should start from the current element
  • Loading branch information
mislav committed Dec 28, 2010
1 parent dbe33a2 commit 116c79b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.rdoc
Expand Up @@ -47,7 +47,7 @@ Context and .find calls are equivalent:
last(): new collection containing only the last matched element

find('selector'): find all children/grandchildren that match the given selector
closest('selector'): traverses the DOM upwards to find the first matching element
closest('selector'): find the first matching element by going upwards starting from the current element
next(): next siblings
prev(): previous siblings
is('selector'): returns true/false if first element matches the selector
Expand Down
9 changes: 5 additions & 4 deletions src/zepto.js
Expand Up @@ -66,10 +66,11 @@ var Zepto = (function() {
find: function(selector){
return $(this.dom.map(function(el){ return $$(el, selector) }).reduce(function(a,b){ return a.concat(b) }, []));
},
closest: function(selector){
var node = this.dom[0].parentNode, nodes = $$(document, selector);
while(node && nodes.indexOf(node) < 0) node = node.parentNode;
return $(node && !(node === document) ? node : []);
closest: function(selector, context){
var node = this.dom[0], nodes = $$(context !== undefined ? context : document, selector);
if (nodes.length === 0) node = null;
while(node && node !== document && nodes.indexOf(node) < 0) node = node.parentNode;
return $(node);
},
pluck: function(property){ return this.dom.map(function(element){ return element[property] }) },
show: function(){ return this.css('display', 'block') },
Expand Down
28 changes: 23 additions & 5 deletions test/zepto.html
Expand Up @@ -51,10 +51,12 @@ <h1>Zepto DOM unit tests</h1>

<div style="position:absolute;width:100px;height:50px" id="offset">test</div>

<ul>
<ul id="parents">
<li id="li1">
<ul>
<li id="li2">
<ul id="nested">
<li id="li2">one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
</ul>
Expand Down Expand Up @@ -121,6 +123,16 @@ <h1>Zepto DOM unit tests</h1>
'Expected length %d, got %d.', expected, actual);
}

Evidence.Assertions.assertEqualCollection = function(expectedCollection, actualCollection, message) {
var expected = expectedCollection.get(), actual = actualCollection.get(),
passed = expected.length == actual.length;

if (passed) for (var i=0; i<expected.length; i++) passed = expected[i] == actual[i];

this._assertExpression(passed, message || 'Failed assertion.',
'Expected %o, got %o.', expected, actual);
}

Evidence.TestCase.extend('ZeptoTest', {

// test to see if we augment iOS 3.2 with String#trim()
Expand Down Expand Up @@ -320,8 +332,14 @@ <h1>Zepto DOM unit tests</h1>
},

testClosest: function(t){
t.assertIdentical($('#li1').get(0), $('#li2').closest('li').get(0));
t.assertLength(0, $('#li2').closest('div'));
var el = $('#li2');
t.assertEqualCollection(el, el.closest('li'));
t.assertEqualCollection($('#nested'), el.closest('ul'));
// with context
t.assertEqualCollection($('#nested'), el.closest('ul', $('#li1').get(0)));
t.assertLength(0, el.closest('#parents', $('#li1').get(0)));
// no ancestor matched
t.assertLength(0, el.closest('div'));
},

testFind: function(t){
Expand Down

0 comments on commit 116c79b

Please sign in to comment.