Merge lp:~edb/quam-plures/update_jquery_and_jqueryUI into lp:quam-plures

Proposed by EdB
Status: Merged
Merged at revision: 7630
Proposed branch: lp:~edb/quam-plures/update_jquery_and_jqueryUI
Merge into: lp:quam-plures
Diff against target: 24202 lines
To merge this branch: bzr merge lp:~edb/quam-plures/update_jquery_and_jqueryUI
Reviewer Review Type Date Requested Status
Lee Turner (community) Approve
Tilman Blumenbach (community) Approve
Review via email: mp+72840@code.launchpad.net

Description of the change

http://forums.quamplures.net/viewtopic.php?f=11&t=771

This updates our jQuery from 1.3.2 to 1.6.2 and our jQueryUI from 1.7 to 1.8.16 I honestly forget if jQuery has a newer version, but I went with 1.6.2 because that is what came with the jQueryUI package. We need this to use uploadify for a mass file uploader.

To post a comment you must log in.
7614. By EdB

core to 7614

7615. By EdB

core up to 7618

Revision history for this message
Tilman Blumenbach (tblue) wrote :

Well, I didn't review any code because you just updated jQuery stuff -- the app seems to run fine.

review: Approve
Revision history for this message
EdB (edb) wrote :

That was my theory: jqueryUI gave me a jquery that it likes to work with so I went with it and couldn't detect a problem. And uploadify says it needs a higher version of jquery to be used (which is unrelated to this branch).

OT: I'm making some fair progress with a mass uploader using uploadify, which is shocking considering it involves jquery and me.

Revision history for this message
EdB (edb) wrote :

Oh and one thing I did was to make sure that what we had was EXACTLY what jquery of that version was. In other words I verified that there were no changes to the jquery file(s) made by that other app and therefore in use by us. To find our jquery was exactly what it was supposed to be gave me confidence to simply update the versions ... then drive around the back end and play with file uploading and widget selection/placement as my "testing".

7616. By EdB

core to 7620

7617. By EdB

core to 7624

Revision history for this message
Lee Turner (leeturner) wrote :

Couldn't find any issues with this

review: Approve
Revision history for this message
EdB (edb) wrote :

I am adding core updates AND retesting everything I have in merge just to be sure, but it is taking a long time due to many conflicts this time around. Will send another comment when I got them back up to speed.

7618. By EdB

core to 7628

Revision history for this message
EdB (edb) wrote :

Okay cool. This one is good to go - no issues when re-testing after merging from core.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'qp_rsc/js/jquery.js'
--- qp_rsc/js/jquery.js 2009-03-08 08:42:22 +0000
+++ qp_rsc/js/jquery.js 2011-09-04 22:26:29 +0000
@@ -1,153 +1,271 @@
1/*!1/*!
2 * jQuery JavaScript Library v1.3.22 * jQuery JavaScript Library v1.6.2
3 * http://jquery.com/3 * http://jquery.com/
4 *4 *
5 * Copyright (c) 2009 John Resig5 * Copyright 2011, John Resig
6 * Dual licensed under the MIT and GPL licenses.6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://docs.jquery.com/License7 * http://jquery.org/license
8 *8 *
9 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)9 * Includes Sizzle.js
10 * Revision: 624610 * http://sizzlejs.com/
11 * Copyright 2011, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Thu Jun 30 14:16:56 2011 -0400
11 */15 */
12(function(){16(function( window, undefined ) {
1317
14var 18// Use the correct document accordingly with window argument (sandbox)
15 // Will speed up references to window, and allows munging its name.19var document = window.document,
16 window = this,20 navigator = window.navigator,
17 // Will speed up references to undefined, and allows munging its name.21 location = window.location;
18 undefined,22var jQuery = (function() {
23
24// Define a local copy of jQuery
25var jQuery = function( selector, context ) {
26 // The jQuery object is actually just the init constructor 'enhanced'
27 return new jQuery.fn.init( selector, context, rootjQuery );
28 },
29
19 // Map over jQuery in case of overwrite30 // Map over jQuery in case of overwrite
20 _jQuery = window.jQuery,31 _jQuery = window.jQuery,
32
21 // Map over the $ in case of overwrite33 // Map over the $ in case of overwrite
22 _$ = window.$,34 _$ = window.$,
2335
24 jQuery = window.jQuery = window.$ = function( selector, context ) {36 // A central reference to the root jQuery(document)
25 // The jQuery object is actually just the init constructor 'enhanced'37 rootjQuery,
26 return new jQuery.fn.init( selector, context );
27 },
2838
29 // A simple way to check for HTML strings or ID strings39 // A simple way to check for HTML strings or ID strings
30 // (both of which we optimize for)40 // (both of which we optimize for)
31 quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,41 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
32 // Is it a simple selector42
33 isSimple = /^.[^:#\[\.,]*$/;43 // Check if a string has a non-whitespace character in it
44 rnotwhite = /\S/,
45
46 // Used for trimming whitespace
47 trimLeft = /^\s+/,
48 trimRight = /\s+$/,
49
50 // Check for digits
51 rdigit = /\d/,
52
53 // Match a standalone tag
54 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
55
56 // JSON RegExp
57 rvalidchars = /^[\],:{}\s]*$/,
58 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
59 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
60 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
61
62 // Useragent RegExp
63 rwebkit = /(webkit)[ \/]([\w.]+)/,
64 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
65 rmsie = /(msie) ([\w.]+)/,
66 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
67
68 // Matches dashed string for camelizing
69 rdashAlpha = /-([a-z])/ig,
70
71 // Used by jQuery.camelCase as callback to replace()
72 fcamelCase = function( all, letter ) {
73 return letter.toUpperCase();
74 },
75
76 // Keep a UserAgent string for use with jQuery.browser
77 userAgent = navigator.userAgent,
78
79 // For matching the engine and version of the browser
80 browserMatch,
81
82 // The deferred used on DOM ready
83 readyList,
84
85 // The ready event handler
86 DOMContentLoaded,
87
88 // Save a reference to some core methods
89 toString = Object.prototype.toString,
90 hasOwn = Object.prototype.hasOwnProperty,
91 push = Array.prototype.push,
92 slice = Array.prototype.slice,
93 trim = String.prototype.trim,
94 indexOf = Array.prototype.indexOf,
95
96 // [[Class]] -> type pairs
97 class2type = {};
3498
35jQuery.fn = jQuery.prototype = {99jQuery.fn = jQuery.prototype = {
36 init: function( selector, context ) {100 constructor: jQuery,
37 // Make sure that a selection was provided101 init: function( selector, context, rootjQuery ) {
38 selector = selector || document;102 var match, elem, ret, doc;
103
104 // Handle $(""), $(null), or $(undefined)
105 if ( !selector ) {
106 return this;
107 }
39108
40 // Handle $(DOMElement)109 // Handle $(DOMElement)
41 if ( selector.nodeType ) {110 if ( selector.nodeType ) {
42 this[0] = selector;111 this.context = this[0] = selector;
43 this.length = 1;112 this.length = 1;
44 this.context = selector;113 return this;
45 return this;114 }
46 }115
116 // The body element only exists once, optimize finding it
117 if ( selector === "body" && !context && document.body ) {
118 this.context = document;
119 this[0] = document.body;
120 this.selector = selector;
121 this.length = 1;
122 return this;
123 }
124
47 // Handle HTML strings125 // Handle HTML strings
48 if ( typeof selector === "string" ) {126 if ( typeof selector === "string" ) {
49 // Are we dealing with HTML string or an ID?127 // Are we dealing with HTML string or an ID?
50 var match = quickExpr.exec( selector );128 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
129 // Assume that strings that start and end with <> are HTML and skip the regex check
130 match = [ null, selector, null ];
131
132 } else {
133 match = quickExpr.exec( selector );
134 }
51135
52 // Verify a match, and that no context was specified for #id136 // Verify a match, and that no context was specified for #id
53 if ( match && (match[1] || !context) ) {137 if ( match && (match[1] || !context) ) {
54138
55 // HANDLE: $(html) -> $(array)139 // HANDLE: $(html) -> $(array)
56 if ( match[1] )140 if ( match[1] ) {
57 selector = jQuery.clean( [ match[1] ], context );141 context = context instanceof jQuery ? context[0] : context;
142 doc = (context ? context.ownerDocument || context : document);
143
144 // If a single string is passed in and it's a single tag
145 // just do a createElement and skip the rest
146 ret = rsingleTag.exec( selector );
147
148 if ( ret ) {
149 if ( jQuery.isPlainObject( context ) ) {
150 selector = [ document.createElement( ret[1] ) ];
151 jQuery.fn.attr.call( selector, context, true );
152
153 } else {
154 selector = [ doc.createElement( ret[1] ) ];
155 }
156
157 } else {
158 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
159 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
160 }
161
162 return jQuery.merge( this, selector );
58163
59 // HANDLE: $("#id")164 // HANDLE: $("#id")
60 else {165 } else {
61 var elem = document.getElementById( match[3] );166 elem = document.getElementById( match[2] );
62167
63 // Handle the case where IE and Opera return items168 // Check parentNode to catch when Blackberry 4.6 returns
64 // by name instead of ID169 // nodes that are no longer in the document #6963
65 if ( elem && elem.id != match[3] )170 if ( elem && elem.parentNode ) {
66 return jQuery().find( selector );171 // Handle the case where IE and Opera return items
67172 // by name instead of ID
68 // Otherwise, we inject the element directly into the jQuery object173 if ( elem.id !== match[2] ) {
69 var ret = jQuery( elem || [] );174 return rootjQuery.find( selector );
70 ret.context = document;175 }
71 ret.selector = selector;176
72 return ret;177 // Otherwise, we inject the element directly into the jQuery object
178 this.length = 1;
179 this[0] = elem;
180 }
181
182 this.context = document;
183 this.selector = selector;
184 return this;
73 }185 }
74186
75 // HANDLE: $(expr, [context])187 // HANDLE: $(expr, $(...))
76 // (which is just equivalent to: $(content).find(expr)188 } else if ( !context || context.jquery ) {
77 } else189 return (context || rootjQuery).find( selector );
78 return jQuery( context ).find( selector );190
191 // HANDLE: $(expr, context)
192 // (which is just equivalent to: $(context).find(expr)
193 } else {
194 return this.constructor( context ).find( selector );
195 }
79196
80 // HANDLE: $(function)197 // HANDLE: $(function)
81 // Shortcut for document ready198 // Shortcut for document ready
82 } else if ( jQuery.isFunction( selector ) )199 } else if ( jQuery.isFunction( selector ) ) {
83 return jQuery( document ).ready( selector );200 return rootjQuery.ready( selector );
201 }
84202
85 // Make sure that old selector state is passed along203 if (selector.selector !== undefined) {
86 if ( selector.selector && selector.context ) {
87 this.selector = selector.selector;204 this.selector = selector.selector;
88 this.context = selector.context;205 this.context = selector.context;
89 }206 }
90207
91 return this.setArray(jQuery.isArray( selector ) ?208 return jQuery.makeArray( selector, this );
92 selector :
93 jQuery.makeArray(selector));
94 },209 },
95210
96 // Start with an empty selector211 // Start with an empty selector
97 selector: "",212 selector: "",
98213
99 // The current version of jQuery being used214 // The current version of jQuery being used
100 jquery: "1.3.2",215 jquery: "1.6.2",
216
217 // The default length of a jQuery object is 0
218 length: 0,
101219
102 // The number of elements contained in the matched element set220 // The number of elements contained in the matched element set
103 size: function() {221 size: function() {
104 return this.length;222 return this.length;
105 },223 },
106224
225 toArray: function() {
226 return slice.call( this, 0 );
227 },
228
107 // Get the Nth element in the matched element set OR229 // Get the Nth element in the matched element set OR
108 // Get the whole matched element set as a clean array230 // Get the whole matched element set as a clean array
109 get: function( num ) {231 get: function( num ) {
110 return num === undefined ?232 return num == null ?
111233
112 // Return a 'clean' array234 // Return a 'clean' array
113 Array.prototype.slice.call( this ) :235 this.toArray() :
114236
115 // Return just the object237 // Return just the object
116 this[ num ];238 ( num < 0 ? this[ this.length + num ] : this[ num ] );
117 },239 },
118240
119 // Take an array of elements and push it onto the stack241 // Take an array of elements and push it onto the stack
120 // (returning the new matched element set)242 // (returning the new matched element set)
121 pushStack: function( elems, name, selector ) {243 pushStack: function( elems, name, selector ) {
122 // Build a new jQuery matched element set244 // Build a new jQuery matched element set
123 var ret = jQuery( elems );245 var ret = this.constructor();
246
247 if ( jQuery.isArray( elems ) ) {
248 push.apply( ret, elems );
249
250 } else {
251 jQuery.merge( ret, elems );
252 }
124253
125 // Add the old object onto the stack (as a reference)254 // Add the old object onto the stack (as a reference)
126 ret.prevObject = this;255 ret.prevObject = this;
127256
128 ret.context = this.context;257 ret.context = this.context;
129258
130 if ( name === "find" )259 if ( name === "find" ) {
131 ret.selector = this.selector + (this.selector ? " " : "") + selector;260 ret.selector = this.selector + (this.selector ? " " : "") + selector;
132 else if ( name )261 } else if ( name ) {
133 ret.selector = this.selector + "." + name + "(" + selector + ")";262 ret.selector = this.selector + "." + name + "(" + selector + ")";
263 }
134264
135 // Return the newly-formed element set265 // Return the newly-formed element set
136 return ret;266 return ret;
137 },267 },
138268
139 // Force the current matched set of elements to become
140 // the specified array of elements (destroying the stack in the process)
141 // You should use pushStack() in order to do this, but maintain the stack
142 setArray: function( elems ) {
143 // Resetting the length to 0, then using the native Array push
144 // is a super-fast way to populate an object with array-like properties
145 this.length = 0;
146 Array.prototype.push.apply( this, elems );
147
148 return this;
149 },
150
151 // Execute a callback for every element in the matched set.269 // Execute a callback for every element in the matched set.
152 // (You can seed the arguments with an array of args, but this is270 // (You can seed the arguments with an array of args, but this is
153 // only used internally.)271 // only used internally.)
@@ -155,413 +273,61 @@
155 return jQuery.each( this, callback, args );273 return jQuery.each( this, callback, args );
156 },274 },
157275
158 // Determine the position of an element within276 ready: function( fn ) {
159 // the matched set of elements277 // Attach the listeners
160 index: function( elem ) {278 jQuery.bindReady();
161 // Locate the position of the desired element279
162 return jQuery.inArray(280 // Add the callback
163 // If it receives a jQuery object, the first element is used281 readyList.done( fn );
164 elem && elem.jquery ? elem[0] : elem
165 , this );
166 },
167
168 attr: function( name, value, type ) {
169 var options = name;
170
171 // Look for the case where we're accessing a style value
172 if ( typeof name === "string" )
173 if ( value === undefined )
174 return this[0] && jQuery[ type || "attr" ]( this[0], name );
175
176 else {
177 options = {};
178 options[ name ] = value;
179 }
180
181 // Check to see if we're setting style values
182 return this.each(function(i){
183 // Set all the styles
184 for ( name in options )
185 jQuery.attr(
186 type ?
187 this.style :
188 this,
189 name, jQuery.prop( this, options[ name ], type, i, name )
190 );
191 });
192 },
193
194 css: function( key, value ) {
195 // ignore negative width and height values
196 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
197 value = undefined;
198 return this.attr( key, value, "curCSS" );
199 },
200
201 text: function( text ) {
202 if ( typeof text !== "object" && text != null )
203 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
204
205 var ret = "";
206
207 jQuery.each( text || this, function(){
208 jQuery.each( this.childNodes, function(){
209 if ( this.nodeType != 8 )
210 ret += this.nodeType != 1 ?
211 this.nodeValue :
212 jQuery.fn.text( [ this ] );
213 });
214 });
215
216 return ret;
217 },
218
219 wrapAll: function( html ) {
220 if ( this[0] ) {
221 // The elements to wrap the target around
222 var wrap = jQuery( html, this[0].ownerDocument ).clone();
223
224 if ( this[0].parentNode )
225 wrap.insertBefore( this[0] );
226
227 wrap.map(function(){
228 var elem = this;
229
230 while ( elem.firstChild )
231 elem = elem.firstChild;
232
233 return elem;
234 }).append(this);
235 }
236282
237 return this;283 return this;
238 },284 },
239285
240 wrapInner: function( html ) {
241 return this.each(function(){
242 jQuery( this ).contents().wrapAll( html );
243 });
244 },
245
246 wrap: function( html ) {
247 return this.each(function(){
248 jQuery( this ).wrapAll( html );
249 });
250 },
251
252 append: function() {
253 return this.domManip(arguments, true, function(elem){
254 if (this.nodeType == 1)
255 this.appendChild( elem );
256 });
257 },
258
259 prepend: function() {
260 return this.domManip(arguments, true, function(elem){
261 if (this.nodeType == 1)
262 this.insertBefore( elem, this.firstChild );
263 });
264 },
265
266 before: function() {
267 return this.domManip(arguments, false, function(elem){
268 this.parentNode.insertBefore( elem, this );
269 });
270 },
271
272 after: function() {
273 return this.domManip(arguments, false, function(elem){
274 this.parentNode.insertBefore( elem, this.nextSibling );
275 });
276 },
277
278 end: function() {
279 return this.prevObject || jQuery( [] );
280 },
281
282 // For internal use only.
283 // Behaves like an Array's method, not like a jQuery method.
284 push: [].push,
285 sort: [].sort,
286 splice: [].splice,
287
288 find: function( selector ) {
289 if ( this.length === 1 ) {
290 var ret = this.pushStack( [], "find", selector );
291 ret.length = 0;
292 jQuery.find( selector, this[0], ret );
293 return ret;
294 } else {
295 return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
296 return jQuery.find( selector, elem );
297 })), "find", selector );
298 }
299 },
300
301 clone: function( events ) {
302 // Do the clone
303 var ret = this.map(function(){
304 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
305 // IE copies events bound via attachEvent when
306 // using cloneNode. Calling detachEvent on the
307 // clone will also remove the events from the orignal
308 // In order to get around this, we use innerHTML.
309 // Unfortunately, this means some modifications to
310 // attributes in IE that are actually only stored
311 // as properties will not be copied (such as the
312 // the name attribute on an input).
313 var html = this.outerHTML;
314 if ( !html ) {
315 var div = this.ownerDocument.createElement("div");
316 div.appendChild( this.cloneNode(true) );
317 html = div.innerHTML;
318 }
319
320 return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
321 } else
322 return this.cloneNode(true);
323 });
324
325 // Copy the events from the original to the clone
326 if ( events === true ) {
327 var orig = this.find("*").andSelf(), i = 0;
328
329 ret.find("*").andSelf().each(function(){
330 if ( this.nodeName !== orig[i].nodeName )
331 return;
332
333 var events = jQuery.data( orig[i], "events" );
334
335 for ( var type in events ) {
336 for ( var handler in events[ type ] ) {
337 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
338 }
339 }
340
341 i++;
342 });
343 }
344
345 // Return the cloned set
346 return ret;
347 },
348
349 filter: function( selector ) {
350 return this.pushStack(
351 jQuery.isFunction( selector ) &&
352 jQuery.grep(this, function(elem, i){
353 return selector.call( elem, i );
354 }) ||
355
356 jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
357 return elem.nodeType === 1;
358 }) ), "filter", selector );
359 },
360
361 closest: function( selector ) {
362 var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
363 closer = 0;
364
365 return this.map(function(){
366 var cur = this;
367 while ( cur && cur.ownerDocument ) {
368 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
369 jQuery.data(cur, "closest", closer);
370 return cur;
371 }
372 cur = cur.parentNode;
373 closer++;
374 }
375 });
376 },
377
378 not: function( selector ) {
379 if ( typeof selector === "string" )
380 // test special case where just one selector is passed in
381 if ( isSimple.test( selector ) )
382 return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
383 else
384 selector = jQuery.multiFilter( selector, this );
385
386 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
387 return this.filter(function() {
388 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
389 });
390 },
391
392 add: function( selector ) {
393 return this.pushStack( jQuery.unique( jQuery.merge(
394 this.get(),
395 typeof selector === "string" ?
396 jQuery( selector ) :
397 jQuery.makeArray( selector )
398 )));
399 },
400
401 is: function( selector ) {
402 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
403 },
404
405 hasClass: function( selector ) {
406 return !!selector && this.is( "." + selector );
407 },
408
409 val: function( value ) {
410 if ( value === undefined ) {
411 var elem = this[0];
412
413 if ( elem ) {
414 if( jQuery.nodeName( elem, 'option' ) )
415 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
416
417 // We need to handle select boxes special
418 if ( jQuery.nodeName( elem, "select" ) ) {
419 var index = elem.selectedIndex,
420 values = [],
421 options = elem.options,
422 one = elem.type == "select-one";
423
424 // Nothing was selected
425 if ( index < 0 )
426 return null;
427
428 // Loop through all the selected options
429 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
430 var option = options[ i ];
431
432 if ( option.selected ) {
433 // Get the specifc value for the option
434 value = jQuery(option).val();
435
436 // We don't need an array for one selects
437 if ( one )
438 return value;
439
440 // Multi-Selects return an array
441 values.push( value );
442 }
443 }
444
445 return values;
446 }
447
448 // Everything else, we just grab the value
449 return (elem.value || "").replace(/\r/g, "");
450
451 }
452
453 return undefined;
454 }
455
456 if ( typeof value === "number" )
457 value += '';
458
459 return this.each(function(){
460 if ( this.nodeType != 1 )
461 return;
462
463 if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
464 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
465 jQuery.inArray(this.name, value) >= 0);
466
467 else if ( jQuery.nodeName( this, "select" ) ) {
468 var values = jQuery.makeArray(value);
469
470 jQuery( "option", this ).each(function(){
471 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
472 jQuery.inArray( this.text, values ) >= 0);
473 });
474
475 if ( !values.length )
476 this.selectedIndex = -1;
477
478 } else
479 this.value = value;
480 });
481 },
482
483 html: function( value ) {
484 return value === undefined ?
485 (this[0] ?
486 this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
487 null) :
488 this.empty().append( value );
489 },
490
491 replaceWith: function( value ) {
492 return this.after( value ).remove();
493 },
494
495 eq: function( i ) {286 eq: function( i ) {
496 return this.slice( i, +i + 1 );287 return i === -1 ?
288 this.slice( i ) :
289 this.slice( i, +i + 1 );
290 },
291
292 first: function() {
293 return this.eq( 0 );
294 },
295
296 last: function() {
297 return this.eq( -1 );
497 },298 },
498299
499 slice: function() {300 slice: function() {
500 return this.pushStack( Array.prototype.slice.apply( this, arguments ),301 return this.pushStack( slice.apply( this, arguments ),
501 "slice", Array.prototype.slice.call(arguments).join(",") );302 "slice", slice.call(arguments).join(",") );
502 },303 },
503304
504 map: function( callback ) {305 map: function( callback ) {
505 return this.pushStack( jQuery.map(this, function(elem, i){306 return this.pushStack( jQuery.map(this, function( elem, i ) {
506 return callback.call( elem, i, elem );307 return callback.call( elem, i, elem );
507 }));308 }));
508 },309 },
509310
510 andSelf: function() {311 end: function() {
511 return this.add( this.prevObject );312 return this.prevObject || this.constructor(null);
512 },313 },
513314
514 domManip: function( args, table, callback ) {315 // For internal use only.
515 if ( this[0] ) {316 // Behaves like an Array's method, not like a jQuery method.
516 var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),317 push: push,
517 scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),318 sort: [].sort,
518 first = fragment.firstChild;319 splice: [].splice
519
520 if ( first )
521 for ( var i = 0, l = this.length; i < l; i++ )
522 callback.call( root(this[i], first), this.length > 1 || i > 0 ?
523 fragment.cloneNode(true) : fragment );
524
525 if ( scripts )
526 jQuery.each( scripts, evalScript );
527 }
528
529 return this;
530
531 function root( elem, cur ) {
532 return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
533 (elem.getElementsByTagName("tbody")[0] ||
534 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
535 elem;
536 }
537 }
538};320};
539321
540// Give the init function the jQuery prototype for later instantiation322// Give the init function the jQuery prototype for later instantiation
541jQuery.fn.init.prototype = jQuery.fn;323jQuery.fn.init.prototype = jQuery.fn;
542324
543function evalScript( i, elem ) {
544 if ( elem.src )
545 jQuery.ajax({
546 url: elem.src,
547 async: false,
548 dataType: "script"
549 });
550
551 else
552 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
553
554 if ( elem.parentNode )
555 elem.parentNode.removeChild( elem );
556}
557
558function now(){
559 return +new Date;
560}
561
562jQuery.extend = jQuery.fn.extend = function() {325jQuery.extend = jQuery.fn.extend = function() {
563 // copy reference to target object326 var options, name, src, copy, copyIsArray, clone,
564 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;327 target = arguments[0] || {},
328 i = 1,
329 length = arguments.length,
330 deep = false;
565331
566 // Handle a deep copy situation332 // Handle a deep copy situation
567 if ( typeof target === "boolean" ) {333 if ( typeof target === "boolean" ) {
@@ -572,884 +338,3464 @@
572 }338 }
573339
574 // Handle case when target is a string or something (possible in deep copy)340 // Handle case when target is a string or something (possible in deep copy)
575 if ( typeof target !== "object" && !jQuery.isFunction(target) )341 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
576 target = {};342 target = {};
343 }
577344
578 // extend jQuery itself if only one argument is passed345 // extend jQuery itself if only one argument is passed
579 if ( length == i ) {346 if ( length === i ) {
580 target = this;347 target = this;
581 --i;348 --i;
582 }349 }
583350
584 for ( ; i < length; i++ )351 for ( ; i < length; i++ ) {
585 // Only deal with non-null/undefined values352 // Only deal with non-null/undefined values
586 if ( (options = arguments[ i ]) != null )353 if ( (options = arguments[ i ]) != null ) {
587 // Extend the base object354 // Extend the base object
588 for ( var name in options ) {355 for ( name in options ) {
589 var src = target[ name ], copy = options[ name ];356 src = target[ name ];
357 copy = options[ name ];
590358
591 // Prevent never-ending loop359 // Prevent never-ending loop
592 if ( target === copy )360 if ( target === copy ) {
593 continue;361 continue;
594362 }
595 // Recurse if we're merging object values363
596 if ( deep && copy && typeof copy === "object" && !copy.nodeType )364 // Recurse if we're merging plain objects or arrays
597 target[ name ] = jQuery.extend( deep, 365 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
598 // Never move original objects, clone them366 if ( copyIsArray ) {
599 src || ( copy.length != null ? [ ] : { } )367 copyIsArray = false;
600 , copy );368 clone = src && jQuery.isArray(src) ? src : [];
369
370 } else {
371 clone = src && jQuery.isPlainObject(src) ? src : {};
372 }
373
374 // Never move original objects, clone them
375 target[ name ] = jQuery.extend( deep, clone, copy );
601376
602 // Don't bring in undefined values377 // Don't bring in undefined values
603 else if ( copy !== undefined )378 } else if ( copy !== undefined ) {
604 target[ name ] = copy;379 target[ name ] = copy;
605380 }
606 }381 }
382 }
383 }
607384
608 // Return the modified object385 // Return the modified object
609 return target;386 return target;
610};387};
611388
612// exclude the following css properties to add px
613var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
614 // cache defaultView
615 defaultView = document.defaultView || {},
616 toString = Object.prototype.toString;
617
618jQuery.extend({389jQuery.extend({
619 noConflict: function( deep ) {390 noConflict: function( deep ) {
620 window.$ = _$;391 if ( window.$ === jQuery ) {
392 window.$ = _$;
393 }
621394
622 if ( deep )395 if ( deep && window.jQuery === jQuery ) {
623 window.jQuery = _jQuery;396 window.jQuery = _jQuery;
397 }
624398
625 return jQuery;399 return jQuery;
626 },400 },
627401
402 // Is the DOM ready to be used? Set to true once it occurs.
403 isReady: false,
404
405 // A counter to track how many items to wait for before
406 // the ready event fires. See #6781
407 readyWait: 1,
408
409 // Hold (or release) the ready event
410 holdReady: function( hold ) {
411 if ( hold ) {
412 jQuery.readyWait++;
413 } else {
414 jQuery.ready( true );
415 }
416 },
417
418 // Handle when the DOM is ready
419 ready: function( wait ) {
420 // Either a released hold or an DOMready/load event and not yet ready
421 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
422 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
423 if ( !document.body ) {
424 return setTimeout( jQuery.ready, 1 );
425 }
426
427 // Remember that the DOM is ready
428 jQuery.isReady = true;
429
430 // If a normal DOM Ready event fired, decrement, and wait if need be
431 if ( wait !== true && --jQuery.readyWait > 0 ) {
432 return;
433 }
434
435 // If there are functions bound, to execute
436 readyList.resolveWith( document, [ jQuery ] );
437
438 // Trigger any bound ready events
439 if ( jQuery.fn.trigger ) {
440 jQuery( document ).trigger( "ready" ).unbind( "ready" );
441 }
442 }
443 },
444
445 bindReady: function() {
446 if ( readyList ) {
447 return;
448 }
449
450 readyList = jQuery._Deferred();
451
452 // Catch cases where $(document).ready() is called after the
453 // browser event has already occurred.
454 if ( document.readyState === "complete" ) {
455 // Handle it asynchronously to allow scripts the opportunity to delay ready
456 return setTimeout( jQuery.ready, 1 );
457 }
458
459 // Mozilla, Opera and webkit nightlies currently support this event
460 if ( document.addEventListener ) {
461 // Use the handy event callback
462 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
463
464 // A fallback to window.onload, that will always work
465 window.addEventListener( "load", jQuery.ready, false );
466
467 // If IE event model is used
468 } else if ( document.attachEvent ) {
469 // ensure firing before onload,
470 // maybe late but safe also for iframes
471 document.attachEvent( "onreadystatechange", DOMContentLoaded );
472
473 // A fallback to window.onload, that will always work
474 window.attachEvent( "onload", jQuery.ready );
475
476 // If IE and not a frame
477 // continually check to see if the document is ready
478 var toplevel = false;
479
480 try {
481 toplevel = window.frameElement == null;
482 } catch(e) {}
483
484 if ( document.documentElement.doScroll && toplevel ) {
485 doScrollCheck();
486 }
487 }
488 },
489
628 // See test/unit/core.js for details concerning isFunction.490 // See test/unit/core.js for details concerning isFunction.
629 // Since version 1.3, DOM methods and functions like alert491 // Since version 1.3, DOM methods and functions like alert
630 // aren't supported. They return false on IE (#2968).492 // aren't supported. They return false on IE (#2968).
631 isFunction: function( obj ) {493 isFunction: function( obj ) {
632 return toString.call(obj) === "[object Function]";494 return jQuery.type(obj) === "function";
633 },495 },
634496
635 isArray: function( obj ) {497 isArray: Array.isArray || function( obj ) {
636 return toString.call(obj) === "[object Array]";498 return jQuery.type(obj) === "array";
637 },499 },
638500
639 // check if an element is in a (or is an) XML document501 // A crude way of determining if an object is a window
640 isXMLDoc: function( elem ) {502 isWindow: function( obj ) {
641 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||503 return obj && typeof obj === "object" && "setInterval" in obj;
642 !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );504 },
643 },505
644506 isNaN: function( obj ) {
645 // Evalulates a script in a global context507 return obj == null || !rdigit.test( obj ) || isNaN( obj );
508 },
509
510 type: function( obj ) {
511 return obj == null ?
512 String( obj ) :
513 class2type[ toString.call(obj) ] || "object";
514 },
515
516 isPlainObject: function( obj ) {
517 // Must be an Object.
518 // Because of IE, we also have to check the presence of the constructor property.
519 // Make sure that DOM nodes and window objects don't pass through, as well
520 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
521 return false;
522 }
523
524 // Not own constructor property must be Object
525 if ( obj.constructor &&
526 !hasOwn.call(obj, "constructor") &&
527 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
528 return false;
529 }
530
531 // Own properties are enumerated firstly, so to speed up,
532 // if last one is own, then all properties are own.
533
534 var key;
535 for ( key in obj ) {}
536
537 return key === undefined || hasOwn.call( obj, key );
538 },
539
540 isEmptyObject: function( obj ) {
541 for ( var name in obj ) {
542 return false;
543 }
544 return true;
545 },
546
547 error: function( msg ) {
548 throw msg;
549 },
550
551 parseJSON: function( data ) {
552 if ( typeof data !== "string" || !data ) {
553 return null;
554 }
555
556 // Make sure leading/trailing whitespace is removed (IE can't handle it)
557 data = jQuery.trim( data );
558
559 // Attempt to parse using the native JSON parser first
560 if ( window.JSON && window.JSON.parse ) {
561 return window.JSON.parse( data );
562 }
563
564 // Make sure the incoming data is actual JSON
565 // Logic borrowed from http://json.org/json2.js
566 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
567 .replace( rvalidtokens, "]" )
568 .replace( rvalidbraces, "")) ) {
569
570 return (new Function( "return " + data ))();
571
572 }
573 jQuery.error( "Invalid JSON: " + data );
574 },
575
576 // Cross-browser xml parsing
577 // (xml & tmp used internally)
578 parseXML: function( data , xml , tmp ) {
579
580 if ( window.DOMParser ) { // Standard
581 tmp = new DOMParser();
582 xml = tmp.parseFromString( data , "text/xml" );
583 } else { // IE
584 xml = new ActiveXObject( "Microsoft.XMLDOM" );
585 xml.async = "false";
586 xml.loadXML( data );
587 }
588
589 tmp = xml.documentElement;
590
591 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
592 jQuery.error( "Invalid XML: " + data );
593 }
594
595 return xml;
596 },
597
598 noop: function() {},
599
600 // Evaluates a script in a global context
601 // Workarounds based on findings by Jim Driscoll
602 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
646 globalEval: function( data ) {603 globalEval: function( data ) {
647 if ( data && /\S/.test(data) ) {604 if ( data && rnotwhite.test( data ) ) {
648 // Inspired by code by Andrea Giammarchi605 // We use execScript on Internet Explorer
649 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html606 // We use an anonymous function so that context is window
650 var head = document.getElementsByTagName("head")[0] || document.documentElement,607 // rather than jQuery in Firefox
651 script = document.createElement("script");608 ( window.execScript || function( data ) {
652609 window[ "eval" ].call( window, data );
653 script.type = "text/javascript";610 } )( data );
654 if ( jQuery.support.scriptEval )
655 script.appendChild( document.createTextNode( data ) );
656 else
657 script.text = data;
658
659 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
660 // This arises when a base node is used (#2709).
661 head.insertBefore( script, head.firstChild );
662 head.removeChild( script );
663 }611 }
664 },612 },
665613
614 // Converts a dashed string to camelCased string;
615 // Used by both the css and data modules
616 camelCase: function( string ) {
617 return string.replace( rdashAlpha, fcamelCase );
618 },
619
666 nodeName: function( elem, name ) {620 nodeName: function( elem, name ) {
667 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();621 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
668 },622 },
669623
670 // args is for internal usage only624 // args is for internal usage only
671 each: function( object, callback, args ) {625 each: function( object, callback, args ) {
672 var name, i = 0, length = object.length;626 var name, i = 0,
627 length = object.length,
628 isObj = length === undefined || jQuery.isFunction( object );
673629
674 if ( args ) {630 if ( args ) {
675 if ( length === undefined ) {631 if ( isObj ) {
676 for ( name in object )632 for ( name in object ) {
677 if ( callback.apply( object[ name ], args ) === false )633 if ( callback.apply( object[ name ], args ) === false ) {
678 break;634 break;
679 } else635 }
680 for ( ; i < length; )636 }
681 if ( callback.apply( object[ i++ ], args ) === false )637 } else {
682 break;638 for ( ; i < length; ) {
639 if ( callback.apply( object[ i++ ], args ) === false ) {
640 break;
641 }
642 }
643 }
683644
684 // A special, fast, case for the most common use of each645 // A special, fast, case for the most common use of each
685 } else {646 } else {
686 if ( length === undefined ) {647 if ( isObj ) {
687 for ( name in object )648 for ( name in object ) {
688 if ( callback.call( object[ name ], name, object[ name ] ) === false )649 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
689 break;650 break;
690 } else651 }
691 for ( var value = object[0];652 }
692 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}653 } else {
654 for ( ; i < length; ) {
655 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
656 break;
657 }
658 }
659 }
693 }660 }
694661
695 return object;662 return object;
696 },663 },
697664
698 prop: function( elem, value, type, i, name ) {665 // Use native String.trim function wherever possible
699 // Handle executable functions666 trim: trim ?
700 if ( jQuery.isFunction( value ) )667 function( text ) {
701 value = value.call( elem, i );668 return text == null ?
702669 "" :
703 // Handle passing in a number to a CSS property670 trim.call( text );
704 return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?671 } :
705 value + "px" :672
706 value;673 // Otherwise use our own trimming functionality
707 },674 function( text ) {
708675 return text == null ?
709 className: {676 "" :
710 // internal only, use addClass("class")677 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
711 add: function( elem, classNames ) {678 },
712 jQuery.each((classNames || "").split(/\s+/), function(i, className){679
713 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )680 // results is for internal usage only
714 elem.className += (elem.className ? " " : "") + className;681 makeArray: function( array, results ) {
715 });682 var ret = results || [];
716 },683
717684 if ( array != null ) {
718 // internal only, use removeClass("class")
719 remove: function( elem, classNames ) {
720 if (elem.nodeType == 1)
721 elem.className = classNames !== undefined ?
722 jQuery.grep(elem.className.split(/\s+/), function(className){
723 return !jQuery.className.has( classNames, className );
724 }).join(" ") :
725 "";
726 },
727
728 // internal only, use hasClass("class")
729 has: function( elem, className ) {
730 return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
731 }
732 },
733
734 // A method for quickly swapping in/out CSS properties to get correct calculations
735 swap: function( elem, options, callback ) {
736 var old = {};
737 // Remember the old values, and insert the new ones
738 for ( var name in options ) {
739 old[ name ] = elem.style[ name ];
740 elem.style[ name ] = options[ name ];
741 }
742
743 callback.call( elem );
744
745 // Revert the old values
746 for ( var name in options )
747 elem.style[ name ] = old[ name ];
748 },
749
750 css: function( elem, name, force, extra ) {
751 if ( name == "width" || name == "height" ) {
752 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
753
754 function getWH() {
755 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
756
757 if ( extra === "border" )
758 return;
759
760 jQuery.each( which, function() {
761 if ( !extra )
762 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
763 if ( extra === "margin" )
764 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
765 else
766 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
767 });
768 }
769
770 if ( elem.offsetWidth !== 0 )
771 getWH();
772 else
773 jQuery.swap( elem, props, getWH );
774
775 return Math.max(0, Math.round(val));
776 }
777
778 return jQuery.curCSS( elem, name, force );
779 },
780
781 curCSS: function( elem, name, force ) {
782 var ret, style = elem.style;
783
784 // We need to handle opacity special in IE
785 if ( name == "opacity" && !jQuery.support.opacity ) {
786 ret = jQuery.attr( style, "opacity" );
787
788 return ret == "" ?
789 "1" :
790 ret;
791 }
792
793 // Make sure we're using the right name for getting the float value
794 if ( name.match( /float/i ) )
795 name = styleFloat;
796
797 if ( !force && style && style[ name ] )
798 ret = style[ name ];
799
800 else if ( defaultView.getComputedStyle ) {
801
802 // Only "float" is needed here
803 if ( name.match( /float/i ) )
804 name = "float";
805
806 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
807
808 var computedStyle = defaultView.getComputedStyle( elem, null );
809
810 if ( computedStyle )
811 ret = computedStyle.getPropertyValue( name );
812
813 // We should always get a number back from opacity
814 if ( name == "opacity" && ret == "" )
815 ret = "1";
816
817 } else if ( elem.currentStyle ) {
818 var camelCase = name.replace(/\-(\w)/g, function(all, letter){
819 return letter.toUpperCase();
820 });
821
822 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
823
824 // From the awesome hack by Dean Edwards
825 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
826
827 // If we're not dealing with a regular pixel number
828 // but a number that has a weird ending, we need to convert it to pixels
829 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
830 // Remember the original values
831 var left = style.left, rsLeft = elem.runtimeStyle.left;
832
833 // Put in the new values to get a computed value out
834 elem.runtimeStyle.left = elem.currentStyle.left;
835 style.left = ret || 0;
836 ret = style.pixelLeft + "px";
837
838 // Revert the changed values
839 style.left = left;
840 elem.runtimeStyle.left = rsLeft;
841 }
842 }
843
844 return ret;
845 },
846
847 clean: function( elems, context, fragment ) {
848 context = context || document;
849
850 // !context.createElement fails in IE with an error but returns typeof 'object'
851 if ( typeof context.createElement === "undefined" )
852 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
853
854 // If a single string is passed in and it's a single tag
855 // just do a createElement and skip the rest
856 if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
857 var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
858 if ( match )
859 return [ context.createElement( match[1] ) ];
860 }
861
862 var ret = [], scripts = [], div = context.createElement("div");
863
864 jQuery.each(elems, function(i, elem){
865 if ( typeof elem === "number" )
866 elem += '';
867
868 if ( !elem )
869 return;
870
871 // Convert html string into DOM nodes
872 if ( typeof elem === "string" ) {
873 // Fix "XHTML"-style tags in all browsers
874 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
875 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
876 all :
877 front + "></" + tag + ">";
878 });
879
880 // Trim whitespace, otherwise indexOf won't work as expected
881 var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
882
883 var wrap =
884 // option or optgroup
885 !tags.indexOf("<opt") &&
886 [ 1, "<select multiple='multiple'>", "</select>" ] ||
887
888 !tags.indexOf("<leg") &&
889 [ 1, "<fieldset>", "</fieldset>" ] ||
890
891 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
892 [ 1, "<table>", "</table>" ] ||
893
894 !tags.indexOf("<tr") &&
895 [ 2, "<table><tbody>", "</tbody></table>" ] ||
896
897 // <thead> matched above
898 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
899 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
900
901 !tags.indexOf("<col") &&
902 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
903
904 // IE can't serialize <link> and <script> tags normally
905 !jQuery.support.htmlSerialize &&
906 [ 1, "div<div>", "</div>" ] ||
907
908 [ 0, "", "" ];
909
910 // Go to html and back, then peel off extra wrappers
911 div.innerHTML = wrap[1] + elem + wrap[2];
912
913 // Move to the right depth
914 while ( wrap[0]-- )
915 div = div.lastChild;
916
917 // Remove IE's autoinserted <tbody> from table fragments
918 if ( !jQuery.support.tbody ) {
919
920 // String was a <table>, *may* have spurious <tbody>
921 var hasBody = /<tbody/i.test(elem),
922 tbody = !tags.indexOf("<table") && !hasBody ?
923 div.firstChild && div.firstChild.childNodes :
924
925 // String was a bare <thead> or <tfoot>
926 wrap[1] == "<table>" && !hasBody ?
927 div.childNodes :
928 [];
929
930 for ( var j = tbody.length - 1; j >= 0 ; --j )
931 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
932 tbody[ j ].parentNode.removeChild( tbody[ j ] );
933
934 }
935
936 // IE completely kills leading whitespace when innerHTML is used
937 if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
938 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
939
940 elem = jQuery.makeArray( div.childNodes );
941 }
942
943 if ( elem.nodeType )
944 ret.push( elem );
945 else
946 ret = jQuery.merge( ret, elem );
947
948 });
949
950 if ( fragment ) {
951 for ( var i = 0; ret[i]; i++ ) {
952 if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
953 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
954 } else {
955 if ( ret[i].nodeType === 1 )
956 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
957 fragment.appendChild( ret[i] );
958 }
959 }
960
961 return scripts;
962 }
963
964 return ret;
965 },
966
967 attr: function( elem, name, value ) {
968 // don't set attributes on text and comment nodes
969 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
970 return undefined;
971
972 var notxml = !jQuery.isXMLDoc( elem ),
973 // Whether we are setting (or getting)
974 set = value !== undefined;
975
976 // Try to normalize/fix the name
977 name = notxml && jQuery.props[ name ] || name;
978
979 // Only do all the following if this is a node (faster for style)
980 // IE elem.getAttribute passes even for style
981 if ( elem.tagName ) {
982
983 // These attributes require special treatment
984 var special = /href|src|style/.test( name );
985
986 // Safari mis-reports the default selected property of a hidden option
987 // Accessing the parent's selectedIndex property fixes it
988 if ( name == "selected" && elem.parentNode )
989 elem.parentNode.selectedIndex;
990
991 // If applicable, access the attribute via the DOM 0 way
992 if ( name in elem && notxml && !special ) {
993 if ( set ){
994 // We can't allow the type property to be changed (since it causes problems in IE)
995 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
996 throw "type property can't be changed";
997
998 elem[ name ] = value;
999 }
1000
1001 // browsers index elements by id/name on forms, give priority to attributes.
1002 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1003 return elem.getAttributeNode( name ).nodeValue;
1004
1005 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1006 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1007 if ( name == "tabIndex" ) {
1008 var attributeNode = elem.getAttributeNode( "tabIndex" );
1009 return attributeNode && attributeNode.specified
1010 ? attributeNode.value
1011 : elem.nodeName.match(/(button|input|object|select|textarea)/i)
1012 ? 0
1013 : elem.nodeName.match(/^(a|area)$/i) && elem.href
1014 ? 0
1015 : undefined;
1016 }
1017
1018 return elem[ name ];
1019 }
1020
1021 if ( !jQuery.support.style && notxml && name == "style" )
1022 return jQuery.attr( elem.style, "cssText", value );
1023
1024 if ( set )
1025 // convert the value to a string (all browsers do this but IE) see #1070
1026 elem.setAttribute( name, "" + value );
1027
1028 var attr = !jQuery.support.hrefNormalized && notxml && special
1029 // Some attributes require a special call on IE
1030 ? elem.getAttribute( name, 2 )
1031 : elem.getAttribute( name );
1032
1033 // Non-existent attributes return null, we normalize to undefined
1034 return attr === null ? undefined : attr;
1035 }
1036
1037 // elem is actually elem.style ... set the style
1038
1039 // IE uses filters for opacity
1040 if ( !jQuery.support.opacity && name == "opacity" ) {
1041 if ( set ) {
1042 // IE has trouble with opacity if it does not have layout
1043 // Force it by setting the zoom level
1044 elem.zoom = 1;
1045
1046 // Set the alpha filter to set the opacity
1047 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1048 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1049 }
1050
1051 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1052 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1053 "";
1054 }
1055
1056 name = name.replace(/-([a-z])/ig, function(all, letter){
1057 return letter.toUpperCase();
1058 });
1059
1060 if ( set )
1061 elem[ name ] = value;
1062
1063 return elem[ name ];
1064 },
1065
1066 trim: function( text ) {
1067 return (text || "").replace( /^\s+|\s+$/g, "" );
1068 },
1069
1070 makeArray: function( array ) {
1071 var ret = [];
1072
1073 if( array != null ){
1074 var i = array.length;
1075 // The window, strings (and functions) also have 'length'685 // The window, strings (and functions) also have 'length'
1076 if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )686 // The extra typeof function check is to prevent crashes
1077 ret[0] = array;687 // in Safari 2 (See: #3039)
1078 else688 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
1079 while( i )689 var type = jQuery.type( array );
1080 ret[--i] = array[i];690
691 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
692 push.call( ret, array );
693 } else {
694 jQuery.merge( ret, array );
695 }
1081 }696 }
1082697
1083 return ret;698 return ret;
1084 },699 },
1085700
1086 inArray: function( elem, array ) {701 inArray: function( elem, array ) {
1087 for ( var i = 0, length = array.length; i < length; i++ )702
1088 // Use === because on IE, window == document703 if ( indexOf ) {
1089 if ( array[ i ] === elem )704 return indexOf.call( array, elem );
705 }
706
707 for ( var i = 0, length = array.length; i < length; i++ ) {
708 if ( array[ i ] === elem ) {
1090 return i;709 return i;
710 }
711 }
1091712
1092 return -1;713 return -1;
1093 },714 },
1094715
1095 merge: function( first, second ) {716 merge: function( first, second ) {
1096 // We have to loop this way because IE & Opera overwrite the length717 var i = first.length,
1097 // expando of getElementsByTagName718 j = 0;
1098 var i = 0, elem, pos = first.length;719
1099 // Also, we need to make sure that the correct elements are being returned720 if ( typeof second.length === "number" ) {
1100 // (IE returns comment nodes in a '*' query)721 for ( var l = second.length; j < l; j++ ) {
1101 if ( !jQuery.support.getAll ) {722 first[ i++ ] = second[ j ];
1102 while ( (elem = second[ i++ ]) != null )723 }
1103 if ( elem.nodeType != 8 )724
1104 first[ pos++ ] = elem;725 } else {
1105726 while ( second[j] !== undefined ) {
1106 } else727 first[ i++ ] = second[ j++ ];
1107 while ( (elem = second[ i++ ]) != null )728 }
1108 first[ pos++ ] = elem;729 }
730
731 first.length = i;
1109732
1110 return first;733 return first;
1111 },734 },
1112735
1113 unique: function( array ) {
1114 var ret = [], done = {};
1115
1116 try {
1117
1118 for ( var i = 0, length = array.length; i < length; i++ ) {
1119 var id = jQuery.data( array[ i ] );
1120
1121 if ( !done[ id ] ) {
1122 done[ id ] = true;
1123 ret.push( array[ i ] );
1124 }
1125 }
1126
1127 } catch( e ) {
1128 ret = array;
1129 }
1130
1131 return ret;
1132 },
1133
1134 grep: function( elems, callback, inv ) {736 grep: function( elems, callback, inv ) {
1135 var ret = [];737 var ret = [], retVal;
738 inv = !!inv;
1136739
1137 // Go through the array, only saving the items740 // Go through the array, only saving the items
1138 // that pass the validator function741 // that pass the validator function
1139 for ( var i = 0, length = elems.length; i < length; i++ )742 for ( var i = 0, length = elems.length; i < length; i++ ) {
1140 if ( !inv != !callback( elems[ i ], i ) )743 retVal = !!callback( elems[ i ], i );
744 if ( inv !== retVal ) {
1141 ret.push( elems[ i ] );745 ret.push( elems[ i ] );
746 }
747 }
1142748
1143 return ret;749 return ret;
1144 },750 },
1145751
1146 map: function( elems, callback ) {752 // arg is for internal usage only
1147 var ret = [];753 map: function( elems, callback, arg ) {
754 var value, key, ret = [],
755 i = 0,
756 length = elems.length,
757 // jquery objects are treated as arrays
758 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
1148759
1149 // Go through the array, translating each of the items to their760 // Go through the array, translating each of the items to their
1150 // new value (or values).761 if ( isArray ) {
1151 for ( var i = 0, length = elems.length; i < length; i++ ) {762 for ( ; i < length; i++ ) {
1152 var value = callback( elems[ i ], i );763 value = callback( elems[ i ], i, arg );
1153764
1154 if ( value != null )765 if ( value != null ) {
1155 ret[ ret.length ] = value;766 ret[ ret.length ] = value;
767 }
768 }
769
770 // Go through every key on the object,
771 } else {
772 for ( key in elems ) {
773 value = callback( elems[ key ], key, arg );
774
775 if ( value != null ) {
776 ret[ ret.length ] = value;
777 }
778 }
1156 }779 }
1157780
781 // Flatten any nested arrays
1158 return ret.concat.apply( [], ret );782 return ret.concat.apply( [], ret );
1159 }783 },
1160});784
1161785 // A global GUID counter for objects
1162// Use of jQuery.browser is deprecated.786 guid: 1,
1163// It's included for backwards compatibility and plugins,787
1164// although they should work to migrate away.788 // Bind a function to a context, optionally partially applying any
1165789 // arguments.
1166var userAgent = navigator.userAgent.toLowerCase();790 proxy: function( fn, context ) {
1167791 if ( typeof context === "string" ) {
1168// Figure out what browser is being used792 var tmp = fn[ context ];
1169jQuery.browser = {793 context = fn;
1170 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],794 fn = tmp;
1171 safari: /webkit/.test( userAgent ),795 }
1172 opera: /opera/.test( userAgent ),796
1173 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),797 // Quick check to determine if target is callable, in the spec
1174 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )798 // this throws a TypeError, but we will just return undefined.
1175};799 if ( !jQuery.isFunction( fn ) ) {
1176800 return undefined;
1177jQuery.each({801 }
1178 parent: function(elem){return elem.parentNode;},802
1179 parents: function(elem){return jQuery.dir(elem,"parentNode");},803 // Simulated bind
1180 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},804 var args = slice.call( arguments, 2 ),
1181 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},805 proxy = function() {
1182 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},806 return fn.apply( context, args.concat( slice.call( arguments ) ) );
1183 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},807 };
1184 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},808
1185 children: function(elem){return jQuery.sibling(elem.firstChild);},809 // Set the guid of unique handler to the same of original handler, so it can be removed
1186 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}810 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
1187}, function(name, fn){811
1188 jQuery.fn[ name ] = function( selector ) {812 return proxy;
1189 var ret = jQuery.map( this, fn );813 },
1190814
1191 if ( selector && typeof selector == "string" )815 // Mutifunctional method to get and set values to a collection
1192 ret = jQuery.multiFilter( selector, ret );816 // The value/s can optionally be executed if it's a function
1193817 access: function( elems, key, value, exec, fn, pass ) {
1194 return this.pushStack( jQuery.unique( ret ), name, selector );818 var length = elems.length;
1195 };819
1196});820 // Setting many attributes
1197821 if ( typeof key === "object" ) {
1198jQuery.each({822 for ( var k in key ) {
1199 appendTo: "append",823 jQuery.access( elems, k, key[k], exec, fn, value );
1200 prependTo: "prepend",824 }
1201 insertBefore: "before",825 return elems;
1202 insertAfter: "after",826 }
1203 replaceAll: "replaceWith"827
1204}, function(name, original){828 // Setting one attribute
1205 jQuery.fn[ name ] = function( selector ) {829 if ( value !== undefined ) {
1206 var ret = [], insert = jQuery( selector );830 // Optionally, function values get executed if exec is true
1207831 exec = !pass && exec && jQuery.isFunction(value);
1208 for ( var i = 0, l = insert.length; i < l; i++ ) {832
1209 var elems = (i > 0 ? this.clone(true) : this).get();833 for ( var i = 0; i < length; i++ ) {
1210 jQuery.fn[ original ].apply( jQuery(insert[i]), elems );834 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
1211 ret = ret.concat( elems );835 }
1212 }836
1213837 return elems;
1214 return this.pushStack( ret, name, selector );838 }
1215 };839
1216});840 // Getting an attribute
1217841 return length ? fn( elems[0], key ) : undefined;
1218jQuery.each({842 },
1219 removeAttr: function( name ) {843
1220 jQuery.attr( this, name, "" );844 now: function() {
1221 if (this.nodeType == 1)845 return (new Date()).getTime();
1222 this.removeAttribute( name );846 },
1223 },847
1224848 // Use of jQuery.browser is frowned upon.
1225 addClass: function( classNames ) {849 // More details: http://docs.jquery.com/Utilities/jQuery.browser
1226 jQuery.className.add( this, classNames );850 uaMatch: function( ua ) {
1227 },851 ua = ua.toLowerCase();
1228852
1229 removeClass: function( classNames ) {853 var match = rwebkit.exec( ua ) ||
1230 jQuery.className.remove( this, classNames );854 ropera.exec( ua ) ||
1231 },855 rmsie.exec( ua ) ||
1232856 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
1233 toggleClass: function( classNames, state ) {857 [];
1234 if( typeof state !== "boolean" )858
1235 state = !jQuery.className.has( this, classNames );859 return { browser: match[1] || "", version: match[2] || "0" };
1236 jQuery.className[ state ? "add" : "remove" ]( this, classNames );860 },
1237 },861
1238862 sub: function() {
1239 remove: function( selector ) {863 function jQuerySub( selector, context ) {
1240 if ( !selector || jQuery.filter( selector, [ this ] ).length ) {864 return new jQuerySub.fn.init( selector, context );
1241 // Prevent memory leaks865 }
1242 jQuery( "*", this ).add([this]).each(function(){866 jQuery.extend( true, jQuerySub, this );
1243 jQuery.event.remove(this);867 jQuerySub.superclass = this;
1244 jQuery.removeData(this);868 jQuerySub.fn = jQuerySub.prototype = this();
1245 });869 jQuerySub.fn.constructor = jQuerySub;
1246 if (this.parentNode)870 jQuerySub.sub = this.sub;
1247 this.parentNode.removeChild( this );871 jQuerySub.fn.init = function init( selector, context ) {
1248 }872 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
1249 },873 context = jQuerySub( context );
1250874 }
1251 empty: function() {875
1252 // Remove element nodes and prevent memory leaks876 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
1253 jQuery(this).children().remove();877 };
1254878 jQuerySub.fn.init.prototype = jQuerySub.fn;
1255 // Remove any remaining nodes879 var rootjQuerySub = jQuerySub(document);
1256 while ( this.firstChild )880 return jQuerySub;
1257 this.removeChild( this.firstChild );881 },
1258 }882
1259}, function(name, fn){883 browser: {}
1260 jQuery.fn[ name ] = function(){884});
1261 return this.each( fn, arguments );885
1262 };886// Populate the class2type map
1263});887jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
1264888 class2type[ "[object " + name + "]" ] = name.toLowerCase();
1265// Helper function used by the dimensions and offset modules889});
1266function num(elem, prop) {890
1267 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;891browserMatch = jQuery.uaMatch( userAgent );
1268}892if ( browserMatch.browser ) {
1269var expando = "jQuery" + now(), uuid = 0, windowData = {};893 jQuery.browser[ browserMatch.browser ] = true;
894 jQuery.browser.version = browserMatch.version;
895}
896
897// Deprecated, use jQuery.browser.webkit instead
898if ( jQuery.browser.webkit ) {
899 jQuery.browser.safari = true;
900}
901
902// IE doesn't match non-breaking spaces with \s
903if ( rnotwhite.test( "\xA0" ) ) {
904 trimLeft = /^[\s\xA0]+/;
905 trimRight = /[\s\xA0]+$/;
906}
907
908// All jQuery objects should point back to these
909rootjQuery = jQuery(document);
910
911// Cleanup functions for the document ready method
912if ( document.addEventListener ) {
913 DOMContentLoaded = function() {
914 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
915 jQuery.ready();
916 };
917
918} else if ( document.attachEvent ) {
919 DOMContentLoaded = function() {
920 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
921 if ( document.readyState === "complete" ) {
922 document.detachEvent( "onreadystatechange", DOMContentLoaded );
923 jQuery.ready();
924 }
925 };
926}
927
928// The DOM ready check for Internet Explorer
929function doScrollCheck() {
930 if ( jQuery.isReady ) {
931 return;
932 }
933
934 try {
935 // If IE is used, use the trick by Diego Perini
936 // http://javascript.nwbox.com/IEContentLoaded/
937 document.documentElement.doScroll("left");
938 } catch(e) {
939 setTimeout( doScrollCheck, 1 );
940 return;
941 }
942
943 // and execute any waiting functions
944 jQuery.ready();
945}
946
947return jQuery;
948
949})();
950
951
952var // Promise methods
953 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
954 // Static reference to slice
955 sliceDeferred = [].slice;
956
957jQuery.extend({
958 // Create a simple deferred (one callbacks list)
959 _Deferred: function() {
960 var // callbacks list
961 callbacks = [],
962 // stored [ context , args ]
963 fired,
964 // to avoid firing when already doing so
965 firing,
966 // flag to know if the deferred has been cancelled
967 cancelled,
968 // the deferred itself
969 deferred = {
970
971 // done( f1, f2, ...)
972 done: function() {
973 if ( !cancelled ) {
974 var args = arguments,
975 i,
976 length,
977 elem,
978 type,
979 _fired;
980 if ( fired ) {
981 _fired = fired;
982 fired = 0;
983 }
984 for ( i = 0, length = args.length; i < length; i++ ) {
985 elem = args[ i ];
986 type = jQuery.type( elem );
987 if ( type === "array" ) {
988 deferred.done.apply( deferred, elem );
989 } else if ( type === "function" ) {
990 callbacks.push( elem );
991 }
992 }
993 if ( _fired ) {
994 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
995 }
996 }
997 return this;
998 },
999
1000 // resolve with given context and args
1001 resolveWith: function( context, args ) {
1002 if ( !cancelled && !fired && !firing ) {
1003 // make sure args are available (#8421)
1004 args = args || [];
1005 firing = 1;
1006 try {
1007 while( callbacks[ 0 ] ) {
1008 callbacks.shift().apply( context, args );
1009 }
1010 }
1011 finally {
1012 fired = [ context, args ];
1013 firing = 0;
1014 }
1015 }
1016 return this;
1017 },
1018
1019 // resolve with this as context and given arguments
1020 resolve: function() {
1021 deferred.resolveWith( this, arguments );
1022 return this;
1023 },
1024
1025 // Has this deferred been resolved?
1026 isResolved: function() {
1027 return !!( firing || fired );
1028 },
1029
1030 // Cancel
1031 cancel: function() {
1032 cancelled = 1;
1033 callbacks = [];
1034 return this;
1035 }
1036 };
1037
1038 return deferred;
1039 },
1040
1041 // Full fledged deferred (two callbacks list)
1042 Deferred: function( func ) {
1043 var deferred = jQuery._Deferred(),
1044 failDeferred = jQuery._Deferred(),
1045 promise;
1046 // Add errorDeferred methods, then and promise
1047 jQuery.extend( deferred, {
1048 then: function( doneCallbacks, failCallbacks ) {
1049 deferred.done( doneCallbacks ).fail( failCallbacks );
1050 return this;
1051 },
1052 always: function() {
1053 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1054 },
1055 fail: failDeferred.done,
1056 rejectWith: failDeferred.resolveWith,
1057 reject: failDeferred.resolve,
1058 isRejected: failDeferred.isResolved,
1059 pipe: function( fnDone, fnFail ) {
1060 return jQuery.Deferred(function( newDefer ) {
1061 jQuery.each( {
1062 done: [ fnDone, "resolve" ],
1063 fail: [ fnFail, "reject" ]
1064 }, function( handler, data ) {
1065 var fn = data[ 0 ],
1066 action = data[ 1 ],
1067 returned;
1068 if ( jQuery.isFunction( fn ) ) {
1069 deferred[ handler ](function() {
1070 returned = fn.apply( this, arguments );
1071 if ( returned && jQuery.isFunction( returned.promise ) ) {
1072 returned.promise().then( newDefer.resolve, newDefer.reject );
1073 } else {
1074 newDefer[ action ]( returned );
1075 }
1076 });
1077 } else {
1078 deferred[ handler ]( newDefer[ action ] );
1079 }
1080 });
1081 }).promise();
1082 },
1083 // Get a promise for this deferred
1084 // If obj is provided, the promise aspect is added to the object
1085 promise: function( obj ) {
1086 if ( obj == null ) {
1087 if ( promise ) {
1088 return promise;
1089 }
1090 promise = obj = {};
1091 }
1092 var i = promiseMethods.length;
1093 while( i-- ) {
1094 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1095 }
1096 return obj;
1097 }
1098 });
1099 // Make sure only one callback list will be used
1100 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1101 // Unexpose cancel
1102 delete deferred.cancel;
1103 // Call given func if any
1104 if ( func ) {
1105 func.call( deferred, deferred );
1106 }
1107 return deferred;
1108 },
1109
1110 // Deferred helper
1111 when: function( firstParam ) {
1112 var args = arguments,
1113 i = 0,
1114 length = args.length,
1115 count = length,
1116 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1117 firstParam :
1118 jQuery.Deferred();
1119 function resolveFunc( i ) {
1120 return function( value ) {
1121 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1122 if ( !( --count ) ) {
1123 // Strange bug in FF4:
1124 // Values changed onto the arguments object sometimes end up as undefined values
1125 // outside the $.when method. Cloning the object into a fresh array solves the issue
1126 deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1127 }
1128 };
1129 }
1130 if ( length > 1 ) {
1131 for( ; i < length; i++ ) {
1132 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1133 args[ i ].promise().then( resolveFunc(i), deferred.reject );
1134 } else {
1135 --count;
1136 }
1137 }
1138 if ( !count ) {
1139 deferred.resolveWith( deferred, args );
1140 }
1141 } else if ( deferred !== firstParam ) {
1142 deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1143 }
1144 return deferred.promise();
1145 }
1146});
1147
1148
1149
1150jQuery.support = (function() {
1151
1152 var div = document.createElement( "div" ),
1153 documentElement = document.documentElement,
1154 all,
1155 a,
1156 select,
1157 opt,
1158 input,
1159 marginDiv,
1160 support,
1161 fragment,
1162 body,
1163 testElementParent,
1164 testElement,
1165 testElementStyle,
1166 tds,
1167 events,
1168 eventName,
1169 i,
1170 isSupported;
1171
1172 // Preliminary tests
1173 div.setAttribute("className", "t");
1174 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1175
1176 all = div.getElementsByTagName( "*" );
1177 a = div.getElementsByTagName( "a" )[ 0 ];
1178
1179 // Can't get basic test support
1180 if ( !all || !all.length || !a ) {
1181 return {};
1182 }
1183
1184 // First batch of supports tests
1185 select = document.createElement( "select" );
1186 opt = select.appendChild( document.createElement("option") );
1187 input = div.getElementsByTagName( "input" )[ 0 ];
1188
1189 support = {
1190 // IE strips leading whitespace when .innerHTML is used
1191 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1192
1193 // Make sure that tbody elements aren't automatically inserted
1194 // IE will insert them into empty tables
1195 tbody: !div.getElementsByTagName( "tbody" ).length,
1196
1197 // Make sure that link elements get serialized correctly by innerHTML
1198 // This requires a wrapper element in IE
1199 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1200
1201 // Get the style information from getAttribute
1202 // (IE uses .cssText instead)
1203 style: /top/.test( a.getAttribute("style") ),
1204
1205 // Make sure that URLs aren't manipulated
1206 // (IE normalizes it by default)
1207 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1208
1209 // Make sure that element opacity exists
1210 // (IE uses filter instead)
1211 // Use a regex to work around a WebKit issue. See #5145
1212 opacity: /^0.55$/.test( a.style.opacity ),
1213
1214 // Verify style float existence
1215 // (IE uses styleFloat instead of cssFloat)
1216 cssFloat: !!a.style.cssFloat,
1217
1218 // Make sure that if no value is specified for a checkbox
1219 // that it defaults to "on".
1220 // (WebKit defaults to "" instead)
1221 checkOn: ( input.value === "on" ),
1222
1223 // Make sure that a selected-by-default option has a working selected property.
1224 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1225 optSelected: opt.selected,
1226
1227 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1228 getSetAttribute: div.className !== "t",
1229
1230 // Will be defined later
1231 submitBubbles: true,
1232 changeBubbles: true,
1233 focusinBubbles: false,
1234 deleteExpando: true,
1235 noCloneEvent: true,
1236 inlineBlockNeedsLayout: false,
1237 shrinkWrapBlocks: false,
1238 reliableMarginRight: true
1239 };
1240
1241 // Make sure checked status is properly cloned
1242 input.checked = true;
1243 support.noCloneChecked = input.cloneNode( true ).checked;
1244
1245 // Make sure that the options inside disabled selects aren't marked as disabled
1246 // (WebKit marks them as disabled)
1247 select.disabled = true;
1248 support.optDisabled = !opt.disabled;
1249
1250 // Test to see if it's possible to delete an expando from an element
1251 // Fails in Internet Explorer
1252 try {
1253 delete div.test;
1254 } catch( e ) {
1255 support.deleteExpando = false;
1256 }
1257
1258 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1259 div.attachEvent( "onclick", function() {
1260 // Cloning a node shouldn't copy over any
1261 // bound event handlers (IE does this)
1262 support.noCloneEvent = false;
1263 });
1264 div.cloneNode( true ).fireEvent( "onclick" );
1265 }
1266
1267 // Check if a radio maintains it's value
1268 // after being appended to the DOM
1269 input = document.createElement("input");
1270 input.value = "t";
1271 input.setAttribute("type", "radio");
1272 support.radioValue = input.value === "t";
1273
1274 input.setAttribute("checked", "checked");
1275 div.appendChild( input );
1276 fragment = document.createDocumentFragment();
1277 fragment.appendChild( div.firstChild );
1278
1279 // WebKit doesn't clone checked state correctly in fragments
1280 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1281
1282 div.innerHTML = "";
1283
1284 // Figure out if the W3C box model works as expected
1285 div.style.width = div.style.paddingLeft = "1px";
1286
1287 body = document.getElementsByTagName( "body" )[ 0 ];
1288 // We use our own, invisible, body unless the body is already present
1289 // in which case we use a div (#9239)
1290 testElement = document.createElement( body ? "div" : "body" );
1291 testElementStyle = {
1292 visibility: "hidden",
1293 width: 0,
1294 height: 0,
1295 border: 0,
1296 margin: 0
1297 };
1298 if ( body ) {
1299 jQuery.extend( testElementStyle, {
1300 position: "absolute",
1301 left: -1000,
1302 top: -1000
1303 });
1304 }
1305 for ( i in testElementStyle ) {
1306 testElement.style[ i ] = testElementStyle[ i ];
1307 }
1308 testElement.appendChild( div );
1309 testElementParent = body || documentElement;
1310 testElementParent.insertBefore( testElement, testElementParent.firstChild );
1311
1312 // Check if a disconnected checkbox will retain its checked
1313 // value of true after appended to the DOM (IE6/7)
1314 support.appendChecked = input.checked;
1315
1316 support.boxModel = div.offsetWidth === 2;
1317
1318 if ( "zoom" in div.style ) {
1319 // Check if natively block-level elements act like inline-block
1320 // elements when setting their display to 'inline' and giving
1321 // them layout
1322 // (IE < 8 does this)
1323 div.style.display = "inline";
1324 div.style.zoom = 1;
1325 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1326
1327 // Check if elements with layout shrink-wrap their children
1328 // (IE 6 does this)
1329 div.style.display = "";
1330 div.innerHTML = "<div style='width:4px;'></div>";
1331 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1332 }
1333
1334 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1335 tds = div.getElementsByTagName( "td" );
1336
1337 // Check if table cells still have offsetWidth/Height when they are set
1338 // to display:none and there are still other visible table cells in a
1339 // table row; if so, offsetWidth/Height are not reliable for use when
1340 // determining if an element has been hidden directly using
1341 // display:none (it is still safe to use offsets if a parent element is
1342 // hidden; don safety goggles and see bug #4512 for more information).
1343 // (only IE 8 fails this test)
1344 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1345
1346 tds[ 0 ].style.display = "";
1347 tds[ 1 ].style.display = "none";
1348
1349 // Check if empty table cells still have offsetWidth/Height
1350 // (IE < 8 fail this test)
1351 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1352 div.innerHTML = "";
1353
1354 // Check if div with explicit width and no margin-right incorrectly
1355 // gets computed margin-right based on width of container. For more
1356 // info see bug #3333
1357 // Fails in WebKit before Feb 2011 nightlies
1358 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1359 if ( document.defaultView && document.defaultView.getComputedStyle ) {
1360 marginDiv = document.createElement( "div" );
1361 marginDiv.style.width = "0";
1362 marginDiv.style.marginRight = "0";
1363 div.appendChild( marginDiv );
1364 support.reliableMarginRight =
1365 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1366 }
1367
1368 // Remove the body element we added
1369 testElement.innerHTML = "";
1370 testElementParent.removeChild( testElement );
1371
1372 // Technique from Juriy Zaytsev
1373 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1374 // We only care about the case where non-standard event systems
1375 // are used, namely in IE. Short-circuiting here helps us to
1376 // avoid an eval call (in setAttribute) which can cause CSP
1377 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1378 if ( div.attachEvent ) {
1379 for( i in {
1380 submit: 1,
1381 change: 1,
1382 focusin: 1
1383 } ) {
1384 eventName = "on" + i;
1385 isSupported = ( eventName in div );
1386 if ( !isSupported ) {
1387 div.setAttribute( eventName, "return;" );
1388 isSupported = ( typeof div[ eventName ] === "function" );
1389 }
1390 support[ i + "Bubbles" ] = isSupported;
1391 }
1392 }
1393
1394 // Null connected elements to avoid leaks in IE
1395 testElement = fragment = select = opt = body = marginDiv = div = input = null;
1396
1397 return support;
1398})();
1399
1400// Keep track of boxModel
1401jQuery.boxModel = jQuery.support.boxModel;
1402
1403
1404
1405
1406var rbrace = /^(?:\{.*\}|\[.*\])$/,
1407 rmultiDash = /([a-z])([A-Z])/g;
12701408
1271jQuery.extend({1409jQuery.extend({
1272 cache: {},1410 cache: {},
12731411
1274 data: function( elem, name, data ) {1412 // Please use with caution
1275 elem = elem == window ?1413 uuid: 0,
1276 windowData :1414
1277 elem;1415 // Unique for each copy of jQuery on the page
12781416 // Non-digits removed to match rinlinejQuery
1279 var id = elem[ expando ];1417 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
12801418
1281 // Compute a unique ID for the element1419 // The following elements throw uncatchable exceptions if you
1282 if ( !id )1420 // attempt to add expando properties to them.
1283 id = elem[ expando ] = ++uuid;1421 noData: {
12841422 "embed": true,
1285 // Only generate the data cache if we're1423 // Ban all objects except for Flash (which handle expandos)
1286 // trying to access or manipulate it1424 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1287 if ( name && !jQuery.cache[ id ] )1425 "applet": true
1288 jQuery.cache[ id ] = {};1426 },
12891427
1290 // Prevent overriding the named cache with undefined values1428 hasData: function( elem ) {
1291 if ( data !== undefined )1429 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1292 jQuery.cache[ id ][ name ] = data;1430
12931431 return !!elem && !isEmptyDataObject( elem );
1294 // Return the named cache data, or the ID for the element1432 },
1295 return name ?1433
1296 jQuery.cache[ id ][ name ] :1434 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1297 id;1435 if ( !jQuery.acceptData( elem ) ) {
1298 },1436 return;
12991437 }
1300 removeData: function( elem, name ) {1438
1301 elem = elem == window ?1439 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1302 windowData :1440
1303 elem;1441 // We have to handle DOM nodes and JS objects differently because IE6-7
13041442 // can't GC object references properly across the DOM-JS boundary
1305 var id = elem[ expando ];1443 isNode = elem.nodeType,
13061444
1307 // If we want to remove a specific section of the element's data1445 // Only DOM nodes need the global jQuery cache; JS object data is
1446 // attached directly to the object so GC can occur automatically
1447 cache = isNode ? jQuery.cache : elem,
1448
1449 // Only defining an ID for JS objects if its cache already exists allows
1450 // the code to shortcut on the same path as a DOM node with no cache
1451 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1452
1453 // Avoid doing any more work than we need to when trying to get data on an
1454 // object that has no data at all
1455 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1456 return;
1457 }
1458
1459 if ( !id ) {
1460 // Only DOM nodes need a new unique ID for each element since their data
1461 // ends up in the global cache
1462 if ( isNode ) {
1463 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1464 } else {
1465 id = jQuery.expando;
1466 }
1467 }
1468
1469 if ( !cache[ id ] ) {
1470 cache[ id ] = {};
1471
1472 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1473 // metadata on plain JS objects when the object is serialized using
1474 // JSON.stringify
1475 if ( !isNode ) {
1476 cache[ id ].toJSON = jQuery.noop;
1477 }
1478 }
1479
1480 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1481 // shallow copied over onto the existing cache
1482 if ( typeof name === "object" || typeof name === "function" ) {
1483 if ( pvt ) {
1484 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1485 } else {
1486 cache[ id ] = jQuery.extend(cache[ id ], name);
1487 }
1488 }
1489
1490 thisCache = cache[ id ];
1491
1492 // Internal jQuery data is stored in a separate object inside the object's data
1493 // cache in order to avoid key collisions between internal data and user-defined
1494 // data
1495 if ( pvt ) {
1496 if ( !thisCache[ internalKey ] ) {
1497 thisCache[ internalKey ] = {};
1498 }
1499
1500 thisCache = thisCache[ internalKey ];
1501 }
1502
1503 if ( data !== undefined ) {
1504 thisCache[ jQuery.camelCase( name ) ] = data;
1505 }
1506
1507 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1508 // not attempt to inspect the internal events object using jQuery.data, as this
1509 // internal data object is undocumented and subject to change.
1510 if ( name === "events" && !thisCache[name] ) {
1511 return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1512 }
1513
1514 return getByName ?
1515 // Check for both converted-to-camel and non-converted data property names
1516 thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] :
1517 thisCache;
1518 },
1519
1520 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1521 if ( !jQuery.acceptData( elem ) ) {
1522 return;
1523 }
1524
1525 var internalKey = jQuery.expando, isNode = elem.nodeType,
1526
1527 // See jQuery.data for more information
1528 cache = isNode ? jQuery.cache : elem,
1529
1530 // See jQuery.data for more information
1531 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1532
1533 // If there is already no cache entry for this object, there is no
1534 // purpose in continuing
1535 if ( !cache[ id ] ) {
1536 return;
1537 }
1538
1308 if ( name ) {1539 if ( name ) {
1309 if ( jQuery.cache[ id ] ) {1540 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1310 // Remove the section of cache data1541
1311 delete jQuery.cache[ id ][ name ];1542 if ( thisCache ) {
13121543 delete thisCache[ name ];
1313 // If we've removed all the data, remove the element's cache1544
1314 name = "";1545 // If there is no data left in the cache, we want to continue
13151546 // and let the cache object itself get destroyed
1316 for ( name in jQuery.cache[ id ] )1547 if ( !isEmptyDataObject(thisCache) ) {
1317 break;1548 return;
13181549 }
1319 if ( !name )1550 }
1320 jQuery.removeData( elem );1551 }
1321 }1552
13221553 // See jQuery.data for more information
1323 // Otherwise, we want to remove all of the element's data1554 if ( pvt ) {
1555 delete cache[ id ][ internalKey ];
1556
1557 // Don't destroy the parent cache unless the internal data object
1558 // had been the only thing left in it
1559 if ( !isEmptyDataObject(cache[ id ]) ) {
1560 return;
1561 }
1562 }
1563
1564 var internalCache = cache[ id ][ internalKey ];
1565
1566 // Browsers that fail expando deletion also refuse to delete expandos on
1567 // the window, but it will allow it on all other JS objects; other browsers
1568 // don't care
1569 if ( jQuery.support.deleteExpando || cache != window ) {
1570 delete cache[ id ];
1324 } else {1571 } else {
1325 // Clean up the element expando1572 cache[ id ] = null;
1326 try {1573 }
1327 delete elem[ expando ];1574
1328 } catch(e){1575 // We destroyed the entire user cache at once because it's faster than
1329 // IE has trouble directly removing the expando1576 // iterating through each key, but we need to continue to persist internal
1330 // but it's ok with using removeAttribute1577 // data if it existed
1331 if ( elem.removeAttribute )1578 if ( internalCache ) {
1332 elem.removeAttribute( expando );1579 cache[ id ] = {};
1333 }1580 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
13341581 // metadata on plain JS objects when the object is serialized using
1335 // Completely remove the data cache1582 // JSON.stringify
1336 delete jQuery.cache[ id ];1583 if ( !isNode ) {
1337 }1584 cache[ id ].toJSON = jQuery.noop;
1338 },1585 }
1339 queue: function( elem, type, data ) {1586
1340 if ( elem ){1587 cache[ id ][ internalKey ] = internalCache;
1341 1588
1342 type = (type || "fx") + "queue";1589 // Otherwise, we need to eliminate the expando on the node to avoid
1343 1590 // false lookups in the cache for entries that no longer exist
1344 var q = jQuery.data( elem, type );1591 } else if ( isNode ) {
1345 1592 // IE does not allow us to delete expando properties from nodes,
1346 if ( !q || jQuery.isArray(data) )1593 // nor does it have a removeAttribute function on Document nodes;
1347 q = jQuery.data( elem, type, jQuery.makeArray(data) );1594 // we must handle all of these cases
1348 else if( data )1595 if ( jQuery.support.deleteExpando ) {
1349 q.push( data );1596 delete elem[ jQuery.expando ];
1350 1597 } else if ( elem.removeAttribute ) {
1351 }1598 elem.removeAttribute( jQuery.expando );
1352 return q;1599 } else {
1353 },1600 elem[ jQuery.expando ] = null;
13541601 }
1355 dequeue: function( elem, type ){1602 }
1356 var queue = jQuery.queue( elem, type ),1603 },
1357 fn = queue.shift();1604
1358 1605 // For internal use only.
1359 if( !type || type === "fx" )1606 _data: function( elem, name, data ) {
1360 fn = queue[0];1607 return jQuery.data( elem, name, data, true );
1361 1608 },
1362 if( fn !== undefined )1609
1363 fn.call(elem);1610 // A method for determining if a DOM node can handle the data expando
1611 acceptData: function( elem ) {
1612 if ( elem.nodeName ) {
1613 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1614
1615 if ( match ) {
1616 return !(match === true || elem.getAttribute("classid") !== match);
1617 }
1618 }
1619
1620 return true;
1364 }1621 }
1365});1622});
13661623
1367jQuery.fn.extend({1624jQuery.fn.extend({
1368 data: function( key, value ){1625 data: function( key, value ) {
1626 var data = null;
1627
1628 if ( typeof key === "undefined" ) {
1629 if ( this.length ) {
1630 data = jQuery.data( this[0] );
1631
1632 if ( this[0].nodeType === 1 ) {
1633 var attr = this[0].attributes, name;
1634 for ( var i = 0, l = attr.length; i < l; i++ ) {
1635 name = attr[i].name;
1636
1637 if ( name.indexOf( "data-" ) === 0 ) {
1638 name = jQuery.camelCase( name.substring(5) );
1639
1640 dataAttr( this[0], name, data[ name ] );
1641 }
1642 }
1643 }
1644 }
1645
1646 return data;
1647
1648 } else if ( typeof key === "object" ) {
1649 return this.each(function() {
1650 jQuery.data( this, key );
1651 });
1652 }
1653
1369 var parts = key.split(".");1654 var parts = key.split(".");
1370 parts[1] = parts[1] ? "." + parts[1] : "";1655 parts[1] = parts[1] ? "." + parts[1] : "";
13711656
1372 if ( value === undefined ) {1657 if ( value === undefined ) {
1373 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);1658 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
13741659
1375 if ( data === undefined && this.length )1660 // Try to fetch any internally stored data first
1661 if ( data === undefined && this.length ) {
1376 data = jQuery.data( this[0], key );1662 data = jQuery.data( this[0], key );
1663 data = dataAttr( this[0], key, data );
1664 }
13771665
1378 return data === undefined && parts[1] ?1666 return data === undefined && parts[1] ?
1379 this.data( parts[0] ) :1667 this.data( parts[0] ) :
1380 data;1668 data;
1381 } else1669
1382 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){1670 } else {
1671 return this.each(function() {
1672 var $this = jQuery( this ),
1673 args = [ parts[0], value ];
1674
1675 $this.triggerHandler( "setData" + parts[1] + "!", args );
1383 jQuery.data( this, key, value );1676 jQuery.data( this, key, value );
1677 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1384 });1678 });
1679 }
1385 },1680 },
13861681
1387 removeData: function( key ){1682 removeData: function( key ) {
1388 return this.each(function(){1683 return this.each(function() {
1389 jQuery.removeData( this, key );1684 jQuery.removeData( this, key );
1390 });1685 });
1391 },1686 }
1392 queue: function(type, data){1687});
1688
1689function dataAttr( elem, key, data ) {
1690 // If nothing was found internally, try to fetch any
1691 // data from the HTML5 data-* attribute
1692 if ( data === undefined && elem.nodeType === 1 ) {
1693 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1694
1695 data = elem.getAttribute( name );
1696
1697 if ( typeof data === "string" ) {
1698 try {
1699 data = data === "true" ? true :
1700 data === "false" ? false :
1701 data === "null" ? null :
1702 !jQuery.isNaN( data ) ? parseFloat( data ) :
1703 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1704 data;
1705 } catch( e ) {}
1706
1707 // Make sure we set the data so it isn't changed later
1708 jQuery.data( elem, key, data );
1709
1710 } else {
1711 data = undefined;
1712 }
1713 }
1714
1715 return data;
1716}
1717
1718// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1719// property to be considered empty objects; this property always exists in
1720// order to make sure JSON.stringify does not expose internal metadata
1721function isEmptyDataObject( obj ) {
1722 for ( var name in obj ) {
1723 if ( name !== "toJSON" ) {
1724 return false;
1725 }
1726 }
1727
1728 return true;
1729}
1730
1731
1732
1733
1734function handleQueueMarkDefer( elem, type, src ) {
1735 var deferDataKey = type + "defer",
1736 queueDataKey = type + "queue",
1737 markDataKey = type + "mark",
1738 defer = jQuery.data( elem, deferDataKey, undefined, true );
1739 if ( defer &&
1740 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1741 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1742 // Give room for hard-coded callbacks to fire first
1743 // and eventually mark/queue something else on the element
1744 setTimeout( function() {
1745 if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1746 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1747 jQuery.removeData( elem, deferDataKey, true );
1748 defer.resolve();
1749 }
1750 }, 0 );
1751 }
1752}
1753
1754jQuery.extend({
1755
1756 _mark: function( elem, type ) {
1757 if ( elem ) {
1758 type = (type || "fx") + "mark";
1759 jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1760 }
1761 },
1762
1763 _unmark: function( force, elem, type ) {
1764 if ( force !== true ) {
1765 type = elem;
1766 elem = force;
1767 force = false;
1768 }
1769 if ( elem ) {
1770 type = type || "fx";
1771 var key = type + "mark",
1772 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1773 if ( count ) {
1774 jQuery.data( elem, key, count, true );
1775 } else {
1776 jQuery.removeData( elem, key, true );
1777 handleQueueMarkDefer( elem, type, "mark" );
1778 }
1779 }
1780 },
1781
1782 queue: function( elem, type, data ) {
1783 if ( elem ) {
1784 type = (type || "fx") + "queue";
1785 var q = jQuery.data( elem, type, undefined, true );
1786 // Speed up dequeue by getting out quickly if this is just a lookup
1787 if ( data ) {
1788 if ( !q || jQuery.isArray(data) ) {
1789 q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1790 } else {
1791 q.push( data );
1792 }
1793 }
1794 return q || [];
1795 }
1796 },
1797
1798 dequeue: function( elem, type ) {
1799 type = type || "fx";
1800
1801 var queue = jQuery.queue( elem, type ),
1802 fn = queue.shift(),
1803 defer;
1804
1805 // If the fx queue is dequeued, always remove the progress sentinel
1806 if ( fn === "inprogress" ) {
1807 fn = queue.shift();
1808 }
1809
1810 if ( fn ) {
1811 // Add a progress sentinel to prevent the fx queue from being
1812 // automatically dequeued
1813 if ( type === "fx" ) {
1814 queue.unshift("inprogress");
1815 }
1816
1817 fn.call(elem, function() {
1818 jQuery.dequeue(elem, type);
1819 });
1820 }
1821
1822 if ( !queue.length ) {
1823 jQuery.removeData( elem, type + "queue", true );
1824 handleQueueMarkDefer( elem, type, "queue" );
1825 }
1826 }
1827});
1828
1829jQuery.fn.extend({
1830 queue: function( type, data ) {
1393 if ( typeof type !== "string" ) {1831 if ( typeof type !== "string" ) {
1394 data = type;1832 data = type;
1395 type = "fx";1833 type = "fx";
1396 }1834 }
13971835
1398 if ( data === undefined )1836 if ( data === undefined ) {
1399 return jQuery.queue( this[0], type );1837 return jQuery.queue( this[0], type );
14001838 }
1401 return this.each(function(){1839 return this.each(function() {
1402 var queue = jQuery.queue( this, type, data );1840 var queue = jQuery.queue( this, type, data );
1403 1841
1404 if( type == "fx" && queue.length == 1 )1842 if ( type === "fx" && queue[0] !== "inprogress" ) {
1405 queue[0].call(this);1843 jQuery.dequeue( this, type );
1844 }
1406 });1845 });
1407 },1846 },
1408 dequeue: function(type){1847 dequeue: function( type ) {
1409 return this.each(function(){1848 return this.each(function() {
1410 jQuery.dequeue( this, type );1849 jQuery.dequeue( this, type );
1411 });1850 });
1412 }1851 },
1413});/*!1852 // Based off of the plugin by Clint Helfers, with permission.
1414 * Sizzle CSS Selector Engine - v0.9.31853 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1415 * Copyright 2009, The Dojo Foundation1854 delay: function( time, type ) {
1855 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1856 type = type || "fx";
1857
1858 return this.queue( type, function() {
1859 var elem = this;
1860 setTimeout(function() {
1861 jQuery.dequeue( elem, type );
1862 }, time );
1863 });
1864 },
1865 clearQueue: function( type ) {
1866 return this.queue( type || "fx", [] );
1867 },
1868 // Get a promise resolved when queues of a certain type
1869 // are emptied (fx is the type by default)
1870 promise: function( type, object ) {
1871 if ( typeof type !== "string" ) {
1872 object = type;
1873 type = undefined;
1874 }
1875 type = type || "fx";
1876 var defer = jQuery.Deferred(),
1877 elements = this,
1878 i = elements.length,
1879 count = 1,
1880 deferDataKey = type + "defer",
1881 queueDataKey = type + "queue",
1882 markDataKey = type + "mark",
1883 tmp;
1884 function resolve() {
1885 if ( !( --count ) ) {
1886 defer.resolveWith( elements, [ elements ] );
1887 }
1888 }
1889 while( i-- ) {
1890 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1891 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1892 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1893 jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1894 count++;
1895 tmp.done( resolve );
1896 }
1897 }
1898 resolve();
1899 return defer.promise();
1900 }
1901});
1902
1903
1904
1905
1906var rclass = /[\n\t\r]/g,
1907 rspace = /\s+/,
1908 rreturn = /\r/g,
1909 rtype = /^(?:button|input)$/i,
1910 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1911 rclickable = /^a(?:rea)?$/i,
1912 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1913 rinvalidChar = /\:|^on/,
1914 formHook, boolHook;
1915
1916jQuery.fn.extend({
1917 attr: function( name, value ) {
1918 return jQuery.access( this, name, value, true, jQuery.attr );
1919 },
1920
1921 removeAttr: function( name ) {
1922 return this.each(function() {
1923 jQuery.removeAttr( this, name );
1924 });
1925 },
1926
1927 prop: function( name, value ) {
1928 return jQuery.access( this, name, value, true, jQuery.prop );
1929 },
1930
1931 removeProp: function( name ) {
1932 name = jQuery.propFix[ name ] || name;
1933 return this.each(function() {
1934 // try/catch handles cases where IE balks (such as removing a property on window)
1935 try {
1936 this[ name ] = undefined;
1937 delete this[ name ];
1938 } catch( e ) {}
1939 });
1940 },
1941
1942 addClass: function( value ) {
1943 var classNames, i, l, elem,
1944 setClass, c, cl;
1945
1946 if ( jQuery.isFunction( value ) ) {
1947 return this.each(function( j ) {
1948 jQuery( this ).addClass( value.call(this, j, this.className) );
1949 });
1950 }
1951
1952 if ( value && typeof value === "string" ) {
1953 classNames = value.split( rspace );
1954
1955 for ( i = 0, l = this.length; i < l; i++ ) {
1956 elem = this[ i ];
1957
1958 if ( elem.nodeType === 1 ) {
1959 if ( !elem.className && classNames.length === 1 ) {
1960 elem.className = value;
1961
1962 } else {
1963 setClass = " " + elem.className + " ";
1964
1965 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
1966 if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
1967 setClass += classNames[ c ] + " ";
1968 }
1969 }
1970 elem.className = jQuery.trim( setClass );
1971 }
1972 }
1973 }
1974 }
1975
1976 return this;
1977 },
1978
1979 removeClass: function( value ) {
1980 var classNames, i, l, elem, className, c, cl;
1981
1982 if ( jQuery.isFunction( value ) ) {
1983 return this.each(function( j ) {
1984 jQuery( this ).removeClass( value.call(this, j, this.className) );
1985 });
1986 }
1987
1988 if ( (value && typeof value === "string") || value === undefined ) {
1989 classNames = (value || "").split( rspace );
1990
1991 for ( i = 0, l = this.length; i < l; i++ ) {
1992 elem = this[ i ];
1993
1994 if ( elem.nodeType === 1 && elem.className ) {
1995 if ( value ) {
1996 className = (" " + elem.className + " ").replace( rclass, " " );
1997 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
1998 className = className.replace(" " + classNames[ c ] + " ", " ");
1999 }
2000 elem.className = jQuery.trim( className );
2001
2002 } else {
2003 elem.className = "";
2004 }
2005 }
2006 }
2007 }
2008
2009 return this;
2010 },
2011
2012 toggleClass: function( value, stateVal ) {
2013 var type = typeof value,
2014 isBool = typeof stateVal === "boolean";
2015
2016 if ( jQuery.isFunction( value ) ) {
2017 return this.each(function( i ) {
2018 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2019 });
2020 }
2021
2022 return this.each(function() {
2023 if ( type === "string" ) {
2024 // toggle individual class names
2025 var className,
2026 i = 0,
2027 self = jQuery( this ),
2028 state = stateVal,
2029 classNames = value.split( rspace );
2030
2031 while ( (className = classNames[ i++ ]) ) {
2032 // check each className given, space seperated list
2033 state = isBool ? state : !self.hasClass( className );
2034 self[ state ? "addClass" : "removeClass" ]( className );
2035 }
2036
2037 } else if ( type === "undefined" || type === "boolean" ) {
2038 if ( this.className ) {
2039 // store className if set
2040 jQuery._data( this, "__className__", this.className );
2041 }
2042
2043 // toggle whole className
2044 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2045 }
2046 });
2047 },
2048
2049 hasClass: function( selector ) {
2050 var className = " " + selector + " ";
2051 for ( var i = 0, l = this.length; i < l; i++ ) {
2052 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2053 return true;
2054 }
2055 }
2056
2057 return false;
2058 },
2059
2060 val: function( value ) {
2061 var hooks, ret,
2062 elem = this[0];
2063
2064 if ( !arguments.length ) {
2065 if ( elem ) {
2066 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2067
2068 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2069 return ret;
2070 }
2071
2072 ret = elem.value;
2073
2074 return typeof ret === "string" ?
2075 // handle most common string cases
2076 ret.replace(rreturn, "") :
2077 // handle cases where value is null/undef or number
2078 ret == null ? "" : ret;
2079 }
2080
2081 return undefined;
2082 }
2083
2084 var isFunction = jQuery.isFunction( value );
2085
2086 return this.each(function( i ) {
2087 var self = jQuery(this), val;
2088
2089 if ( this.nodeType !== 1 ) {
2090 return;
2091 }
2092
2093 if ( isFunction ) {
2094 val = value.call( this, i, self.val() );
2095 } else {
2096 val = value;
2097 }
2098
2099 // Treat null/undefined as ""; convert numbers to string
2100 if ( val == null ) {
2101 val = "";
2102 } else if ( typeof val === "number" ) {
2103 val += "";
2104 } else if ( jQuery.isArray( val ) ) {
2105 val = jQuery.map(val, function ( value ) {
2106 return value == null ? "" : value + "";
2107 });
2108 }
2109
2110 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2111
2112 // If set returns undefined, fall back to normal setting
2113 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2114 this.value = val;
2115 }
2116 });
2117 }
2118});
2119
2120jQuery.extend({
2121 valHooks: {
2122 option: {
2123 get: function( elem ) {
2124 // attributes.value is undefined in Blackberry 4.7 but
2125 // uses .value. See #6932
2126 var val = elem.attributes.value;
2127 return !val || val.specified ? elem.value : elem.text;
2128 }
2129 },
2130 select: {
2131 get: function( elem ) {
2132 var value,
2133 index = elem.selectedIndex,
2134 values = [],
2135 options = elem.options,
2136 one = elem.type === "select-one";
2137
2138 // Nothing was selected
2139 if ( index < 0 ) {
2140 return null;
2141 }
2142
2143 // Loop through all the selected options
2144 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2145 var option = options[ i ];
2146
2147 // Don't return options that are disabled or in a disabled optgroup
2148 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2149 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2150
2151 // Get the specific value for the option
2152 value = jQuery( option ).val();
2153
2154 // We don't need an array for one selects
2155 if ( one ) {
2156 return value;
2157 }
2158
2159 // Multi-Selects return an array
2160 values.push( value );
2161 }
2162 }
2163
2164 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2165 if ( one && !values.length && options.length ) {
2166 return jQuery( options[ index ] ).val();
2167 }
2168
2169 return values;
2170 },
2171
2172 set: function( elem, value ) {
2173 var values = jQuery.makeArray( value );
2174
2175 jQuery(elem).find("option").each(function() {
2176 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2177 });
2178
2179 if ( !values.length ) {
2180 elem.selectedIndex = -1;
2181 }
2182 return values;
2183 }
2184 }
2185 },
2186
2187 attrFn: {
2188 val: true,
2189 css: true,
2190 html: true,
2191 text: true,
2192 data: true,
2193 width: true,
2194 height: true,
2195 offset: true
2196 },
2197
2198 attrFix: {
2199 // Always normalize to ensure hook usage
2200 tabindex: "tabIndex"
2201 },
2202
2203 attr: function( elem, name, value, pass ) {
2204 var nType = elem.nodeType;
2205
2206 // don't get/set attributes on text, comment and attribute nodes
2207 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2208 return undefined;
2209 }
2210
2211 if ( pass && name in jQuery.attrFn ) {
2212 return jQuery( elem )[ name ]( value );
2213 }
2214
2215 // Fallback to prop when attributes are not supported
2216 if ( !("getAttribute" in elem) ) {
2217 return jQuery.prop( elem, name, value );
2218 }
2219
2220 var ret, hooks,
2221 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2222
2223 // Normalize the name if needed
2224 if ( notxml ) {
2225 name = jQuery.attrFix[ name ] || name;
2226
2227 hooks = jQuery.attrHooks[ name ];
2228
2229 if ( !hooks ) {
2230 // Use boolHook for boolean attributes
2231 if ( rboolean.test( name ) ) {
2232
2233 hooks = boolHook;
2234
2235 // Use formHook for forms and if the name contains certain characters
2236 } else if ( formHook && name !== "className" &&
2237 (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2238
2239 hooks = formHook;
2240 }
2241 }
2242 }
2243
2244 if ( value !== undefined ) {
2245
2246 if ( value === null ) {
2247 jQuery.removeAttr( elem, name );
2248 return undefined;
2249
2250 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2251 return ret;
2252
2253 } else {
2254 elem.setAttribute( name, "" + value );
2255 return value;
2256 }
2257
2258 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2259 return ret;
2260
2261 } else {
2262
2263 ret = elem.getAttribute( name );
2264
2265 // Non-existent attributes return null, we normalize to undefined
2266 return ret === null ?
2267 undefined :
2268 ret;
2269 }
2270 },
2271
2272 removeAttr: function( elem, name ) {
2273 var propName;
2274 if ( elem.nodeType === 1 ) {
2275 name = jQuery.attrFix[ name ] || name;
2276
2277 if ( jQuery.support.getSetAttribute ) {
2278 // Use removeAttribute in browsers that support it
2279 elem.removeAttribute( name );
2280 } else {
2281 jQuery.attr( elem, name, "" );
2282 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2283 }
2284
2285 // Set corresponding property to false for boolean attributes
2286 if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2287 elem[ propName ] = false;
2288 }
2289 }
2290 },
2291
2292 attrHooks: {
2293 type: {
2294 set: function( elem, value ) {
2295 // We can't allow the type property to be changed (since it causes problems in IE)
2296 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2297 jQuery.error( "type property can't be changed" );
2298 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2299 // Setting the type on a radio button after the value resets the value in IE6-9
2300 // Reset value to it's default in case type is set after value
2301 // This is for element creation
2302 var val = elem.value;
2303 elem.setAttribute( "type", value );
2304 if ( val ) {
2305 elem.value = val;
2306 }
2307 return value;
2308 }
2309 }
2310 },
2311 tabIndex: {
2312 get: function( elem ) {
2313 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2314 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2315 var attributeNode = elem.getAttributeNode("tabIndex");
2316
2317 return attributeNode && attributeNode.specified ?
2318 parseInt( attributeNode.value, 10 ) :
2319 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2320 0 :
2321 undefined;
2322 }
2323 },
2324 // Use the value property for back compat
2325 // Use the formHook for button elements in IE6/7 (#1954)
2326 value: {
2327 get: function( elem, name ) {
2328 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2329 return formHook.get( elem, name );
2330 }
2331 return name in elem ?
2332 elem.value :
2333 null;
2334 },
2335 set: function( elem, value, name ) {
2336 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2337 return formHook.set( elem, value, name );
2338 }
2339 // Does not return so that setAttribute is also used
2340 elem.value = value;
2341 }
2342 }
2343 },
2344
2345 propFix: {
2346 tabindex: "tabIndex",
2347 readonly: "readOnly",
2348 "for": "htmlFor",
2349 "class": "className",
2350 maxlength: "maxLength",
2351 cellspacing: "cellSpacing",
2352 cellpadding: "cellPadding",
2353 rowspan: "rowSpan",
2354 colspan: "colSpan",
2355 usemap: "useMap",
2356 frameborder: "frameBorder",
2357 contenteditable: "contentEditable"
2358 },
2359
2360 prop: function( elem, name, value ) {
2361 var nType = elem.nodeType;
2362
2363 // don't get/set properties on text, comment and attribute nodes
2364 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2365 return undefined;
2366 }
2367
2368 var ret, hooks,
2369 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2370
2371 if ( notxml ) {
2372 // Fix name and attach hooks
2373 name = jQuery.propFix[ name ] || name;
2374 hooks = jQuery.propHooks[ name ];
2375 }
2376
2377 if ( value !== undefined ) {
2378 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2379 return ret;
2380
2381 } else {
2382 return (elem[ name ] = value);
2383 }
2384
2385 } else {
2386 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2387 return ret;
2388
2389 } else {
2390 return elem[ name ];
2391 }
2392 }
2393 },
2394
2395 propHooks: {}
2396});
2397
2398// Hook for boolean attributes
2399boolHook = {
2400 get: function( elem, name ) {
2401 // Align boolean attributes with corresponding properties
2402 return jQuery.prop( elem, name ) ?
2403 name.toLowerCase() :
2404 undefined;
2405 },
2406 set: function( elem, value, name ) {
2407 var propName;
2408 if ( value === false ) {
2409 // Remove boolean attributes when set to false
2410 jQuery.removeAttr( elem, name );
2411 } else {
2412 // value is true since we know at this point it's type boolean and not false
2413 // Set boolean attributes to the same name and set the DOM property
2414 propName = jQuery.propFix[ name ] || name;
2415 if ( propName in elem ) {
2416 // Only set the IDL specifically if it already exists on the element
2417 elem[ propName ] = true;
2418 }
2419
2420 elem.setAttribute( name, name.toLowerCase() );
2421 }
2422 return name;
2423 }
2424};
2425
2426// IE6/7 do not support getting/setting some attributes with get/setAttribute
2427if ( !jQuery.support.getSetAttribute ) {
2428
2429 // propFix is more comprehensive and contains all fixes
2430 jQuery.attrFix = jQuery.propFix;
2431
2432 // Use this for any attribute on a form in IE6/7
2433 formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = {
2434 get: function( elem, name ) {
2435 var ret;
2436 ret = elem.getAttributeNode( name );
2437 // Return undefined if nodeValue is empty string
2438 return ret && ret.nodeValue !== "" ?
2439 ret.nodeValue :
2440 undefined;
2441 },
2442 set: function( elem, value, name ) {
2443 // Check form objects in IE (multiple bugs related)
2444 // Only use nodeValue if the attribute node exists on the form
2445 var ret = elem.getAttributeNode( name );
2446 if ( ret ) {
2447 ret.nodeValue = value;
2448 return value;
2449 }
2450 }
2451 };
2452
2453 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2454 // This is for removals
2455 jQuery.each([ "width", "height" ], function( i, name ) {
2456 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2457 set: function( elem, value ) {
2458 if ( value === "" ) {
2459 elem.setAttribute( name, "auto" );
2460 return value;
2461 }
2462 }
2463 });
2464 });
2465}
2466
2467
2468// Some attributes require a special call on IE
2469if ( !jQuery.support.hrefNormalized ) {
2470 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2471 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2472 get: function( elem ) {
2473 var ret = elem.getAttribute( name, 2 );
2474 return ret === null ? undefined : ret;
2475 }
2476 });
2477 });
2478}
2479
2480if ( !jQuery.support.style ) {
2481 jQuery.attrHooks.style = {
2482 get: function( elem ) {
2483 // Return undefined in the case of empty string
2484 // Normalize to lowercase since IE uppercases css property names
2485 return elem.style.cssText.toLowerCase() || undefined;
2486 },
2487 set: function( elem, value ) {
2488 return (elem.style.cssText = "" + value);
2489 }
2490 };
2491}
2492
2493// Safari mis-reports the default selected property of an option
2494// Accessing the parent's selectedIndex property fixes it
2495if ( !jQuery.support.optSelected ) {
2496 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2497 get: function( elem ) {
2498 var parent = elem.parentNode;
2499
2500 if ( parent ) {
2501 parent.selectedIndex;
2502
2503 // Make sure that it also works with optgroups, see #5701
2504 if ( parent.parentNode ) {
2505 parent.parentNode.selectedIndex;
2506 }
2507 }
2508 }
2509 });
2510}
2511
2512// Radios and checkboxes getter/setter
2513if ( !jQuery.support.checkOn ) {
2514 jQuery.each([ "radio", "checkbox" ], function() {
2515 jQuery.valHooks[ this ] = {
2516 get: function( elem ) {
2517 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2518 return elem.getAttribute("value") === null ? "on" : elem.value;
2519 }
2520 };
2521 });
2522}
2523jQuery.each([ "radio", "checkbox" ], function() {
2524 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2525 set: function( elem, value ) {
2526 if ( jQuery.isArray( value ) ) {
2527 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2528 }
2529 }
2530 });
2531});
2532
2533
2534
2535
2536var rnamespaces = /\.(.*)$/,
2537 rformElems = /^(?:textarea|input|select)$/i,
2538 rperiod = /\./g,
2539 rspaces = / /g,
2540 rescape = /[^\w\s.|`]/g,
2541 fcleanup = function( nm ) {
2542 return nm.replace(rescape, "\\$&");
2543 };
2544
2545/*
2546 * A number of helper functions used for managing events.
2547 * Many of the ideas behind this code originated from
2548 * Dean Edwards' addEvent library.
2549 */
2550jQuery.event = {
2551
2552 // Bind an event to an element
2553 // Original by Dean Edwards
2554 add: function( elem, types, handler, data ) {
2555 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2556 return;
2557 }
2558
2559 if ( handler === false ) {
2560 handler = returnFalse;
2561 } else if ( !handler ) {
2562 // Fixes bug #7229. Fix recommended by jdalton
2563 return;
2564 }
2565
2566 var handleObjIn, handleObj;
2567
2568 if ( handler.handler ) {
2569 handleObjIn = handler;
2570 handler = handleObjIn.handler;
2571 }
2572
2573 // Make sure that the function being executed has a unique ID
2574 if ( !handler.guid ) {
2575 handler.guid = jQuery.guid++;
2576 }
2577
2578 // Init the element's event structure
2579 var elemData = jQuery._data( elem );
2580
2581 // If no elemData is found then we must be trying to bind to one of the
2582 // banned noData elements
2583 if ( !elemData ) {
2584 return;
2585 }
2586
2587 var events = elemData.events,
2588 eventHandle = elemData.handle;
2589
2590 if ( !events ) {
2591 elemData.events = events = {};
2592 }
2593
2594 if ( !eventHandle ) {
2595 elemData.handle = eventHandle = function( e ) {
2596 // Discard the second event of a jQuery.event.trigger() and
2597 // when an event is called after a page has unloaded
2598 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2599 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2600 undefined;
2601 };
2602 }
2603
2604 // Add elem as a property of the handle function
2605 // This is to prevent a memory leak with non-native events in IE.
2606 eventHandle.elem = elem;
2607
2608 // Handle multiple events separated by a space
2609 // jQuery(...).bind("mouseover mouseout", fn);
2610 types = types.split(" ");
2611
2612 var type, i = 0, namespaces;
2613
2614 while ( (type = types[ i++ ]) ) {
2615 handleObj = handleObjIn ?
2616 jQuery.extend({}, handleObjIn) :
2617 { handler: handler, data: data };
2618
2619 // Namespaced event handlers
2620 if ( type.indexOf(".") > -1 ) {
2621 namespaces = type.split(".");
2622 type = namespaces.shift();
2623 handleObj.namespace = namespaces.slice(0).sort().join(".");
2624
2625 } else {
2626 namespaces = [];
2627 handleObj.namespace = "";
2628 }
2629
2630 handleObj.type = type;
2631 if ( !handleObj.guid ) {
2632 handleObj.guid = handler.guid;
2633 }
2634
2635 // Get the current list of functions bound to this event
2636 var handlers = events[ type ],
2637 special = jQuery.event.special[ type ] || {};
2638
2639 // Init the event handler queue
2640 if ( !handlers ) {
2641 handlers = events[ type ] = [];
2642
2643 // Check for a special event handler
2644 // Only use addEventListener/attachEvent if the special
2645 // events handler returns false
2646 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2647 // Bind the global event handler to the element
2648 if ( elem.addEventListener ) {
2649 elem.addEventListener( type, eventHandle, false );
2650
2651 } else if ( elem.attachEvent ) {
2652 elem.attachEvent( "on" + type, eventHandle );
2653 }
2654 }
2655 }
2656
2657 if ( special.add ) {
2658 special.add.call( elem, handleObj );
2659
2660 if ( !handleObj.handler.guid ) {
2661 handleObj.handler.guid = handler.guid;
2662 }
2663 }
2664
2665 // Add the function to the element's handler list
2666 handlers.push( handleObj );
2667
2668 // Keep track of which events have been used, for event optimization
2669 jQuery.event.global[ type ] = true;
2670 }
2671
2672 // Nullify elem to prevent memory leaks in IE
2673 elem = null;
2674 },
2675
2676 global: {},
2677
2678 // Detach an event or set of events from an element
2679 remove: function( elem, types, handler, pos ) {
2680 // don't do events on text and comment nodes
2681 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2682 return;
2683 }
2684
2685 if ( handler === false ) {
2686 handler = returnFalse;
2687 }
2688
2689 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2690 elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2691 events = elemData && elemData.events;
2692
2693 if ( !elemData || !events ) {
2694 return;
2695 }
2696
2697 // types is actually an event object here
2698 if ( types && types.type ) {
2699 handler = types.handler;
2700 types = types.type;
2701 }
2702
2703 // Unbind all events for the element
2704 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2705 types = types || "";
2706
2707 for ( type in events ) {
2708 jQuery.event.remove( elem, type + types );
2709 }
2710
2711 return;
2712 }
2713
2714 // Handle multiple events separated by a space
2715 // jQuery(...).unbind("mouseover mouseout", fn);
2716 types = types.split(" ");
2717
2718 while ( (type = types[ i++ ]) ) {
2719 origType = type;
2720 handleObj = null;
2721 all = type.indexOf(".") < 0;
2722 namespaces = [];
2723
2724 if ( !all ) {
2725 // Namespaced event handlers
2726 namespaces = type.split(".");
2727 type = namespaces.shift();
2728
2729 namespace = new RegExp("(^|\\.)" +
2730 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2731 }
2732
2733 eventType = events[ type ];
2734
2735 if ( !eventType ) {
2736 continue;
2737 }
2738
2739 if ( !handler ) {
2740 for ( j = 0; j < eventType.length; j++ ) {
2741 handleObj = eventType[ j ];
2742
2743 if ( all || namespace.test( handleObj.namespace ) ) {
2744 jQuery.event.remove( elem, origType, handleObj.handler, j );
2745 eventType.splice( j--, 1 );
2746 }
2747 }
2748
2749 continue;
2750 }
2751
2752 special = jQuery.event.special[ type ] || {};
2753
2754 for ( j = pos || 0; j < eventType.length; j++ ) {
2755 handleObj = eventType[ j ];
2756
2757 if ( handler.guid === handleObj.guid ) {
2758 // remove the given handler for the given type
2759 if ( all || namespace.test( handleObj.namespace ) ) {
2760 if ( pos == null ) {
2761 eventType.splice( j--, 1 );
2762 }
2763
2764 if ( special.remove ) {
2765 special.remove.call( elem, handleObj );
2766 }
2767 }
2768
2769 if ( pos != null ) {
2770 break;
2771 }
2772 }
2773 }
2774
2775 // remove generic event handler if no more handlers exist
2776 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2777 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2778 jQuery.removeEvent( elem, type, elemData.handle );
2779 }
2780
2781 ret = null;
2782 delete events[ type ];
2783 }
2784 }
2785
2786 // Remove the expando if it's no longer used
2787 if ( jQuery.isEmptyObject( events ) ) {
2788 var handle = elemData.handle;
2789 if ( handle ) {
2790 handle.elem = null;
2791 }
2792
2793 delete elemData.events;
2794 delete elemData.handle;
2795
2796 if ( jQuery.isEmptyObject( elemData ) ) {
2797 jQuery.removeData( elem, undefined, true );
2798 }
2799 }
2800 },
2801
2802 // Events that are safe to short-circuit if no handlers are attached.
2803 // Native DOM events should not be added, they may have inline handlers.
2804 customEvent: {
2805 "getData": true,
2806 "setData": true,
2807 "changeData": true
2808 },
2809
2810 trigger: function( event, data, elem, onlyHandlers ) {
2811 // Event object or event type
2812 var type = event.type || event,
2813 namespaces = [],
2814 exclusive;
2815
2816 if ( type.indexOf("!") >= 0 ) {
2817 // Exclusive events trigger only for the exact event (no namespaces)
2818 type = type.slice(0, -1);
2819 exclusive = true;
2820 }
2821
2822 if ( type.indexOf(".") >= 0 ) {
2823 // Namespaced trigger; create a regexp to match event type in handle()
2824 namespaces = type.split(".");
2825 type = namespaces.shift();
2826 namespaces.sort();
2827 }
2828
2829 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2830 // No jQuery handlers for this event type, and it can't have inline handlers
2831 return;
2832 }
2833
2834 // Caller can pass in an Event, Object, or just an event type string
2835 event = typeof event === "object" ?
2836 // jQuery.Event object
2837 event[ jQuery.expando ] ? event :
2838 // Object literal
2839 new jQuery.Event( type, event ) :
2840 // Just the event type (string)
2841 new jQuery.Event( type );
2842
2843 event.type = type;
2844 event.exclusive = exclusive;
2845 event.namespace = namespaces.join(".");
2846 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2847
2848 // triggerHandler() and global events don't bubble or run the default action
2849 if ( onlyHandlers || !elem ) {
2850 event.preventDefault();
2851 event.stopPropagation();
2852 }
2853
2854 // Handle a global trigger
2855 if ( !elem ) {
2856 // TODO: Stop taunting the data cache; remove global events and always attach to document
2857 jQuery.each( jQuery.cache, function() {
2858 // internalKey variable is just used to make it easier to find
2859 // and potentially change this stuff later; currently it just
2860 // points to jQuery.expando
2861 var internalKey = jQuery.expando,
2862 internalCache = this[ internalKey ];
2863 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2864 jQuery.event.trigger( event, data, internalCache.handle.elem );
2865 }
2866 });
2867 return;
2868 }
2869
2870 // Don't do events on text and comment nodes
2871 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2872 return;
2873 }
2874
2875 // Clean up the event in case it is being reused
2876 event.result = undefined;
2877 event.target = elem;
2878
2879 // Clone any incoming data and prepend the event, creating the handler arg list
2880 data = data != null ? jQuery.makeArray( data ) : [];
2881 data.unshift( event );
2882
2883 var cur = elem,
2884 // IE doesn't like method names with a colon (#3533, #8272)
2885 ontype = type.indexOf(":") < 0 ? "on" + type : "";
2886
2887 // Fire event on the current element, then bubble up the DOM tree
2888 do {
2889 var handle = jQuery._data( cur, "handle" );
2890
2891 event.currentTarget = cur;
2892 if ( handle ) {
2893 handle.apply( cur, data );
2894 }
2895
2896 // Trigger an inline bound script
2897 if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2898 event.result = false;
2899 event.preventDefault();
2900 }
2901
2902 // Bubble up to document, then to window
2903 cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2904 } while ( cur && !event.isPropagationStopped() );
2905
2906 // If nobody prevented the default action, do it now
2907 if ( !event.isDefaultPrevented() ) {
2908 var old,
2909 special = jQuery.event.special[ type ] || {};
2910
2911 if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2912 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2913
2914 // Call a native DOM method on the target with the same name name as the event.
2915 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2916 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2917 try {
2918 if ( ontype && elem[ type ] ) {
2919 // Don't re-trigger an onFOO event when we call its FOO() method
2920 old = elem[ ontype ];
2921
2922 if ( old ) {
2923 elem[ ontype ] = null;
2924 }
2925
2926 jQuery.event.triggered = type;
2927 elem[ type ]();
2928 }
2929 } catch ( ieError ) {}
2930
2931 if ( old ) {
2932 elem[ ontype ] = old;
2933 }
2934
2935 jQuery.event.triggered = undefined;
2936 }
2937 }
2938
2939 return event.result;
2940 },
2941
2942 handle: function( event ) {
2943 event = jQuery.event.fix( event || window.event );
2944 // Snapshot the handlers list since a called handler may add/remove events.
2945 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2946 run_all = !event.exclusive && !event.namespace,
2947 args = Array.prototype.slice.call( arguments, 0 );
2948
2949 // Use the fix-ed Event rather than the (read-only) native event
2950 args[0] = event;
2951 event.currentTarget = this;
2952
2953 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2954 var handleObj = handlers[ j ];
2955
2956 // Triggered event must 1) be non-exclusive and have no namespace, or
2957 // 2) have namespace(s) a subset or equal to those in the bound event.
2958 if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2959 // Pass in a reference to the handler function itself
2960 // So that we can later remove it
2961 event.handler = handleObj.handler;
2962 event.data = handleObj.data;
2963 event.handleObj = handleObj;
2964
2965 var ret = handleObj.handler.apply( this, args );
2966
2967 if ( ret !== undefined ) {
2968 event.result = ret;
2969 if ( ret === false ) {
2970 event.preventDefault();
2971 event.stopPropagation();
2972 }
2973 }
2974
2975 if ( event.isImmediatePropagationStopped() ) {
2976 break;
2977 }
2978 }
2979 }
2980 return event.result;
2981 },
2982
2983 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2984
2985 fix: function( event ) {
2986 if ( event[ jQuery.expando ] ) {
2987 return event;
2988 }
2989
2990 // store a copy of the original event object
2991 // and "clone" to set read-only properties
2992 var originalEvent = event;
2993 event = jQuery.Event( originalEvent );
2994
2995 for ( var i = this.props.length, prop; i; ) {
2996 prop = this.props[ --i ];
2997 event[ prop ] = originalEvent[ prop ];
2998 }
2999
3000 // Fix target property, if necessary
3001 if ( !event.target ) {
3002 // Fixes #1925 where srcElement might not be defined either
3003 event.target = event.srcElement || document;
3004 }
3005
3006 // check if target is a textnode (safari)
3007 if ( event.target.nodeType === 3 ) {
3008 event.target = event.target.parentNode;
3009 }
3010
3011 // Add relatedTarget, if necessary
3012 if ( !event.relatedTarget && event.fromElement ) {
3013 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3014 }
3015
3016 // Calculate pageX/Y if missing and clientX/Y available
3017 if ( event.pageX == null && event.clientX != null ) {
3018 var eventDocument = event.target.ownerDocument || document,
3019 doc = eventDocument.documentElement,
3020 body = eventDocument.body;
3021
3022 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
3023 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
3024 }
3025
3026 // Add which for key events
3027 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3028 event.which = event.charCode != null ? event.charCode : event.keyCode;
3029 }
3030
3031 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3032 if ( !event.metaKey && event.ctrlKey ) {
3033 event.metaKey = event.ctrlKey;
3034 }
3035
3036 // Add which for click: 1 === left; 2 === middle; 3 === right
3037 // Note: button is not normalized, so don't use it
3038 if ( !event.which && event.button !== undefined ) {
3039 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3040 }
3041
3042 return event;
3043 },
3044
3045 // Deprecated, use jQuery.guid instead
3046 guid: 1E8,
3047
3048 // Deprecated, use jQuery.proxy instead
3049 proxy: jQuery.proxy,
3050
3051 special: {
3052 ready: {
3053 // Make sure the ready event is setup
3054 setup: jQuery.bindReady,
3055 teardown: jQuery.noop
3056 },
3057
3058 live: {
3059 add: function( handleObj ) {
3060 jQuery.event.add( this,
3061 liveConvert( handleObj.origType, handleObj.selector ),
3062 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3063 },
3064
3065 remove: function( handleObj ) {
3066 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3067 }
3068 },
3069
3070 beforeunload: {
3071 setup: function( data, namespaces, eventHandle ) {
3072 // We only want to do this special case on windows
3073 if ( jQuery.isWindow( this ) ) {
3074 this.onbeforeunload = eventHandle;
3075 }
3076 },
3077
3078 teardown: function( namespaces, eventHandle ) {
3079 if ( this.onbeforeunload === eventHandle ) {
3080 this.onbeforeunload = null;
3081 }
3082 }
3083 }
3084 }
3085};
3086
3087jQuery.removeEvent = document.removeEventListener ?
3088 function( elem, type, handle ) {
3089 if ( elem.removeEventListener ) {
3090 elem.removeEventListener( type, handle, false );
3091 }
3092 } :
3093 function( elem, type, handle ) {
3094 if ( elem.detachEvent ) {
3095 elem.detachEvent( "on" + type, handle );
3096 }
3097 };
3098
3099jQuery.Event = function( src, props ) {
3100 // Allow instantiation without the 'new' keyword
3101 if ( !this.preventDefault ) {
3102 return new jQuery.Event( src, props );
3103 }
3104
3105 // Event object
3106 if ( src && src.type ) {
3107 this.originalEvent = src;
3108 this.type = src.type;
3109
3110 // Events bubbling up the document may have been marked as prevented
3111 // by a handler lower down the tree; reflect the correct value.
3112 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3113 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3114
3115 // Event type
3116 } else {
3117 this.type = src;
3118 }
3119
3120 // Put explicitly provided properties onto the event object
3121 if ( props ) {
3122 jQuery.extend( this, props );
3123 }
3124
3125 // timeStamp is buggy for some events on Firefox(#3843)
3126 // So we won't rely on the native value
3127 this.timeStamp = jQuery.now();
3128
3129 // Mark it as fixed
3130 this[ jQuery.expando ] = true;
3131};
3132
3133function returnFalse() {
3134 return false;
3135}
3136function returnTrue() {
3137 return true;
3138}
3139
3140// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3141// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3142jQuery.Event.prototype = {
3143 preventDefault: function() {
3144 this.isDefaultPrevented = returnTrue;
3145
3146 var e = this.originalEvent;
3147 if ( !e ) {
3148 return;
3149 }
3150
3151 // if preventDefault exists run it on the original event
3152 if ( e.preventDefault ) {
3153 e.preventDefault();
3154
3155 // otherwise set the returnValue property of the original event to false (IE)
3156 } else {
3157 e.returnValue = false;
3158 }
3159 },
3160 stopPropagation: function() {
3161 this.isPropagationStopped = returnTrue;
3162
3163 var e = this.originalEvent;
3164 if ( !e ) {
3165 return;
3166 }
3167 // if stopPropagation exists run it on the original event
3168 if ( e.stopPropagation ) {
3169 e.stopPropagation();
3170 }
3171 // otherwise set the cancelBubble property of the original event to true (IE)
3172 e.cancelBubble = true;
3173 },
3174 stopImmediatePropagation: function() {
3175 this.isImmediatePropagationStopped = returnTrue;
3176 this.stopPropagation();
3177 },
3178 isDefaultPrevented: returnFalse,
3179 isPropagationStopped: returnFalse,
3180 isImmediatePropagationStopped: returnFalse
3181};
3182
3183// Checks if an event happened on an element within another element
3184// Used in jQuery.event.special.mouseenter and mouseleave handlers
3185var withinElement = function( event ) {
3186
3187 // Check if mouse(over|out) are still within the same parent element
3188 var related = event.relatedTarget,
3189 inside = false,
3190 eventType = event.type;
3191
3192 event.type = event.data;
3193
3194 if ( related !== this ) {
3195
3196 if ( related ) {
3197 inside = jQuery.contains( this, related );
3198 }
3199
3200 if ( !inside ) {
3201
3202 jQuery.event.handle.apply( this, arguments );
3203
3204 event.type = eventType;
3205 }
3206 }
3207},
3208
3209// In case of event delegation, we only need to rename the event.type,
3210// liveHandler will take care of the rest.
3211delegate = function( event ) {
3212 event.type = event.data;
3213 jQuery.event.handle.apply( this, arguments );
3214};
3215
3216// Create mouseenter and mouseleave events
3217jQuery.each({
3218 mouseenter: "mouseover",
3219 mouseleave: "mouseout"
3220}, function( orig, fix ) {
3221 jQuery.event.special[ orig ] = {
3222 setup: function( data ) {
3223 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3224 },
3225 teardown: function( data ) {
3226 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3227 }
3228 };
3229});
3230
3231// submit delegation
3232if ( !jQuery.support.submitBubbles ) {
3233
3234 jQuery.event.special.submit = {
3235 setup: function( data, namespaces ) {
3236 if ( !jQuery.nodeName( this, "form" ) ) {
3237 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3238 var elem = e.target,
3239 type = elem.type;
3240
3241 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3242 trigger( "submit", this, arguments );
3243 }
3244 });
3245
3246 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3247 var elem = e.target,
3248 type = elem.type;
3249
3250 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3251 trigger( "submit", this, arguments );
3252 }
3253 });
3254
3255 } else {
3256 return false;
3257 }
3258 },
3259
3260 teardown: function( namespaces ) {
3261 jQuery.event.remove( this, ".specialSubmit" );
3262 }
3263 };
3264
3265}
3266
3267// change delegation, happens here so we have bind.
3268if ( !jQuery.support.changeBubbles ) {
3269
3270 var changeFilters,
3271
3272 getVal = function( elem ) {
3273 var type = elem.type, val = elem.value;
3274
3275 if ( type === "radio" || type === "checkbox" ) {
3276 val = elem.checked;
3277
3278 } else if ( type === "select-multiple" ) {
3279 val = elem.selectedIndex > -1 ?
3280 jQuery.map( elem.options, function( elem ) {
3281 return elem.selected;
3282 }).join("-") :
3283 "";
3284
3285 } else if ( jQuery.nodeName( elem, "select" ) ) {
3286 val = elem.selectedIndex;
3287 }
3288
3289 return val;
3290 },
3291
3292 testChange = function testChange( e ) {
3293 var elem = e.target, data, val;
3294
3295 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3296 return;
3297 }
3298
3299 data = jQuery._data( elem, "_change_data" );
3300 val = getVal(elem);
3301
3302 // the current data will be also retrieved by beforeactivate
3303 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3304 jQuery._data( elem, "_change_data", val );
3305 }
3306
3307 if ( data === undefined || val === data ) {
3308 return;
3309 }
3310
3311 if ( data != null || val ) {
3312 e.type = "change";
3313 e.liveFired = undefined;
3314 jQuery.event.trigger( e, arguments[1], elem );
3315 }
3316 };
3317
3318 jQuery.event.special.change = {
3319 filters: {
3320 focusout: testChange,
3321
3322 beforedeactivate: testChange,
3323
3324 click: function( e ) {
3325 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3326
3327 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3328 testChange.call( this, e );
3329 }
3330 },
3331
3332 // Change has to be called before submit
3333 // Keydown will be called before keypress, which is used in submit-event delegation
3334 keydown: function( e ) {
3335 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3336
3337 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3338 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3339 type === "select-multiple" ) {
3340 testChange.call( this, e );
3341 }
3342 },
3343
3344 // Beforeactivate happens also before the previous element is blurred
3345 // with this event you can't trigger a change event, but you can store
3346 // information
3347 beforeactivate: function( e ) {
3348 var elem = e.target;
3349 jQuery._data( elem, "_change_data", getVal(elem) );
3350 }
3351 },
3352
3353 setup: function( data, namespaces ) {
3354 if ( this.type === "file" ) {
3355 return false;
3356 }
3357
3358 for ( var type in changeFilters ) {
3359 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3360 }
3361
3362 return rformElems.test( this.nodeName );
3363 },
3364
3365 teardown: function( namespaces ) {
3366 jQuery.event.remove( this, ".specialChange" );
3367
3368 return rformElems.test( this.nodeName );
3369 }
3370 };
3371
3372 changeFilters = jQuery.event.special.change.filters;
3373
3374 // Handle when the input is .focus()'d
3375 changeFilters.focus = changeFilters.beforeactivate;
3376}
3377
3378function trigger( type, elem, args ) {
3379 // Piggyback on a donor event to simulate a different one.
3380 // Fake originalEvent to avoid donor's stopPropagation, but if the
3381 // simulated event prevents default then we do the same on the donor.
3382 // Don't pass args or remember liveFired; they apply to the donor event.
3383 var event = jQuery.extend( {}, args[ 0 ] );
3384 event.type = type;
3385 event.originalEvent = {};
3386 event.liveFired = undefined;
3387 jQuery.event.handle.call( elem, event );
3388 if ( event.isDefaultPrevented() ) {
3389 args[ 0 ].preventDefault();
3390 }
3391}
3392
3393// Create "bubbling" focus and blur events
3394if ( !jQuery.support.focusinBubbles ) {
3395 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3396
3397 // Attach a single capturing handler while someone wants focusin/focusout
3398 var attaches = 0;
3399
3400 jQuery.event.special[ fix ] = {
3401 setup: function() {
3402 if ( attaches++ === 0 ) {
3403 document.addEventListener( orig, handler, true );
3404 }
3405 },
3406 teardown: function() {
3407 if ( --attaches === 0 ) {
3408 document.removeEventListener( orig, handler, true );
3409 }
3410 }
3411 };
3412
3413 function handler( donor ) {
3414 // Donor event is always a native one; fix it and switch its type.
3415 // Let focusin/out handler cancel the donor focus/blur event.
3416 var e = jQuery.event.fix( donor );
3417 e.type = fix;
3418 e.originalEvent = {};
3419 jQuery.event.trigger( e, null, e.target );
3420 if ( e.isDefaultPrevented() ) {
3421 donor.preventDefault();
3422 }
3423 }
3424 });
3425}
3426
3427jQuery.each(["bind", "one"], function( i, name ) {
3428 jQuery.fn[ name ] = function( type, data, fn ) {
3429 var handler;
3430
3431 // Handle object literals
3432 if ( typeof type === "object" ) {
3433 for ( var key in type ) {
3434 this[ name ](key, data, type[key], fn);
3435 }
3436 return this;
3437 }
3438
3439 if ( arguments.length === 2 || data === false ) {
3440 fn = data;
3441 data = undefined;
3442 }
3443
3444 if ( name === "one" ) {
3445 handler = function( event ) {
3446 jQuery( this ).unbind( event, handler );
3447 return fn.apply( this, arguments );
3448 };
3449 handler.guid = fn.guid || jQuery.guid++;
3450 } else {
3451 handler = fn;
3452 }
3453
3454 if ( type === "unload" && name !== "one" ) {
3455 this.one( type, data, fn );
3456
3457 } else {
3458 for ( var i = 0, l = this.length; i < l; i++ ) {
3459 jQuery.event.add( this[i], type, handler, data );
3460 }
3461 }
3462
3463 return this;
3464 };
3465});
3466
3467jQuery.fn.extend({
3468 unbind: function( type, fn ) {
3469 // Handle object literals
3470 if ( typeof type === "object" && !type.preventDefault ) {
3471 for ( var key in type ) {
3472 this.unbind(key, type[key]);
3473 }
3474
3475 } else {
3476 for ( var i = 0, l = this.length; i < l; i++ ) {
3477 jQuery.event.remove( this[i], type, fn );
3478 }
3479 }
3480
3481 return this;
3482 },
3483
3484 delegate: function( selector, types, data, fn ) {
3485 return this.live( types, data, fn, selector );
3486 },
3487
3488 undelegate: function( selector, types, fn ) {
3489 if ( arguments.length === 0 ) {
3490 return this.unbind( "live" );
3491
3492 } else {
3493 return this.die( types, null, fn, selector );
3494 }
3495 },
3496
3497 trigger: function( type, data ) {
3498 return this.each(function() {
3499 jQuery.event.trigger( type, data, this );
3500 });
3501 },
3502
3503 triggerHandler: function( type, data ) {
3504 if ( this[0] ) {
3505 return jQuery.event.trigger( type, data, this[0], true );
3506 }
3507 },
3508
3509 toggle: function( fn ) {
3510 // Save reference to arguments for access in closure
3511 var args = arguments,
3512 guid = fn.guid || jQuery.guid++,
3513 i = 0,
3514 toggler = function( event ) {
3515 // Figure out which function to execute
3516 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3517 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3518
3519 // Make sure that clicks stop
3520 event.preventDefault();
3521
3522 // and execute the function
3523 return args[ lastToggle ].apply( this, arguments ) || false;
3524 };
3525
3526 // link all the functions, so any of them can unbind this click handler
3527 toggler.guid = guid;
3528 while ( i < args.length ) {
3529 args[ i++ ].guid = guid;
3530 }
3531
3532 return this.click( toggler );
3533 },
3534
3535 hover: function( fnOver, fnOut ) {
3536 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3537 }
3538});
3539
3540var liveMap = {
3541 focus: "focusin",
3542 blur: "focusout",
3543 mouseenter: "mouseover",
3544 mouseleave: "mouseout"
3545};
3546
3547jQuery.each(["live", "die"], function( i, name ) {
3548 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3549 var type, i = 0, match, namespaces, preType,
3550 selector = origSelector || this.selector,
3551 context = origSelector ? this : jQuery( this.context );
3552
3553 if ( typeof types === "object" && !types.preventDefault ) {
3554 for ( var key in types ) {
3555 context[ name ]( key, data, types[key], selector );
3556 }
3557
3558 return this;
3559 }
3560
3561 if ( name === "die" && !types &&
3562 origSelector && origSelector.charAt(0) === "." ) {
3563
3564 context.unbind( origSelector );
3565
3566 return this;
3567 }
3568
3569 if ( data === false || jQuery.isFunction( data ) ) {
3570 fn = data || returnFalse;
3571 data = undefined;
3572 }
3573
3574 types = (types || "").split(" ");
3575
3576 while ( (type = types[ i++ ]) != null ) {
3577 match = rnamespaces.exec( type );
3578 namespaces = "";
3579
3580 if ( match ) {
3581 namespaces = match[0];
3582 type = type.replace( rnamespaces, "" );
3583 }
3584
3585 if ( type === "hover" ) {
3586 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3587 continue;
3588 }
3589
3590 preType = type;
3591
3592 if ( liveMap[ type ] ) {
3593 types.push( liveMap[ type ] + namespaces );
3594 type = type + namespaces;
3595
3596 } else {
3597 type = (liveMap[ type ] || type) + namespaces;
3598 }
3599
3600 if ( name === "live" ) {
3601 // bind live handler
3602 for ( var j = 0, l = context.length; j < l; j++ ) {
3603 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3604 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3605 }
3606
3607 } else {
3608 // unbind live handler
3609 context.unbind( "live." + liveConvert( type, selector ), fn );
3610 }
3611 }
3612
3613 return this;
3614 };
3615});
3616
3617function liveHandler( event ) {
3618 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3619 elems = [],
3620 selectors = [],
3621 events = jQuery._data( this, "events" );
3622
3623 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3624 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3625 return;
3626 }
3627
3628 if ( event.namespace ) {
3629 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3630 }
3631
3632 event.liveFired = this;
3633
3634 var live = events.live.slice(0);
3635
3636 for ( j = 0; j < live.length; j++ ) {
3637 handleObj = live[j];
3638
3639 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3640 selectors.push( handleObj.selector );
3641
3642 } else {
3643 live.splice( j--, 1 );
3644 }
3645 }
3646
3647 match = jQuery( event.target ).closest( selectors, event.currentTarget );
3648
3649 for ( i = 0, l = match.length; i < l; i++ ) {
3650 close = match[i];
3651
3652 for ( j = 0; j < live.length; j++ ) {
3653 handleObj = live[j];
3654
3655 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3656 elem = close.elem;
3657 related = null;
3658
3659 // Those two events require additional checking
3660 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3661 event.type = handleObj.preType;
3662 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3663
3664 // Make sure not to accidentally match a child element with the same selector
3665 if ( related && jQuery.contains( elem, related ) ) {
3666 related = elem;
3667 }
3668 }
3669
3670 if ( !related || related !== elem ) {
3671 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3672 }
3673 }
3674 }
3675 }
3676
3677 for ( i = 0, l = elems.length; i < l; i++ ) {
3678 match = elems[i];
3679
3680 if ( maxLevel && match.level > maxLevel ) {
3681 break;
3682 }
3683
3684 event.currentTarget = match.elem;
3685 event.data = match.handleObj.data;
3686 event.handleObj = match.handleObj;
3687
3688 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3689
3690 if ( ret === false || event.isPropagationStopped() ) {
3691 maxLevel = match.level;
3692
3693 if ( ret === false ) {
3694 stop = false;
3695 }
3696 if ( event.isImmediatePropagationStopped() ) {
3697 break;
3698 }
3699 }
3700 }
3701
3702 return stop;
3703}
3704
3705function liveConvert( type, selector ) {
3706 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3707}
3708
3709jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3710 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3711 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3712
3713 // Handle event binding
3714 jQuery.fn[ name ] = function( data, fn ) {
3715 if ( fn == null ) {
3716 fn = data;
3717 data = null;
3718 }
3719
3720 return arguments.length > 0 ?
3721 this.bind( name, data, fn ) :
3722 this.trigger( name );
3723 };
3724
3725 if ( jQuery.attrFn ) {
3726 jQuery.attrFn[ name ] = true;
3727 }
3728});
3729
3730
3731
3732/*!
3733 * Sizzle CSS Selector Engine
3734 * Copyright 2011, The Dojo Foundation
1416 * Released under the MIT, BSD, and GPL Licenses.3735 * Released under the MIT, BSD, and GPL Licenses.
1417 * More information: http://sizzlejs.com/3736 * More information: http://sizzlejs.com/
1418 */3737 */
1419(function(){3738(function(){
14203739
1421var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,3740var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
1422 done = 0,3741 done = 0,
1423 toString = Object.prototype.toString;3742 toString = Object.prototype.toString,
14243743 hasDuplicate = false,
1425var Sizzle = function(selector, context, results, seed) {3744 baseHasDuplicate = true,
3745 rBackslash = /\\/g,
3746 rNonWord = /\W/;
3747
3748// Here we check if the JavaScript engine is using some sort of
3749// optimization where it does not always call our comparision
3750// function. If that is the case, discard the hasDuplicate value.
3751// Thus far that includes Google Chrome.
3752[0, 0].sort(function() {
3753 baseHasDuplicate = false;
3754 return 0;
3755});
3756
3757var Sizzle = function( selector, context, results, seed ) {
1426 results = results || [];3758 results = results || [];
1427 context = context || document;3759 context = context || document;
14283760
1429 if ( context.nodeType !== 1 && context.nodeType !== 9 )3761 var origContext = context;
3762
3763 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
1430 return [];3764 return [];
3765 }
1431 3766
1432 if ( !selector || typeof selector !== "string" ) {3767 if ( !selector || typeof selector !== "string" ) {
1433 return results;3768 return results;
1434 }3769 }
14353770
1436 var parts = [], m, set, checkSet, check, mode, extra, prune = true;3771 var m, set, checkSet, extra, ret, cur, pop, i,
3772 prune = true,
3773 contextXML = Sizzle.isXML( context ),
3774 parts = [],
3775 soFar = selector;
1437 3776
1438 // Reset the position of the chunker regexp (start from head)3777 // Reset the position of the chunker regexp (start from head)
1439 chunker.lastIndex = 0;3778 do {
1440 3779 chunker.exec( "" );
1441 while ( (m = chunker.exec(selector)) !== null ) {3780 m = chunker.exec( soFar );
1442 parts.push( m[1] );3781
1443 3782 if ( m ) {
1444 if ( m[2] ) {3783 soFar = m[3];
1445 extra = RegExp.rightContext;3784
1446 break;3785 parts.push( m[1] );
3786
3787 if ( m[2] ) {
3788 extra = m[3];
3789 break;
3790 }
1447 }3791 }
1448 }3792 } while ( m );
14493793
1450 if ( parts.length > 1 && origPOS.exec( selector ) ) {3794 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3795
1451 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {3796 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1452 set = posProcess( parts[0] + parts[1], context );3797 set = posProcess( parts[0] + parts[1], context );
3798
1453 } else {3799 } else {
1454 set = Expr.relative[ parts[0] ] ?3800 set = Expr.relative[ parts[0] ] ?
1455 [ context ] :3801 [ context ] :
@@ -1458,38 +3804,61 @@
1458 while ( parts.length ) {3804 while ( parts.length ) {
1459 selector = parts.shift();3805 selector = parts.shift();
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches