Commit 4c3aba9a authored by jaubourg's avatar jaubourg

Merge branch 'master' of github.com:jquery/jquery

parents 3411d47a 56ffad2d
...@@ -56,6 +56,89 @@ Sometimes, the various git repositories get into an inconsistent state where bui ...@@ -56,6 +56,89 @@ Sometimes, the various git repositories get into an inconsistent state where bui
(usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then (usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then
run `make` again. run `make` again.
Git for dummies
---------------
As the source code is handled by the version control system Git, it's useful to know some features used.
### Submodules ###
The repository uses submodules, which normally are handles directly by the Makefile, but sometimes you want to
be able to work with them manually.
Following are the steps to manually get the submodules:
1. `git clone https://github.com/jquery/jquery.git`
2. `git submodule init`
3. `git submodule update`
Or:
1. `git clone https://github.com/jquery/jquery.git`
2. `git submodule update --init`
Or:
1. `git clone --recursive https://github.com/jquery/jquery.git`
If you want to work inside a submodule, it is possible, but first you need to checkout a branch:
1. `cd src/sizzle`
2. `git checkout master`
After you've commited your changes to the submodule, you'll update the jquery project to point to the new commit,
but remember to push the submodule changes before pushing the new jquery commit:
1. `cd src/sizzle`
2. `git push origin master`
3. `cd ..`
4. `git add src/sizzle`
5. `git commit`
The makefile has some targets to simplify submodule handling:
#### `make update_submodules` ####
checks out the commit pointed to byu jquery, but merges your local changes, if any. This target is executed
when you are doing a normal `make`.
#### `make pull_submodules` ####
updates the content of the submoduels to what is probably the latest upstream code
#### `make pull` ####
make a `make pull_submodules` and after that a `git pull`. if you have no remote tracking in your master branch, you can
execute this command as `make pull REMOTE=origin BRANCH=master` instead.
### cleaning ###
If you want to purge your working directory back to the status of upstream, following commands can be used (remember everything you've worked on is gone after these):
1. `git reset --hard upstream/master`
2. `git clean -fdx`
### rebasing ###
For feature/topic branches, you should always used the `--rebase` flag to `git pull`, or if you are usually handling many temporary "to be in a github pull request" branches, run following to automate this:
* `git config branch.autosetuprebase local` (see `man git-config` for more information)
### handling merge conflicts ###
If you're getting merge conflicts when merging, instead of editing the conflicted files manually, you can use the feature
`git mergetool`. Even though the default tool `xxdiff` looks awful/old, it's rather useful.
Following are some commands that can be used there:
* `Ctrl + Alt + M` - automerge as much as possible
* `b` - jump to next merge conflict
* `s` - change the order of the conflicted lines
* `u` - undo an merge
* `left mouse button` - mark a block to be the winner
* `middle mouse button` - mark a line to be the winner
* `Ctrl + S` - save
* `Ctrl + Q` - quit
Questions? Questions?
---------- ----------
......
This diff is collapsed.
...@@ -88,7 +88,7 @@ jQuery.fn = jQuery.prototype = { ...@@ -88,7 +88,7 @@ jQuery.fn = jQuery.prototype = {
if ( selector === "body" && !context && document.body ) { if ( selector === "body" && !context && document.body ) {
this.context = document; this.context = document;
this[0] = document.body; this[0] = document.body;
this.selector = "body"; this.selector = selector;
this.length = 1; this.length = 1;
return this; return this;
} }
...@@ -658,8 +658,9 @@ jQuery.extend({ ...@@ -658,8 +658,9 @@ jQuery.extend({
}, },
inArray: function( elem, array ) { inArray: function( elem, array ) {
if ( array.indexOf ) {
return array.indexOf( elem ); if ( indexOf ) {
return indexOf.call( array, elem );
} }
for ( var i = 0, length = array.length; i < length; i++ ) { for ( var i = 0, length = array.length; i < length; i++ ) {
...@@ -709,11 +710,15 @@ jQuery.extend({ ...@@ -709,11 +710,15 @@ jQuery.extend({
// arg is for internal usage only // arg is for internal usage only
map: function( elems, callback, arg ) { map: function( elems, callback, arg ) {
var ret = [], value; var value, key, ret = [],
i = 0,
length = elems.length,
// jquery objects are treated as arrays
isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || jQuery.isArray( elems ) ) ;
// Go through the array, translating each of the items to their // Go through the array, translating each of the items to their
// new value (or values). if ( isArray ) {
for ( var i = 0, length = elems.length; i < length; i++ ) { for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg ); value = callback( elems[ i ], i, arg );
if ( value != null ) { if ( value != null ) {
...@@ -721,6 +726,17 @@ jQuery.extend({ ...@@ -721,6 +726,17 @@ jQuery.extend({
} }
} }
// Go thorugh every key on the object,
} else {
for ( key in elems ) {
value = callback( elems[ key ], key, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
}
// Flatten any nested arrays // Flatten any nested arrays
return ret.concat.apply( [], ret ); return ret.concat.apply( [], ret );
}, },
...@@ -728,31 +744,52 @@ jQuery.extend({ ...@@ -728,31 +744,52 @@ jQuery.extend({
// A global GUID counter for objects // A global GUID counter for objects
guid: 1, guid: 1,
proxy: function( fn, proxy, thisObject ) { // Bind a function to a context, optionally partially applying any
if ( arguments.length === 2 ) { // arguments.
if ( typeof proxy === "string" ) { proxy: function( fn, context ) {
thisObject = fn; var args, proxy;
fn = thisObject[ proxy ];
proxy = undefined;
} else if ( proxy && !jQuery.isFunction( proxy ) ) { // XXX BACKCOMPAT: Support old string method.
thisObject = proxy; if ( typeof context === "string" ) {
proxy = undefined; fn = fn[ context ];
context = arguments[0];
} }
// Quick check to determine if target is callable, in the spec
// this throws a TypeError, but we will just return undefined.
if ( ! jQuery.isFunction( fn ) ) {
return undefined;
} }
if ( !proxy && fn ) { if ( jQuery.support.nativeBind ) {
// Native bind
args = slice.call( arguments, 1 );
if ( args.length ) {
proxy = Function.prototype.bind.apply( fn, args );
} else {
proxy = fn.bind( context );
}
} else {
// Simulated bind
args = slice.call( arguments, 2 );
if ( args.length ) {
proxy = function() {
return arguments.length ?
fn.apply( context, args.concat( slice.call( arguments ) ) ) :
fn.apply( context, args );
};
} else {
proxy = function() { proxy = function() {
return fn.apply( thisObject || this, arguments ); return arguments.length ?
fn.apply( context, arguments ) :
fn.call( context );
}; };
} }
}
// Set the guid of unique handler to the same of original handler, so it can be removed // Set the guid of unique handler to the same of original handler, so it can be removed
if ( fn ) {
proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
}
// So proxy can be declared as an argument
return proxy; return proxy;
}, },
...@@ -843,12 +880,6 @@ if ( jQuery.browser.webkit ) { ...@@ -843,12 +880,6 @@ if ( jQuery.browser.webkit ) {
jQuery.browser.safari = true; jQuery.browser.safari = true;
} }
if ( indexOf ) {
jQuery.inArray = function( elem, array ) {
return indexOf.call( array, elem );
};
}
// IE doesn't match non-breaking spaces with \s // IE doesn't match non-breaking spaces with \s
if ( rnotwhite.test( "\xA0" ) ) { if ( rnotwhite.test( "\xA0" ) ) {
trimLeft = /^[\s\xA0]+/; trimLeft = /^[\s\xA0]+/;
......
(function( jQuery ) { (function( jQuery ) {
var rbrace = /^(?:\{.*\}|\[.*\])$/; var rbrace = /^(?:\{.*\}|\[.*\])$/,
rmultiDash = /([a-z])([A-Z])/g;
jQuery.extend({ jQuery.extend({
cache: {}, cache: {},
...@@ -228,7 +229,8 @@ jQuery.fn.extend({ ...@@ -228,7 +229,8 @@ jQuery.fn.extend({
name = attr[i].name; name = attr[i].name;
if ( name.indexOf( "data-" ) === 0 ) { if ( name.indexOf( "data-" ) === 0 ) {
name = name.substr( 5 ); name = jQuery.camelCase( name.substring(5) );
dataAttr( this[0], name, data[ name ] ); dataAttr( this[0], name, data[ name ] );
} }
} }
...@@ -282,7 +284,9 @@ function dataAttr( elem, key, data ) { ...@@ -282,7 +284,9 @@ function dataAttr( elem, key, data ) {
// If nothing was found internally, try to fetch any // If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute // data from the HTML5 data-* attribute
if ( data === undefined && elem.nodeType === 1 ) { if ( data === undefined && elem.nodeType === 1 ) {
data = elem.getAttribute( "data-" + key ); name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
data = elem.getAttribute( name );
if ( typeof data === "string" ) { if ( typeof data === "string" ) {
try { try {
......
...@@ -12,7 +12,10 @@ var elemdisplay = {}, ...@@ -12,7 +12,10 @@ var elemdisplay = {},
// opacity animations // opacity animations
[ "opacity" ] [ "opacity" ]
], ],
fxNow; fxNow,
requestAnimationFrame = window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame;
function clearFxNow() { function clearFxNow() {
fxNow = undefined; fxNow = undefined;
...@@ -368,7 +371,8 @@ jQuery.fx.prototype = { ...@@ -368,7 +371,8 @@ jQuery.fx.prototype = {
// Start an animation from one number to another // Start an animation from one number to another
custom: function( from, to, unit ) { custom: function( from, to, unit ) {
var self = this, var self = this,
fx = jQuery.fx; fx = jQuery.fx,
raf;
this.startTime = fxNow || createFxNow(); this.startTime = fxNow || createFxNow();
this.start = from; this.start = from;
...@@ -384,7 +388,20 @@ jQuery.fx.prototype = { ...@@ -384,7 +388,20 @@ jQuery.fx.prototype = {
t.elem = this.elem; t.elem = this.elem;
if ( t() && jQuery.timers.push(t) && !timerId ) { if ( t() && jQuery.timers.push(t) && !timerId ) {
timerId = setInterval(fx.tick, fx.interval); // Use requestAnimationFrame instead of setInterval if available
if ( requestAnimationFrame ) {
timerId = 1;
raf = function() {
// When timerId gets set to null at any point, this stops
if ( timerId ) {
requestAnimationFrame( raf );
fx.tick();
}
};
requestAnimationFrame( raf );
} else {
timerId = setInterval( fx.tick, fx.interval );
}
} }
}, },
......
(function( jQuery ) { (function( jQuery ) {
var rnamespaces = /\.(.*)$/, var hasOwn = Object.prototype.hasOwnProperty,
rnamespaces = /\.(.*)$/,
rformElems = /^(?:textarea|input|select)$/i, rformElems = /^(?:textarea|input|select)$/i,
rperiod = /\./g, rperiod = /\./g,
rspace = / /g, rspace = / /g,
...@@ -563,7 +564,15 @@ jQuery.Event = function( src ) { ...@@ -563,7 +564,15 @@ jQuery.Event = function( src ) {
// Event object // Event object
if ( src && src.type ) { if ( src && src.type ) {
this.originalEvent = src; this.originalEvent = src;
this.type = src.type;
// Push explicitly provided properties onto the event object
for ( var prop in src ) {
// Ensure we don't clobber jQuery.Event prototype
// with own properties.
if ( hasOwn.call( src, prop ) ) {
this[ prop ] = src[ prop ];
}
}
// Events bubbling up the document may have been marked as prevented // Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value. // by a handler lower down the tree; reflect the correct value.
...@@ -885,6 +894,8 @@ if ( !jQuery.support.focusinBubbles ) { ...@@ -885,6 +894,8 @@ if ( !jQuery.support.focusinBubbles ) {
jQuery.each(["bind", "one"], function( i, name ) { jQuery.each(["bind", "one"], function( i, name ) {
jQuery.fn[ name ] = function( type, data, fn ) { jQuery.fn[ name ] = function( type, data, fn ) {
var handler;
// Handle object literals // Handle object literals
if ( typeof type === "object" ) { if ( typeof type === "object" ) {
for ( var key in type ) { for ( var key in type ) {
...@@ -898,10 +909,15 @@ jQuery.each(["bind", "one"], function( i, name ) { ...@@ -898,10 +909,15 @@ jQuery.each(["bind", "one"], function( i, name ) {
data = undefined; data = undefined;
} }
var handler = name === "one" ? jQuery.proxy( fn, function( event ) { if ( name === "one" ) {
handler = function( event ) {
jQuery( this ).unbind( event, handler ); jQuery( this ).unbind( event, handler );
return fn.apply( this, arguments ); return fn.apply( this, arguments );
}) : fn; };
handler.guid = fn.guid || jQuery.guid++;
} else {
handler = fn;
}
if ( type === "unload" && name !== "one" ) { if ( type === "unload" && name !== "one" ) {
this.one( type, data, fn ); this.one( type, data, fn );
...@@ -965,24 +981,27 @@ jQuery.fn.extend({ ...@@ -965,24 +981,27 @@ jQuery.fn.extend({
toggle: function( fn ) { toggle: function( fn ) {
// Save reference to arguments for access in closure // Save reference to arguments for access in closure
var args = arguments, var args = arguments,
i = 1; guid = fn.guid || jQuery.guid++,
i = 0,
// link all the functions, so any of them can unbind this click handler toggler = function( event ) {
while ( i < args.length ) {
jQuery.proxy( fn, args[ i++ ] );
}
return this.click( jQuery.proxy( fn, function( event ) {
// Figure out which function to execute // Figure out which function to execute
var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop // Make sure that clicks stop
event.preventDefault(); event.preventDefault();
// and execute the function // and execute the function
return args[ lastToggle ].apply( this, arguments ) || false; return args[ lastToggle ].apply( this, arguments ) || false;
})); };
// link all the functions, so any of them can unbind this click handler
toggler.guid = guid;
while ( i < args.length ) {
args[ i++ ].guid = guid;
}
return this.click( toggler );
}, },
hover: function( fnOver, fnOut ) { hover: function( fnOver, fnOut ) {
...@@ -1168,3 +1187,4 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl ...@@ -1168,3 +1187,4 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
}); });
})( jQuery ); })( jQuery );
...@@ -377,7 +377,7 @@ function cloneCopyEvent( src, dest ) { ...@@ -377,7 +377,7 @@ function cloneCopyEvent( src, dest ) {
} }
} }
function cloneFixAttributes(src, dest) { function cloneFixAttributes( src, dest ) {
// We do not need to do anything for non-Elements // We do not need to do anything for non-Elements
if ( dest.nodeType !== 1 ) { if ( dest.nodeType !== 1 ) {
return; return;
...@@ -549,7 +549,8 @@ jQuery.extend({ ...@@ -549,7 +549,8 @@ jQuery.extend({
// Return the cloned set // Return the cloned set
return clone; return clone;
}, },
clean: function( elems, context, fragment, scripts ) { clean: function( elems, context, fragment, scripts ) {
context = context || document; context = context || document;
......
Subproject commit f12b9309269ba7e705a99efe099f86ed1fe98d58 Subproject commit c50b0cddec48494ba882606d03e14cce647d243b
...@@ -19,7 +19,8 @@ jQuery.support = (function() { ...@@ -19,7 +19,8 @@ jQuery.support = (function() {
isSupported; isSupported;
// Preliminary tests // Preliminary tests
div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; div.setAttribute("className", "t");
div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
all = div.getElementsByTagName( "*" ); all = div.getElementsByTagName( "*" );
a = div.getElementsByTagName( "a" )[ 0 ]; a = div.getElementsByTagName( "a" )[ 0 ];
...@@ -48,7 +49,7 @@ jQuery.support = (function() { ...@@ -48,7 +49,7 @@ jQuery.support = (function() {
// Get the style information from getAttribute // Get the style information from getAttribute
// (IE uses .cssText instead) // (IE uses .cssText instead)
style: /red/.test( a.getAttribute("style") ), style: /top/.test( a.getAttribute("style") ),
// Make sure that URLs aren't manipulated // Make sure that URLs aren't manipulated
// (IE normalizes it by default) // (IE normalizes it by default)
...@@ -72,6 +73,13 @@ jQuery.support = (function() { ...@@ -72,6 +73,13 @@ jQuery.support = (function() {
// (WebKit defaults to false instead of true, IE too, if it's in an optgroup) // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
optSelected: opt.selected, optSelected: opt.selected,
// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
getSetAttribute: div.className !== "t",
// Test for presence of native Function#bind.
// Not in: >= Chrome 6, >= FireFox 3, Safari 5?, IE 9?, Opera 11?
nativeBind: jQuery.isFunction( Function.prototype.bind ),
// Will be defined later // Will be defined later
submitBubbles: true, submitBubbles: true,
changeBubbles: true, changeBubbles: true,
......
...@@ -17,17 +17,30 @@ var runtil = /Until$/, ...@@ -17,17 +17,30 @@ var runtil = /Until$/,
jQuery.fn.extend({ jQuery.fn.extend({
find: function( selector ) { find: function( selector ) {
var self = this,
i, l;
if ( typeof selector !== "string" ) {
return jQuery( selector ).filter(function() {
for ( i = 0, l = self.length; i < l; i++ ) {
if ( jQuery.contains( self[ i ], this ) ) {
return true;
}
}
});
}
var ret = this.pushStack( "", "find", selector ), var ret = this.pushStack( "", "find", selector ),
length = 0; length, n, r;
for ( var i = 0, l = this.length; i < l; i++ ) { for ( i = 0, l = this.length; i < l; i++ ) {
length = ret.length; length = ret.length;
jQuery.find( selector, this[i], ret ); jQuery.find( selector, this[i], ret );
if ( i > 0 ) { if ( i > 0 ) {
// Make sure that the results are unique // Make sure that the results are unique
for ( var n = length; n < ret.length; n++ ) { for ( n = length; n < ret.length; n++ ) {
for ( var r = 0; r < length; r++ ) { for ( r = 0; r < length; r++ ) {
if ( ret[r] === ret[n] ) { if ( ret[r] === ret[n] ) {
ret.splice(n--, 1); ret.splice(n--, 1);
break; break;
...@@ -60,12 +73,15 @@ jQuery.fn.extend({ ...@@ -60,12 +73,15 @@ jQuery.fn.extend({
}, },
is: function( selector ) { is: function( selector ) {
return !!selector && jQuery.filter( selector, this ).length > 0; return !!selector && (typeof selector === "string" ?
jQuery.filter( selector, this ).length > 0 :
this.filter( selector ).length > 0);
}, },
closest: function( selectors, context ) { closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0]; var ret = [], i, l, cur = this[0];
// Array
if ( jQuery.isArray( selectors ) ) { if ( jQuery.isArray( selectors ) ) {
var match, selector, var match, selector,
matches = {}, matches = {},
...@@ -75,8 +91,8 @@ jQuery.fn.extend({ ...@@ -75,8 +91,8 @@ jQuery.fn.extend({
for ( i = 0, l = selectors.length; i < l; i++ ) { for ( i = 0, l = selectors.length; i < l; i++ ) {
selector = selectors[i]; selector = selectors[i];
if ( !matches[selector] ) { if ( !matches[ selector ] ) {
matches[selector] = jQuery.expr.match.POS.test( selector ) ? matches[ selector ] = POS.test( selector ) ?
jQuery( selector, context || this.context ) : jQuery( selector, context || this.context ) :
selector; selector;
} }
...@@ -84,9 +100,9 @@ jQuery.fn.extend({ ...@@ -84,9 +100,9 @@ jQuery.fn.extend({
while ( cur && cur.ownerDocument && cur !== context ) { while ( cur && cur.ownerDocument && cur !== context ) {
for ( selector in matches ) { for ( selector in matches ) {
match = matches[selector]; match = matches[ selector ];
if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
ret.push({ selector: selector, elem: cur, level: level }); ret.push({ selector: selector, elem: cur, level: level });
} }
} }
...@@ -99,8 +115,10 @@ jQuery.fn.extend({ ...@@ -99,8 +115,10 @@ jQuery.fn.extend({
return ret; return ret;
} }
var pos = POS.test( selectors ) ? // String
jQuery( selectors, context || this.context ) : null; var pos = POS.test( selectors ) || typeof selectors !== "string" ?
jQuery( selectors, context || this.context ) :
0;
for ( i = 0, l = this.length; i < l; i++ ) { for ( i = 0, l = this.length; i < l; i++ ) {
cur = this[i]; cur = this[i];
...@@ -112,14 +130,14 @@ jQuery.fn.extend({ ...@@ -112,14 +130,14 @@ jQuery.fn.extend({
} else { } else {
cur = cur.parentNode; cur = cur.parentNode;
if ( !cur || !cur.ownerDocument || cur === context ) { if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
break; break;
} }
} }
} }
} }
ret = ret.length > 1 ? jQuery.unique(ret) : ret; ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
return this.pushStack( ret, "closest", selectors ); return this.pushStack( ret, "closest", selectors );
}, },
...@@ -286,7 +304,7 @@ function winnow( elements, qualifier, keep ) { ...@@ -286,7 +304,7 @@ function winnow( elements, qualifier, keep ) {
return retVal === keep; return retVal === keep;
}); });
} else if ( qualifier.nodeType ) { } else if ( qualifier && qualifier.nodeType ) {
return jQuery.grep(elements, function( elem, i ) { return jQuery.grep(elements, function( elem, i ) {
return (elem === qualifier) === keep; return (elem === qualifier) === keep;
}); });
......
...@@ -203,6 +203,10 @@ Z</textarea> ...@@ -203,6 +203,10 @@ Z</textarea>
<select name="D4" disabled="disabled"> <select name="D4" disabled="disabled">
<option selected="selected" value="NO">NO</option> <option selected="selected" value="NO">NO</option>
</select> </select>
<input id="list-test" type="text" />
<datalist id="datalist">
<option value="option"></option>
</datalist>
</form> </form>
<div id="moretests"> <div id="moretests">
<form> <form>
......
This diff is collapsed.
...@@ -642,7 +642,7 @@ test("first()/last()", function() { ...@@ -642,7 +642,7 @@ test("first()/last()", function() {
}); });
test("map()", function() { test("map()", function() {
expect(2);//expect(6); expect(7);
same( same(
jQuery("#ap").map(function(){ jQuery("#ap").map(function(){
...@@ -660,32 +660,32 @@ test("map()", function() { ...@@ -660,32 +660,32 @@ test("map()", function() {
"Single Map" "Single Map"
); );
return;//these haven't been accepted yet
//for #2616 //for #2616
var keys = jQuery.map( {a:1,b:2}, function( v, k ){ var keys = jQuery.map( {a:1,b:2}, function( v, k ){
return k; return k;
}, [ ] ); });
equals( keys.join(""), "ab", "Map the keys from a hash to an array" ); equals( keys.join(""), "ab", "Map the keys from a hash to an array" );
var values = jQuery.map( {a:1,b:2}, function( v, k ){ var values = jQuery.map( {a:1,b:2}, function( v, k ){
return v; return v;
}, [ ] ); });
equals( values.join(""), "12", "Map the values from a hash to an array" ); equals( values.join(""), "12", "Map the values from a hash to an array" );
// object with length prop
var values = jQuery.map( {a:1,b:2, length:3}, function( v, k ){
return v;
});
equals( values.join(""), "123", "Map the values from a hash with a length property to an array" );
var scripts = document.getElementsByTagName("script"); var scripts = document.getElementsByTagName("script");
var mapped = jQuery.map( scripts, function( v, k ){ var mapped = jQuery.map( scripts, function( v, k ){
return v; return v;
}, {length:0} ); });
equals( mapped.length, scripts.length, "Map an array(-like) to a hash" ); equals( mapped.length, scripts.length, "Map an array(-like) to a hash" );
var flat = jQuery.map( Array(4), function( v, k ){ var flat = jQuery.map( Array(4), function( v, k ){
return k % 2 ? k : [k,k,k];//try mixing array and regular returns return k % 2 ? k : [k,k,k];//try mixing array and regular returns
}); });
equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" ); equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" );
}); });
...@@ -903,7 +903,7 @@ test("jQuery.isEmptyObject", function(){ ...@@ -903,7 +903,7 @@ test("jQuery.isEmptyObject", function(){
}); });
test("jQuery.proxy", function(){ test("jQuery.proxy", function(){
expect(4); expect(6);
var test = function(){ equals( this, thisObject, "Make sure that scope is set properly." ); }; var test = function(){ equals( this, thisObject, "Make sure that scope is set properly." ); };
var thisObject = { foo: "bar", method: test }; var thisObject = { foo: "bar", method: test };
...@@ -917,8 +917,17 @@ test("jQuery.proxy", function(){ ...@@ -917,8 +917,17 @@ test("jQuery.proxy", function(){
// Make sure it doesn't freak out // Make sure it doesn't freak out
equals( jQuery.proxy( null, thisObject ), undefined, "Make sure no function was returned." ); equals( jQuery.proxy( null, thisObject ), undefined, "Make sure no function was returned." );
// Use the string shortcut // Partial application
jQuery.proxy( thisObject, "method" )(); var test2 = function( a ){ equals( a, "pre-applied", "Ensure arguments can be pre-applied." ); };
jQuery.proxy( test2, null, "pre-applied" )();
// Partial application w/ normal arguments
var test3 = function( a, b ){ equals( b, "normal", "Ensure arguments can be pre-applied and passed as usual." ); };
jQuery.proxy( test3, null, "pre-applied" )( "normal" );
// Test old syntax
var test4 = { meth: function( a ){ equals( a, "boom", "Ensure old syntax works." ); } };
jQuery.proxy( test4, "meth" )( "boom" );
}); });
test("jQuery.parseJSON", function(){ test("jQuery.parseJSON", function(){
......
...@@ -486,3 +486,20 @@ if (window.JSON && window.JSON.stringify) { ...@@ -486,3 +486,20 @@ if (window.JSON && window.JSON.stringify) {
equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" ); equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" );
}); });
} }
test("jQuery.data should follow html5 specification regarding camel casing", function() {
expect(6);
var div = jQuery("<div id='myObject' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>")
.prependTo("body");
equals(div.data().foo, "a", "Verify single word data-* key");
equals(div.data().fooBar, "b", "Verify multiple word data-* key");
equals(div.data().fooBarBaz, "c", "Verify multiple word data-* key");
equals(div.data("foo"), "a", "Verify single word data-* key");
equals(div.data("fooBar"), "b", "Verify multiple word data-* key");
equals(div.data("fooBarBaz"), "c", "Verify multiple word data-* key");
div.remove();
});
\ No newline at end of file
...@@ -975,6 +975,27 @@ test("trigger(eventObject, [data], [fn])", function() { ...@@ -975,6 +975,27 @@ test("trigger(eventObject, [data], [fn])", function() {
$parent.unbind().remove(); $parent.unbind().remove();
}); });
test("jQuery.Event({ /* props */ })", function() {
expect(4);
var event = jQuery.Event({ type: "keydown", keyCode: 64 }),
handler = function( event ) {
ok( "keyCode" in event, "Special property 'keyCode' exists" );
equal( event.keyCode, 64, "event.keyCode has explicit value '64'" );
};
// Supports jQuery.Event implementation
equal( event.type, "keydown", "Verify type" );
ok( "keyCode" in event, "Special 'keyCode' property exists" );
jQuery("body").bind( "keydown", handler ).trigger( event );
jQuery("body").unbind( "keydown" );
});
test("jQuery.Event.currentTarget", function(){ test("jQuery.Event.currentTarget", function(){
expect(1); expect(1);
...@@ -2151,3 +2172,4 @@ test("event properties", function() { ...@@ -2151,3 +2172,4 @@ test("event properties", function() {
}).click(); }).click();
}); });
*/ */
...@@ -1009,7 +1009,7 @@ test("clone()", function() { ...@@ -1009,7 +1009,7 @@ test("clone()", function() {
}); });
test("clone(form element) (Bug #3879, #6655)", function() { test("clone(form element) (Bug #3879, #6655)", function() {
expect(6); expect(5);
var element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>"); var element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" ); equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
...@@ -1019,7 +1019,9 @@ test("clone(form element) (Bug #3879, #6655)", function() { ...@@ -1019,7 +1019,9 @@ test("clone(form element) (Bug #3879, #6655)", function() {
equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" ); equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" ); equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" );
equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" );
// defaultChecked also gets set now due to setAttribute in attr, is this check still valid?
// equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" );
element = jQuery("<input type='text' value='foo'>"); element = jQuery("<input type='text' value='foo'>");
clone = element.clone(); clone = element.clone();
......
...@@ -13,8 +13,32 @@ test("find(String)", function() { ...@@ -13,8 +13,32 @@ test("find(String)", function() {
same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" ); same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" );
}); });
test("is(String)", function() { test("find(node|jQuery object)", function() {
expect(26); expect( 11 );
var $foo = jQuery('#foo'),
$blog = jQuery('.blogTest'),
$first = jQuery('#first'),
$two = $blog.add( $first ),
$fooTwo = $foo.add( $blog );
equals( $foo.find( $blog ).text(), 'Yahoo', 'Find with blog jQuery object' );
equals( $foo.find( $blog[0] ).text(), 'Yahoo', 'Find with blog node' );
equals( $foo.find( $first ).length, 0, '#first is not in #foo' );
equals( $foo.find( $first[0]).length, 0, '#first not in #foo (node)' );
ok( $foo.find( $two ).is('.blogTest'), 'Find returns only nodes within #foo' );
ok( $fooTwo.find( $blog ).is('.blogTest'), 'Blog is part of the collection, but also within foo' );
ok( $fooTwo.find( $blog[0] ).is('.blogTest'), 'Blog is part of the collection, but also within foo(node)' );
equals( $two.find( $foo ).length, 0, 'Foo is not in two elements' );
equals( $two.find( $foo[0] ).length, 0, 'Foo is not in two elements(node)' );
equals( $two.find( $first ).length, 0, 'first is in the collection and not within two' );
equals( $two.find( $first ).length, 0, 'first is in the collection and not within two(node)' );
});
test("is(String|undefined)", function() {
expect(27);
ok( jQuery('#form').is('form'), 'Check for element: A form must be a form' ); ok( jQuery('#form').is('form'), 'Check for element: A form must be a form' );
ok( !jQuery('#form').is('div'), 'Check for element: A form is not a div' ); ok( !jQuery('#form').is('div'), 'Check for element: A form is not a div' );
ok( jQuery('#mark').is('.blog'), 'Check for class: Expected class "blog"' ); ok( jQuery('#mark').is('.blog'), 'Check for class: Expected class "blog"' );
...@@ -33,10 +57,12 @@ test("is(String)", function() { ...@@ -33,10 +57,12 @@ test("is(String)", function() {
ok( !jQuery('#foo').is(':has(ul)'), 'Check for child: Did not expect "ul" element' ); ok( !jQuery('#foo').is(':has(ul)'), 'Check for child: Did not expect "ul" element' );
ok( jQuery('#foo').is(':has(p):has(a):has(code)'), 'Check for childs: Expected "p", "a" and "code" child elements' ); ok( jQuery('#foo').is(':has(p):has(a):has(code)'), 'Check for childs: Expected "p", "a" and "code" child elements' );
ok( !jQuery('#foo').is(':has(p):has(a):has(code):has(ol)'), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' ); ok( !jQuery('#foo').is(':has(p):has(a):has(code):has(ol)'), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' );
ok( !jQuery('#foo').is(0), 'Expected false for an invalid expression - 0' ); ok( !jQuery('#foo').is(0), 'Expected false for an invalid expression - 0' );
ok( !jQuery('#foo').is(null), 'Expected false for an invalid expression - null' ); ok( !jQuery('#foo').is(null), 'Expected false for an invalid expression - null' );
ok( !jQuery('#foo').is(''), 'Expected false for an invalid expression - ""' ); ok( !jQuery('#foo').is(''), 'Expected false for an invalid expression - ""' );
ok( !jQuery('#foo').is(undefined), 'Expected false for an invalid expression - undefined' ); ok( !jQuery('#foo').is(undefined), 'Expected false for an invalid expression - undefined' );
ok( !jQuery('#foo').is({ plain: "object" }), 'Check passing invalid object' );
// test is() with comma-seperated expressions // test is() with comma-seperated expressions
ok( jQuery('#en').is('[lang="en"],[lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); ok( jQuery('#en').is('[lang="en"],[lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' );
...@@ -45,6 +71,36 @@ test("is(String)", function() { ...@@ -45,6 +71,36 @@ test("is(String)", function() {
ok( jQuery('#en').is('[lang="de"] , [lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); ok( jQuery('#en').is('[lang="de"] , [lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' );
}); });
test("is(jQuery)", function() {
expect(24);
ok( jQuery('#form').is( jQuery('form') ), 'Check for element: A form is a form' );
ok( !jQuery('#form').is( jQuery('div') ), 'Check for element: A form is not a div' );
ok( jQuery('#mark').is( jQuery('.blog') ), 'Check for class: Expected class "blog"' );
ok( !jQuery('#mark').is( jQuery('.link') ), 'Check for class: Did not expect class "link"' );
ok( jQuery('#simon').is( jQuery('.blog.link') ), 'Check for multiple classes: Expected classes "blog" and "link"' );
ok( !jQuery('#simon').is( jQuery('.blogTest') ), 'Check for multiple classes: Expected classes "blog" and "link", but not "blogTest"' );
ok( jQuery('#en').is( jQuery('[lang="en"]') ), 'Check for attribute: Expected attribute lang to be "en"' );
ok( !jQuery('#en').is( jQuery('[lang="de"]') ), 'Check for attribute: Expected attribute lang to be "en", not "de"' );
ok( jQuery('#text1').is( jQuery('[type="text"]') ), 'Check for attribute: Expected attribute type to be "text"' );
ok( !jQuery('#text1').is( jQuery('[type="radio"]') ), 'Check for attribute: Expected attribute type to be "text", not "radio"' );
ok( jQuery('#text2').is( jQuery(':disabled') ), 'Check for pseudoclass: Expected to be disabled' );
ok( !jQuery('#text1').is( jQuery(':disabled') ), 'Check for pseudoclass: Expected not disabled' );
ok( jQuery('#radio2').is( jQuery(':checked') ), 'Check for pseudoclass: Expected to be checked' );
ok( !jQuery('#radio1').is( jQuery(':checked') ), 'Check for pseudoclass: Expected not checked' );
ok( jQuery('#foo').is( jQuery(':has(p)') ), 'Check for child: Expected a child "p" element' );
ok( !jQuery('#foo').is( jQuery(':has(ul)') ), 'Check for child: Did not expect "ul" element' );
ok( jQuery('#foo').is( jQuery(':has(p):has(a):has(code)') ), 'Check for childs: Expected "p", "a" and "code" child elements' );
ok( !jQuery('#foo').is( jQuery(':has(p):has(a):has(code):has(ol)') ), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' );
// Some raw elements
ok( jQuery('#form').is( jQuery('form')[0] ), 'Check for element: A form is a form' );
ok( !jQuery('#form').is( jQuery('div')[0] ), 'Check for element: A form is not a div' );
ok( jQuery('#mark').is( jQuery('.blog')[0] ), 'Check for class: Expected class "blog"' );
ok( !jQuery('#mark').is( jQuery('.link')[0] ), 'Check for class: Did not expect class "link"' );
ok( jQuery('#simon').is( jQuery('.blog.link')[0] ), 'Check for multiple classes: Expected classes "blog" and "link"' );
ok( !jQuery('#simon').is( jQuery('.blogTest')[0] ), 'Check for multiple classes: Expected classes "blog" and "link", but not "blogTest"' );
});
test("index()", function() { test("index()", function() {
expect(1); expect(1);
...@@ -82,12 +138,17 @@ test("index(Object|String|undefined)", function() { ...@@ -82,12 +138,17 @@ test("index(Object|String|undefined)", function() {
equals( jQuery('#radio2').index('#form :text') , -1, "Check for index not found within a selector" ); equals( jQuery('#radio2').index('#form :text') , -1, "Check for index not found within a selector" );
}); });
test("filter(Selector)", function() { test("filter(Selector|undefined)", function() {
expect(5); expect(9);
same( jQuery("#form input").filter(":checked").get(), q("radio2", "check1"), "filter(String)" ); same( jQuery("#form input").filter(":checked").get(), q("radio2", "check1"), "filter(String)" );
same( jQuery("p").filter("#ap, #sndp").get(), q("ap", "sndp"), "filter('String, String')" ); same( jQuery("p").filter("#ap, #sndp").get(), q("ap", "sndp"), "filter('String, String')" );
same( jQuery("p").filter("#ap,#sndp").get(), q("ap", "sndp"), "filter('String,String')" ); same( jQuery("p").filter("#ap,#sndp").get(), q("ap", "sndp"), "filter('String,String')" );
same( jQuery('p').filter(null).get(), [], "filter(null) should return an empty jQuery object");
same( jQuery('p').filter(undefined).get(), [], "filter(undefined) should return an empty jQuery object");
same( jQuery('p').filter(0).get(), [], "filter(0) should return an empty jQuery object");
same( jQuery('p').filter('').get(), [], "filter('') should return an empty jQuery object");
// using contents will get comments regular, text, and comment nodes // using contents will get comments regular, text, and comment nodes
var j = jQuery("#nonnodes").contents(); var j = jQuery("#nonnodes").contents();
equals( j.filter("span").length, 1, "Check node,textnode,comment to filter the one span" ); equals( j.filter("span").length, 1, "Check node,textnode,comment to filter the one span" );
...@@ -124,7 +185,7 @@ test("filter(jQuery)", function() { ...@@ -124,7 +185,7 @@ test("filter(jQuery)", function() {
}) })
test("closest()", function() { test("closest()", function() {
expect(11); expect(13);
same( jQuery("body").closest("body").get(), q("body"), "closest(body)" ); same( jQuery("body").closest("body").get(), q("body"), "closest(body)" );
same( jQuery("body").closest("html").get(), q("html"), "closest(html)" ); same( jQuery("body").closest("html").get(), q("html"), "closest(html)" );
same( jQuery("body").closest("div").get(), [], "closest(div)" ); same( jQuery("body").closest("div").get(), [], "closest(div)" );
...@@ -144,6 +205,10 @@ test("closest()", function() { ...@@ -144,6 +205,10 @@ test("closest()", function() {
// Test on disconnected node // Test on disconnected node
equals( jQuery("<div><p></p></div>").find("p").closest("table").length, 0, "Make sure disconnected closest work." ); equals( jQuery("<div><p></p></div>").find("p").closest("table").length, 0, "Make sure disconnected closest work." );
// Bug #7369
equals( jQuery('<div foo="bar"></div>').closest('[foo]').length, 1, "Disconnected nodes with attribute selector" );
equals( jQuery('<div>text</div>').closest('[lang]').length, 0, "Disconnected nodes with text and non-existent attribute selector" );
}); });
test("closest(Array)", function() { test("closest(Array)", function() {
...@@ -158,8 +223,29 @@ test("closest(Array)", function() { ...@@ -158,8 +223,29 @@ test("closest(Array)", function() {
same( jQuery("body").closest(["span","html"]), [{selector:"html", elem:document.documentElement, level:2}], "closest([body, html])" ); same( jQuery("body").closest(["span","html"]), [{selector:"html", elem:document.documentElement, level:2}], "closest([body, html])" );
}); });
<<<<<<< HEAD
test("not(Selector|undefined)", function() {
expect(11);
=======
test("closest(jQuery)", function() {
expect(8);
var $child = jQuery("#nothiddendivchild"),
$parent = jQuery("#nothiddendiv"),
$main = jQuery("#main"),
$body = jQuery("body");
ok( $child.closest( $parent ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') )" );
ok( $child.closest( $parent[0] ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') ) :: node" );
ok( $child.closest( $child ).is('#nothiddendivchild'), "child is included" );
ok( $child.closest( $child[0] ).is('#nothiddendivchild'), "child is included :: node" );
equals( $child.closest( document.createElement('div') ).length, 0, "created element is not related" );
equals( $child.closest( $main ).length, 0, "Main not a parent of child" );
equals( $child.closest( $main[0] ).length, 0, "Main not a parent of child :: node" );
ok( $child.closest( $body.add($parent) ).is('#nothiddendiv'), "Closest ancestor retrieved." );
});
test("not(Selector)", function() { test("not(Selector)", function() {
expect(7); expect(7);
>>>>>>> 1a167767305202797cf4c839eb64bd7adfb00182
equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" ); equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" );
same( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" ); same( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" );
same( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" ); same( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" );
...@@ -168,6 +254,12 @@ test("not(Selector)", function() { ...@@ -168,6 +254,12 @@ test("not(Selector)", function() {
same( jQuery('#ap *').not('code').get(), q("google", "groups", "anchor1", "mark"), "not('tag selector')" ); same( jQuery('#ap *').not('code').get(), q("google", "groups", "anchor1", "mark"), "not('tag selector')" );
same( jQuery('#ap *').not('code, #mark').get(), q("google", "groups", "anchor1"), "not('tag, ID selector')" ); same( jQuery('#ap *').not('code, #mark').get(), q("google", "groups", "anchor1"), "not('tag, ID selector')" );
same( jQuery('#ap *').not('#mark, code').get(), q("google", "groups", "anchor1"), "not('ID, tag selector')"); same( jQuery('#ap *').not('#mark, code').get(), q("google", "groups", "anchor1"), "not('ID, tag selector')");
var all = jQuery('p').get();
same( jQuery('p').not(null).get(), all, "not(null) should have no effect");
same( jQuery('p').not(undefined).get(), all, "not(undefined) should have no effect");
same( jQuery('p').not(0).get(), all, "not(0) should have no effect");
same( jQuery('p').not('').get(), all, "not('') should have no effect");
}); });
test("not(Element)", function() { test("not(Element)", function() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment