Mercurial > ~darius > hgwebdir.cgi > iwws
comparison static/jquery-1.6.2.js @ 0:2d9ee2b3ae82
Initial commit of iWWS.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Mon, 15 Aug 2011 17:44:56 +0930 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:2d9ee2b3ae82 |
---|---|
1 /*! | |
2 * jQuery JavaScript Library v1.6.2 | |
3 * http://jquery.com/ | |
4 * | |
5 * Copyright 2011, John Resig | |
6 * Dual licensed under the MIT or GPL Version 2 licenses. | |
7 * http://jquery.org/license | |
8 * | |
9 * Includes Sizzle.js | |
10 * 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 | |
15 */ | |
16 (function( window, undefined ) { | |
17 | |
18 // Use the correct document accordingly with window argument (sandbox) | |
19 var document = window.document, | |
20 navigator = window.navigator, | |
21 location = window.location; | |
22 var jQuery = (function() { | |
23 | |
24 // Define a local copy of jQuery | |
25 var 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 | |
30 // Map over jQuery in case of overwrite | |
31 _jQuery = window.jQuery, | |
32 | |
33 // Map over the $ in case of overwrite | |
34 _$ = window.$, | |
35 | |
36 // A central reference to the root jQuery(document) | |
37 rootjQuery, | |
38 | |
39 // A simple way to check for HTML strings or ID strings | |
40 // (both of which we optimize for) | |
41 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, | |
42 | |
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 = {}; | |
98 | |
99 jQuery.fn = jQuery.prototype = { | |
100 constructor: jQuery, | |
101 init: function( selector, context, rootjQuery ) { | |
102 var match, elem, ret, doc; | |
103 | |
104 // Handle $(""), $(null), or $(undefined) | |
105 if ( !selector ) { | |
106 return this; | |
107 } | |
108 | |
109 // Handle $(DOMElement) | |
110 if ( selector.nodeType ) { | |
111 this.context = this[0] = selector; | |
112 this.length = 1; | |
113 return this; | |
114 } | |
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 | |
125 // Handle HTML strings | |
126 if ( typeof selector === "string" ) { | |
127 // Are we dealing with HTML string or an ID? | |
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 } | |
135 | |
136 // Verify a match, and that no context was specified for #id | |
137 if ( match && (match[1] || !context) ) { | |
138 | |
139 // HANDLE: $(html) -> $(array) | |
140 if ( match[1] ) { | |
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 ); | |
163 | |
164 // HANDLE: $("#id") | |
165 } else { | |
166 elem = document.getElementById( match[2] ); | |
167 | |
168 // Check parentNode to catch when Blackberry 4.6 returns | |
169 // nodes that are no longer in the document #6963 | |
170 if ( elem && elem.parentNode ) { | |
171 // Handle the case where IE and Opera return items | |
172 // by name instead of ID | |
173 if ( elem.id !== match[2] ) { | |
174 return rootjQuery.find( selector ); | |
175 } | |
176 | |
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; | |
185 } | |
186 | |
187 // HANDLE: $(expr, $(...)) | |
188 } else if ( !context || context.jquery ) { | |
189 return (context || rootjQuery).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 } | |
196 | |
197 // HANDLE: $(function) | |
198 // Shortcut for document ready | |
199 } else if ( jQuery.isFunction( selector ) ) { | |
200 return rootjQuery.ready( selector ); | |
201 } | |
202 | |
203 if (selector.selector !== undefined) { | |
204 this.selector = selector.selector; | |
205 this.context = selector.context; | |
206 } | |
207 | |
208 return jQuery.makeArray( selector, this ); | |
209 }, | |
210 | |
211 // Start with an empty selector | |
212 selector: "", | |
213 | |
214 // The current version of jQuery being used | |
215 jquery: "1.6.2", | |
216 | |
217 // The default length of a jQuery object is 0 | |
218 length: 0, | |
219 | |
220 // The number of elements contained in the matched element set | |
221 size: function() { | |
222 return this.length; | |
223 }, | |
224 | |
225 toArray: function() { | |
226 return slice.call( this, 0 ); | |
227 }, | |
228 | |
229 // Get the Nth element in the matched element set OR | |
230 // Get the whole matched element set as a clean array | |
231 get: function( num ) { | |
232 return num == null ? | |
233 | |
234 // Return a 'clean' array | |
235 this.toArray() : | |
236 | |
237 // Return just the object | |
238 ( num < 0 ? this[ this.length + num ] : this[ num ] ); | |
239 }, | |
240 | |
241 // Take an array of elements and push it onto the stack | |
242 // (returning the new matched element set) | |
243 pushStack: function( elems, name, selector ) { | |
244 // Build a new jQuery matched element set | |
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 } | |
253 | |
254 // Add the old object onto the stack (as a reference) | |
255 ret.prevObject = this; | |
256 | |
257 ret.context = this.context; | |
258 | |
259 if ( name === "find" ) { | |
260 ret.selector = this.selector + (this.selector ? " " : "") + selector; | |
261 } else if ( name ) { | |
262 ret.selector = this.selector + "." + name + "(" + selector + ")"; | |
263 } | |
264 | |
265 // Return the newly-formed element set | |
266 return ret; | |
267 }, | |
268 | |
269 // Execute a callback for every element in the matched set. | |
270 // (You can seed the arguments with an array of args, but this is | |
271 // only used internally.) | |
272 each: function( callback, args ) { | |
273 return jQuery.each( this, callback, args ); | |
274 }, | |
275 | |
276 ready: function( fn ) { | |
277 // Attach the listeners | |
278 jQuery.bindReady(); | |
279 | |
280 // Add the callback | |
281 readyList.done( fn ); | |
282 | |
283 return this; | |
284 }, | |
285 | |
286 eq: function( i ) { | |
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 ); | |
298 }, | |
299 | |
300 slice: function() { | |
301 return this.pushStack( slice.apply( this, arguments ), | |
302 "slice", slice.call(arguments).join(",") ); | |
303 }, | |
304 | |
305 map: function( callback ) { | |
306 return this.pushStack( jQuery.map(this, function( elem, i ) { | |
307 return callback.call( elem, i, elem ); | |
308 })); | |
309 }, | |
310 | |
311 end: function() { | |
312 return this.prevObject || this.constructor(null); | |
313 }, | |
314 | |
315 // For internal use only. | |
316 // Behaves like an Array's method, not like a jQuery method. | |
317 push: push, | |
318 sort: [].sort, | |
319 splice: [].splice | |
320 }; | |
321 | |
322 // Give the init function the jQuery prototype for later instantiation | |
323 jQuery.fn.init.prototype = jQuery.fn; | |
324 | |
325 jQuery.extend = jQuery.fn.extend = function() { | |
326 var options, name, src, copy, copyIsArray, clone, | |
327 target = arguments[0] || {}, | |
328 i = 1, | |
329 length = arguments.length, | |
330 deep = false; | |
331 | |
332 // Handle a deep copy situation | |
333 if ( typeof target === "boolean" ) { | |
334 deep = target; | |
335 target = arguments[1] || {}; | |
336 // skip the boolean and the target | |
337 i = 2; | |
338 } | |
339 | |
340 // Handle case when target is a string or something (possible in deep copy) | |
341 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { | |
342 target = {}; | |
343 } | |
344 | |
345 // extend jQuery itself if only one argument is passed | |
346 if ( length === i ) { | |
347 target = this; | |
348 --i; | |
349 } | |
350 | |
351 for ( ; i < length; i++ ) { | |
352 // Only deal with non-null/undefined values | |
353 if ( (options = arguments[ i ]) != null ) { | |
354 // Extend the base object | |
355 for ( name in options ) { | |
356 src = target[ name ]; | |
357 copy = options[ name ]; | |
358 | |
359 // Prevent never-ending loop | |
360 if ( target === copy ) { | |
361 continue; | |
362 } | |
363 | |
364 // Recurse if we're merging plain objects or arrays | |
365 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { | |
366 if ( copyIsArray ) { | |
367 copyIsArray = false; | |
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 ); | |
376 | |
377 // Don't bring in undefined values | |
378 } else if ( copy !== undefined ) { | |
379 target[ name ] = copy; | |
380 } | |
381 } | |
382 } | |
383 } | |
384 | |
385 // Return the modified object | |
386 return target; | |
387 }; | |
388 | |
389 jQuery.extend({ | |
390 noConflict: function( deep ) { | |
391 if ( window.$ === jQuery ) { | |
392 window.$ = _$; | |
393 } | |
394 | |
395 if ( deep && window.jQuery === jQuery ) { | |
396 window.jQuery = _jQuery; | |
397 } | |
398 | |
399 return jQuery; | |
400 }, | |
401 | |
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 | |
490 // See test/unit/core.js for details concerning isFunction. | |
491 // Since version 1.3, DOM methods and functions like alert | |
492 // aren't supported. They return false on IE (#2968). | |
493 isFunction: function( obj ) { | |
494 return jQuery.type(obj) === "function"; | |
495 }, | |
496 | |
497 isArray: Array.isArray || function( obj ) { | |
498 return jQuery.type(obj) === "array"; | |
499 }, | |
500 | |
501 // A crude way of determining if an object is a window | |
502 isWindow: function( obj ) { | |
503 return obj && typeof obj === "object" && "setInterval" in obj; | |
504 }, | |
505 | |
506 isNaN: function( obj ) { | |
507 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 | |
603 globalEval: function( data ) { | |
604 if ( data && rnotwhite.test( data ) ) { | |
605 // We use execScript on Internet Explorer | |
606 // We use an anonymous function so that context is window | |
607 // rather than jQuery in Firefox | |
608 ( window.execScript || function( data ) { | |
609 window[ "eval" ].call( window, data ); | |
610 } )( data ); | |
611 } | |
612 }, | |
613 | |
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 | |
620 nodeName: function( elem, name ) { | |
621 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); | |
622 }, | |
623 | |
624 // args is for internal usage only | |
625 each: function( object, callback, args ) { | |
626 var name, i = 0, | |
627 length = object.length, | |
628 isObj = length === undefined || jQuery.isFunction( object ); | |
629 | |
630 if ( args ) { | |
631 if ( isObj ) { | |
632 for ( name in object ) { | |
633 if ( callback.apply( object[ name ], args ) === false ) { | |
634 break; | |
635 } | |
636 } | |
637 } else { | |
638 for ( ; i < length; ) { | |
639 if ( callback.apply( object[ i++ ], args ) === false ) { | |
640 break; | |
641 } | |
642 } | |
643 } | |
644 | |
645 // A special, fast, case for the most common use of each | |
646 } else { | |
647 if ( isObj ) { | |
648 for ( name in object ) { | |
649 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { | |
650 break; | |
651 } | |
652 } | |
653 } else { | |
654 for ( ; i < length; ) { | |
655 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { | |
656 break; | |
657 } | |
658 } | |
659 } | |
660 } | |
661 | |
662 return object; | |
663 }, | |
664 | |
665 // Use native String.trim function wherever possible | |
666 trim: trim ? | |
667 function( text ) { | |
668 return text == null ? | |
669 "" : | |
670 trim.call( text ); | |
671 } : | |
672 | |
673 // Otherwise use our own trimming functionality | |
674 function( text ) { | |
675 return text == null ? | |
676 "" : | |
677 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); | |
678 }, | |
679 | |
680 // results is for internal usage only | |
681 makeArray: function( array, results ) { | |
682 var ret = results || []; | |
683 | |
684 if ( array != null ) { | |
685 // The window, strings (and functions) also have 'length' | |
686 // The extra typeof function check is to prevent crashes | |
687 // in Safari 2 (See: #3039) | |
688 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 | |
689 var type = jQuery.type( array ); | |
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 } | |
696 } | |
697 | |
698 return ret; | |
699 }, | |
700 | |
701 inArray: function( elem, array ) { | |
702 | |
703 if ( indexOf ) { | |
704 return indexOf.call( array, elem ); | |
705 } | |
706 | |
707 for ( var i = 0, length = array.length; i < length; i++ ) { | |
708 if ( array[ i ] === elem ) { | |
709 return i; | |
710 } | |
711 } | |
712 | |
713 return -1; | |
714 }, | |
715 | |
716 merge: function( first, second ) { | |
717 var i = first.length, | |
718 j = 0; | |
719 | |
720 if ( typeof second.length === "number" ) { | |
721 for ( var l = second.length; j < l; j++ ) { | |
722 first[ i++ ] = second[ j ]; | |
723 } | |
724 | |
725 } else { | |
726 while ( second[j] !== undefined ) { | |
727 first[ i++ ] = second[ j++ ]; | |
728 } | |
729 } | |
730 | |
731 first.length = i; | |
732 | |
733 return first; | |
734 }, | |
735 | |
736 grep: function( elems, callback, inv ) { | |
737 var ret = [], retVal; | |
738 inv = !!inv; | |
739 | |
740 // Go through the array, only saving the items | |
741 // that pass the validator function | |
742 for ( var i = 0, length = elems.length; i < length; i++ ) { | |
743 retVal = !!callback( elems[ i ], i ); | |
744 if ( inv !== retVal ) { | |
745 ret.push( elems[ i ] ); | |
746 } | |
747 } | |
748 | |
749 return ret; | |
750 }, | |
751 | |
752 // arg is for internal usage only | |
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 ) ) ; | |
759 | |
760 // Go through the array, translating each of the items to their | |
761 if ( isArray ) { | |
762 for ( ; i < length; i++ ) { | |
763 value = callback( elems[ i ], i, arg ); | |
764 | |
765 if ( value != null ) { | |
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 } | |
779 } | |
780 | |
781 // Flatten any nested arrays | |
782 return ret.concat.apply( [], ret ); | |
783 }, | |
784 | |
785 // A global GUID counter for objects | |
786 guid: 1, | |
787 | |
788 // Bind a function to a context, optionally partially applying any | |
789 // arguments. | |
790 proxy: function( fn, context ) { | |
791 if ( typeof context === "string" ) { | |
792 var tmp = fn[ context ]; | |
793 context = fn; | |
794 fn = tmp; | |
795 } | |
796 | |
797 // Quick check to determine if target is callable, in the spec | |
798 // this throws a TypeError, but we will just return undefined. | |
799 if ( !jQuery.isFunction( fn ) ) { | |
800 return undefined; | |
801 } | |
802 | |
803 // Simulated bind | |
804 var args = slice.call( arguments, 2 ), | |
805 proxy = function() { | |
806 return fn.apply( context, args.concat( slice.call( arguments ) ) ); | |
807 }; | |
808 | |
809 // Set the guid of unique handler to the same of original handler, so it can be removed | |
810 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; | |
811 | |
812 return proxy; | |
813 }, | |
814 | |
815 // Mutifunctional method to get and set values to a collection | |
816 // The value/s can optionally be executed if it's a function | |
817 access: function( elems, key, value, exec, fn, pass ) { | |
818 var length = elems.length; | |
819 | |
820 // Setting many attributes | |
821 if ( typeof key === "object" ) { | |
822 for ( var k in key ) { | |
823 jQuery.access( elems, k, key[k], exec, fn, value ); | |
824 } | |
825 return elems; | |
826 } | |
827 | |
828 // Setting one attribute | |
829 if ( value !== undefined ) { | |
830 // Optionally, function values get executed if exec is true | |
831 exec = !pass && exec && jQuery.isFunction(value); | |
832 | |
833 for ( var i = 0; i < length; i++ ) { | |
834 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); | |
835 } | |
836 | |
837 return elems; | |
838 } | |
839 | |
840 // Getting an attribute | |
841 return length ? fn( elems[0], key ) : undefined; | |
842 }, | |
843 | |
844 now: function() { | |
845 return (new Date()).getTime(); | |
846 }, | |
847 | |
848 // Use of jQuery.browser is frowned upon. | |
849 // More details: http://docs.jquery.com/Utilities/jQuery.browser | |
850 uaMatch: function( ua ) { | |
851 ua = ua.toLowerCase(); | |
852 | |
853 var match = rwebkit.exec( ua ) || | |
854 ropera.exec( ua ) || | |
855 rmsie.exec( ua ) || | |
856 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || | |
857 []; | |
858 | |
859 return { browser: match[1] || "", version: match[2] || "0" }; | |
860 }, | |
861 | |
862 sub: function() { | |
863 function jQuerySub( selector, context ) { | |
864 return new jQuerySub.fn.init( selector, context ); | |
865 } | |
866 jQuery.extend( true, jQuerySub, this ); | |
867 jQuerySub.superclass = this; | |
868 jQuerySub.fn = jQuerySub.prototype = this(); | |
869 jQuerySub.fn.constructor = jQuerySub; | |
870 jQuerySub.sub = this.sub; | |
871 jQuerySub.fn.init = function init( selector, context ) { | |
872 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { | |
873 context = jQuerySub( context ); | |
874 } | |
875 | |
876 return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); | |
877 }; | |
878 jQuerySub.fn.init.prototype = jQuerySub.fn; | |
879 var rootjQuerySub = jQuerySub(document); | |
880 return jQuerySub; | |
881 }, | |
882 | |
883 browser: {} | |
884 }); | |
885 | |
886 // Populate the class2type map | |
887 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { | |
888 class2type[ "[object " + name + "]" ] = name.toLowerCase(); | |
889 }); | |
890 | |
891 browserMatch = jQuery.uaMatch( userAgent ); | |
892 if ( browserMatch.browser ) { | |
893 jQuery.browser[ browserMatch.browser ] = true; | |
894 jQuery.browser.version = browserMatch.version; | |
895 } | |
896 | |
897 // Deprecated, use jQuery.browser.webkit instead | |
898 if ( jQuery.browser.webkit ) { | |
899 jQuery.browser.safari = true; | |
900 } | |
901 | |
902 // IE doesn't match non-breaking spaces with \s | |
903 if ( rnotwhite.test( "\xA0" ) ) { | |
904 trimLeft = /^[\s\xA0]+/; | |
905 trimRight = /[\s\xA0]+$/; | |
906 } | |
907 | |
908 // All jQuery objects should point back to these | |
909 rootjQuery = jQuery(document); | |
910 | |
911 // Cleanup functions for the document ready method | |
912 if ( 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 | |
929 function 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 | |
947 return jQuery; | |
948 | |
949 })(); | |
950 | |
951 | |
952 var // Promise methods | |
953 promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), | |
954 // Static reference to slice | |
955 sliceDeferred = [].slice; | |
956 | |
957 jQuery.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 | |
1150 jQuery.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 | |
1401 jQuery.boxModel = jQuery.support.boxModel; | |
1402 | |
1403 | |
1404 | |
1405 | |
1406 var rbrace = /^(?:\{.*\}|\[.*\])$/, | |
1407 rmultiDash = /([a-z])([A-Z])/g; | |
1408 | |
1409 jQuery.extend({ | |
1410 cache: {}, | |
1411 | |
1412 // Please use with caution | |
1413 uuid: 0, | |
1414 | |
1415 // Unique for each copy of jQuery on the page | |
1416 // Non-digits removed to match rinlinejQuery | |
1417 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), | |
1418 | |
1419 // The following elements throw uncatchable exceptions if you | |
1420 // attempt to add expando properties to them. | |
1421 noData: { | |
1422 "embed": true, | |
1423 // Ban all objects except for Flash (which handle expandos) | |
1424 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", | |
1425 "applet": true | |
1426 }, | |
1427 | |
1428 hasData: function( elem ) { | |
1429 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; | |
1430 | |
1431 return !!elem && !isEmptyDataObject( elem ); | |
1432 }, | |
1433 | |
1434 data: function( elem, name, data, pvt /* Internal Use Only */ ) { | |
1435 if ( !jQuery.acceptData( elem ) ) { | |
1436 return; | |
1437 } | |
1438 | |
1439 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, | |
1440 | |
1441 // We have to handle DOM nodes and JS objects differently because IE6-7 | |
1442 // can't GC object references properly across the DOM-JS boundary | |
1443 isNode = elem.nodeType, | |
1444 | |
1445 // 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 | |
1539 if ( name ) { | |
1540 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; | |
1541 | |
1542 if ( thisCache ) { | |
1543 delete thisCache[ name ]; | |
1544 | |
1545 // If there is no data left in the cache, we want to continue | |
1546 // and let the cache object itself get destroyed | |
1547 if ( !isEmptyDataObject(thisCache) ) { | |
1548 return; | |
1549 } | |
1550 } | |
1551 } | |
1552 | |
1553 // See jQuery.data for more information | |
1554 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 ]; | |
1571 } else { | |
1572 cache[ id ] = null; | |
1573 } | |
1574 | |
1575 // We destroyed the entire user cache at once because it's faster than | |
1576 // iterating through each key, but we need to continue to persist internal | |
1577 // data if it existed | |
1578 if ( internalCache ) { | |
1579 cache[ id ] = {}; | |
1580 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery | |
1581 // metadata on plain JS objects when the object is serialized using | |
1582 // JSON.stringify | |
1583 if ( !isNode ) { | |
1584 cache[ id ].toJSON = jQuery.noop; | |
1585 } | |
1586 | |
1587 cache[ id ][ internalKey ] = internalCache; | |
1588 | |
1589 // Otherwise, we need to eliminate the expando on the node to avoid | |
1590 // false lookups in the cache for entries that no longer exist | |
1591 } else if ( isNode ) { | |
1592 // IE does not allow us to delete expando properties from nodes, | |
1593 // nor does it have a removeAttribute function on Document nodes; | |
1594 // we must handle all of these cases | |
1595 if ( jQuery.support.deleteExpando ) { | |
1596 delete elem[ jQuery.expando ]; | |
1597 } else if ( elem.removeAttribute ) { | |
1598 elem.removeAttribute( jQuery.expando ); | |
1599 } else { | |
1600 elem[ jQuery.expando ] = null; | |
1601 } | |
1602 } | |
1603 }, | |
1604 | |
1605 // For internal use only. | |
1606 _data: function( elem, name, data ) { | |
1607 return jQuery.data( elem, name, data, true ); | |
1608 }, | |
1609 | |
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; | |
1621 } | |
1622 }); | |
1623 | |
1624 jQuery.fn.extend({ | |
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 | |
1654 var parts = key.split("."); | |
1655 parts[1] = parts[1] ? "." + parts[1] : ""; | |
1656 | |
1657 if ( value === undefined ) { | |
1658 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); | |
1659 | |
1660 // Try to fetch any internally stored data first | |
1661 if ( data === undefined && this.length ) { | |
1662 data = jQuery.data( this[0], key ); | |
1663 data = dataAttr( this[0], key, data ); | |
1664 } | |
1665 | |
1666 return data === undefined && parts[1] ? | |
1667 this.data( parts[0] ) : | |
1668 data; | |
1669 | |
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 ); | |
1676 jQuery.data( this, key, value ); | |
1677 $this.triggerHandler( "changeData" + parts[1] + "!", args ); | |
1678 }); | |
1679 } | |
1680 }, | |
1681 | |
1682 removeData: function( key ) { | |
1683 return this.each(function() { | |
1684 jQuery.removeData( this, key ); | |
1685 }); | |
1686 } | |
1687 }); | |
1688 | |
1689 function 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 | |
1721 function 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 | |
1734 function 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 | |
1754 jQuery.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 | |
1829 jQuery.fn.extend({ | |
1830 queue: function( type, data ) { | |
1831 if ( typeof type !== "string" ) { | |
1832 data = type; | |
1833 type = "fx"; | |
1834 } | |
1835 | |
1836 if ( data === undefined ) { | |
1837 return jQuery.queue( this[0], type ); | |
1838 } | |
1839 return this.each(function() { | |
1840 var queue = jQuery.queue( this, type, data ); | |
1841 | |
1842 if ( type === "fx" && queue[0] !== "inprogress" ) { | |
1843 jQuery.dequeue( this, type ); | |
1844 } | |
1845 }); | |
1846 }, | |
1847 dequeue: function( type ) { | |
1848 return this.each(function() { | |
1849 jQuery.dequeue( this, type ); | |
1850 }); | |
1851 }, | |
1852 // Based off of the plugin by Clint Helfers, with permission. | |
1853 // http://blindsignals.com/index.php/2009/07/jquery-delay/ | |
1854 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 | |
1906 var 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 | |
1916 jQuery.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 | |
2120 jQuery.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 | |
2399 boolHook = { | |
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 | |
2427 if ( !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 | |
2469 if ( !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 | |
2480 if ( !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 | |
2495 if ( !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 | |
2513 if ( !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 } | |
2523 jQuery.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 | |
2536 var 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 */ | |
2550 jQuery.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 | |
3087 jQuery.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 | |
3099 jQuery.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 | |
3133 function returnFalse() { | |
3134 return false; | |
3135 } | |
3136 function 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 | |
3142 jQuery.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 | |
3185 var 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. | |
3211 delegate = function( event ) { | |
3212 event.type = event.data; | |
3213 jQuery.event.handle.apply( this, arguments ); | |
3214 }; | |
3215 | |
3216 // Create mouseenter and mouseleave events | |
3217 jQuery.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 | |
3232 if ( !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. | |
3268 if ( !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 | |
3378 function 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 | |
3394 if ( !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 | |
3427 jQuery.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 | |
3467 jQuery.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 | |
3540 var liveMap = { | |
3541 focus: "focusin", | |
3542 blur: "focusout", | |
3543 mouseenter: "mouseover", | |
3544 mouseleave: "mouseout" | |
3545 }; | |
3546 | |
3547 jQuery.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 | |
3617 function 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 | |
3705 function liveConvert( type, selector ) { | |
3706 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); | |
3707 } | |
3708 | |
3709 jQuery.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 | |
3735 * Released under the MIT, BSD, and GPL Licenses. | |
3736 * More information: http://sizzlejs.com/ | |
3737 */ | |
3738 (function(){ | |
3739 | |
3740 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, | |
3741 done = 0, | |
3742 toString = Object.prototype.toString, | |
3743 hasDuplicate = false, | |
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 | |
3757 var Sizzle = function( selector, context, results, seed ) { | |
3758 results = results || []; | |
3759 context = context || document; | |
3760 | |
3761 var origContext = context; | |
3762 | |
3763 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { | |
3764 return []; | |
3765 } | |
3766 | |
3767 if ( !selector || typeof selector !== "string" ) { | |
3768 return results; | |
3769 } | |
3770 | |
3771 var m, set, checkSet, extra, ret, cur, pop, i, | |
3772 prune = true, | |
3773 contextXML = Sizzle.isXML( context ), | |
3774 parts = [], | |
3775 soFar = selector; | |
3776 | |
3777 // Reset the position of the chunker regexp (start from head) | |
3778 do { | |
3779 chunker.exec( "" ); | |
3780 m = chunker.exec( soFar ); | |
3781 | |
3782 if ( m ) { | |
3783 soFar = m[3]; | |
3784 | |
3785 parts.push( m[1] ); | |
3786 | |
3787 if ( m[2] ) { | |
3788 extra = m[3]; | |
3789 break; | |
3790 } | |
3791 } | |
3792 } while ( m ); | |
3793 | |
3794 if ( parts.length > 1 && origPOS.exec( selector ) ) { | |
3795 | |
3796 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { | |
3797 set = posProcess( parts[0] + parts[1], context ); | |
3798 | |
3799 } else { | |
3800 set = Expr.relative[ parts[0] ] ? | |
3801 [ context ] : | |
3802 Sizzle( parts.shift(), context ); | |
3803 | |
3804 while ( parts.length ) { | |
3805 selector = parts.shift(); | |
3806 | |
3807 if ( Expr.relative[ selector ] ) { | |
3808 selector += parts.shift(); | |
3809 } | |
3810 | |
3811 set = posProcess( selector, set ); | |
3812 } | |
3813 } | |
3814 | |
3815 } else { | |
3816 // Take a shortcut and set the context if the root selector is an ID | |
3817 // (but not if it'll be faster if the inner selector is an ID) | |
3818 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && | |
3819 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { | |
3820 | |
3821 ret = Sizzle.find( parts.shift(), context, contextXML ); | |
3822 context = ret.expr ? | |
3823 Sizzle.filter( ret.expr, ret.set )[0] : | |
3824 ret.set[0]; | |
3825 } | |
3826 | |
3827 if ( context ) { | |
3828 ret = seed ? | |
3829 { expr: parts.pop(), set: makeArray(seed) } : | |
3830 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); | |
3831 | |
3832 set = ret.expr ? | |
3833 Sizzle.filter( ret.expr, ret.set ) : | |
3834 ret.set; | |
3835 | |
3836 if ( parts.length > 0 ) { | |
3837 checkSet = makeArray( set ); | |
3838 | |
3839 } else { | |
3840 prune = false; | |
3841 } | |
3842 | |
3843 while ( parts.length ) { | |
3844 cur = parts.pop(); | |
3845 pop = cur; | |
3846 | |
3847 if ( !Expr.relative[ cur ] ) { | |
3848 cur = ""; | |
3849 } else { | |
3850 pop = parts.pop(); | |
3851 } | |
3852 | |
3853 if ( pop == null ) { | |
3854 pop = context; | |
3855 } | |
3856 | |
3857 Expr.relative[ cur ]( checkSet, pop, contextXML ); | |
3858 } | |
3859 | |
3860 } else { | |
3861 checkSet = parts = []; | |
3862 } | |
3863 } | |
3864 | |
3865 if ( !checkSet ) { | |
3866 checkSet = set; | |
3867 } | |
3868 | |
3869 if ( !checkSet ) { | |
3870 Sizzle.error( cur || selector ); | |
3871 } | |
3872 | |
3873 if ( toString.call(checkSet) === "[object Array]" ) { | |
3874 if ( !prune ) { | |
3875 results.push.apply( results, checkSet ); | |
3876 | |
3877 } else if ( context && context.nodeType === 1 ) { | |
3878 for ( i = 0; checkSet[i] != null; i++ ) { | |
3879 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { | |
3880 results.push( set[i] ); | |
3881 } | |
3882 } | |
3883 | |
3884 } else { | |
3885 for ( i = 0; checkSet[i] != null; i++ ) { | |
3886 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { | |
3887 results.push( set[i] ); | |
3888 } | |
3889 } | |
3890 } | |
3891 | |
3892 } else { | |
3893 makeArray( checkSet, results ); | |
3894 } | |
3895 | |
3896 if ( extra ) { | |
3897 Sizzle( extra, origContext, results, seed ); | |
3898 Sizzle.uniqueSort( results ); | |
3899 } | |
3900 | |
3901 return results; | |
3902 }; | |
3903 | |
3904 Sizzle.uniqueSort = function( results ) { | |
3905 if ( sortOrder ) { | |
3906 hasDuplicate = baseHasDuplicate; | |
3907 results.sort( sortOrder ); | |
3908 | |
3909 if ( hasDuplicate ) { | |
3910 for ( var i = 1; i < results.length; i++ ) { | |
3911 if ( results[i] === results[ i - 1 ] ) { | |
3912 results.splice( i--, 1 ); | |
3913 } | |
3914 } | |
3915 } | |
3916 } | |
3917 | |
3918 return results; | |
3919 }; | |
3920 | |
3921 Sizzle.matches = function( expr, set ) { | |
3922 return Sizzle( expr, null, null, set ); | |
3923 }; | |
3924 | |
3925 Sizzle.matchesSelector = function( node, expr ) { | |
3926 return Sizzle( expr, null, null, [node] ).length > 0; | |
3927 }; | |
3928 | |
3929 Sizzle.find = function( expr, context, isXML ) { | |
3930 var set; | |
3931 | |
3932 if ( !expr ) { | |
3933 return []; | |
3934 } | |
3935 | |
3936 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { | |
3937 var match, | |
3938 type = Expr.order[i]; | |
3939 | |
3940 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { | |
3941 var left = match[1]; | |
3942 match.splice( 1, 1 ); | |
3943 | |
3944 if ( left.substr( left.length - 1 ) !== "\\" ) { | |
3945 match[1] = (match[1] || "").replace( rBackslash, "" ); | |
3946 set = Expr.find[ type ]( match, context, isXML ); | |
3947 | |
3948 if ( set != null ) { | |
3949 expr = expr.replace( Expr.match[ type ], "" ); | |
3950 break; | |
3951 } | |
3952 } | |
3953 } | |
3954 } | |
3955 | |
3956 if ( !set ) { | |
3957 set = typeof context.getElementsByTagName !== "undefined" ? | |
3958 context.getElementsByTagName( "*" ) : | |
3959 []; | |
3960 } | |
3961 | |
3962 return { set: set, expr: expr }; | |
3963 }; | |
3964 | |
3965 Sizzle.filter = function( expr, set, inplace, not ) { | |
3966 var match, anyFound, | |
3967 old = expr, | |
3968 result = [], | |
3969 curLoop = set, | |
3970 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); | |
3971 | |
3972 while ( expr && set.length ) { | |
3973 for ( var type in Expr.filter ) { | |
3974 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { | |
3975 var found, item, | |
3976 filter = Expr.filter[ type ], | |
3977 left = match[1]; | |
3978 | |
3979 anyFound = false; | |
3980 | |
3981 match.splice(1,1); | |
3982 | |
3983 if ( left.substr( left.length - 1 ) === "\\" ) { | |
3984 continue; | |
3985 } | |
3986 | |
3987 if ( curLoop === result ) { | |
3988 result = []; | |
3989 } | |
3990 | |
3991 if ( Expr.preFilter[ type ] ) { | |
3992 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); | |
3993 | |
3994 if ( !match ) { | |
3995 anyFound = found = true; | |
3996 | |
3997 } else if ( match === true ) { | |
3998 continue; | |
3999 } | |
4000 } | |
4001 | |
4002 if ( match ) { | |
4003 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { | |
4004 if ( item ) { | |
4005 found = filter( item, match, i, curLoop ); | |
4006 var pass = not ^ !!found; | |
4007 | |
4008 if ( inplace && found != null ) { | |
4009 if ( pass ) { | |
4010 anyFound = true; | |
4011 | |
4012 } else { | |
4013 curLoop[i] = false; | |
4014 } | |
4015 | |
4016 } else if ( pass ) { | |
4017 result.push( item ); | |
4018 anyFound = true; | |
4019 } | |
4020 } | |
4021 } | |
4022 } | |
4023 | |
4024 if ( found !== undefined ) { | |
4025 if ( !inplace ) { | |
4026 curLoop = result; | |
4027 } | |
4028 | |
4029 expr = expr.replace( Expr.match[ type ], "" ); | |
4030 | |
4031 if ( !anyFound ) { | |
4032 return []; | |
4033 } | |
4034 | |
4035 break; | |
4036 } | |
4037 } | |
4038 } | |
4039 | |
4040 // Improper expression | |
4041 if ( expr === old ) { | |
4042 if ( anyFound == null ) { | |
4043 Sizzle.error( expr ); | |
4044 | |
4045 } else { | |
4046 break; | |
4047 } | |
4048 } | |
4049 | |
4050 old = expr; | |
4051 } | |
4052 | |
4053 return curLoop; | |
4054 }; | |
4055 | |
4056 Sizzle.error = function( msg ) { | |
4057 throw "Syntax error, unrecognized expression: " + msg; | |
4058 }; | |
4059 | |
4060 var Expr = Sizzle.selectors = { | |
4061 order: [ "ID", "NAME", "TAG" ], | |
4062 | |
4063 match: { | |
4064 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, | |
4065 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, | |
4066 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, | |
4067 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, | |
4068 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, | |
4069 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, | |
4070 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, | |
4071 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ | |
4072 }, | |
4073 | |
4074 leftMatch: {}, | |
4075 | |
4076 attrMap: { | |
4077 "class": "className", | |
4078 "for": "htmlFor" | |
4079 }, | |
4080 | |
4081 attrHandle: { | |
4082 href: function( elem ) { | |
4083 return elem.getAttribute( "href" ); | |
4084 }, | |
4085 type: function( elem ) { | |
4086 return elem.getAttribute( "type" ); | |
4087 } | |
4088 }, | |
4089 | |
4090 relative: { | |
4091 "+": function(checkSet, part){ | |
4092 var isPartStr = typeof part === "string", | |
4093 isTag = isPartStr && !rNonWord.test( part ), | |
4094 isPartStrNotTag = isPartStr && !isTag; | |
4095 | |
4096 if ( isTag ) { | |
4097 part = part.toLowerCase(); | |
4098 } | |
4099 | |
4100 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { | |
4101 if ( (elem = checkSet[i]) ) { | |
4102 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} | |
4103 | |
4104 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? | |
4105 elem || false : | |
4106 elem === part; | |
4107 } | |
4108 } | |
4109 | |
4110 if ( isPartStrNotTag ) { | |
4111 Sizzle.filter( part, checkSet, true ); | |
4112 } | |
4113 }, | |
4114 | |
4115 ">": function( checkSet, part ) { | |
4116 var elem, | |
4117 isPartStr = typeof part === "string", | |
4118 i = 0, | |
4119 l = checkSet.length; | |
4120 | |
4121 if ( isPartStr && !rNonWord.test( part ) ) { | |
4122 part = part.toLowerCase(); | |
4123 | |
4124 for ( ; i < l; i++ ) { | |
4125 elem = checkSet[i]; | |
4126 | |
4127 if ( elem ) { | |
4128 var parent = elem.parentNode; | |
4129 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; | |
4130 } | |
4131 } | |
4132 | |
4133 } else { | |
4134 for ( ; i < l; i++ ) { | |
4135 elem = checkSet[i]; | |
4136 | |
4137 if ( elem ) { | |
4138 checkSet[i] = isPartStr ? | |
4139 elem.parentNode : | |
4140 elem.parentNode === part; | |
4141 } | |
4142 } | |
4143 | |
4144 if ( isPartStr ) { | |
4145 Sizzle.filter( part, checkSet, true ); | |
4146 } | |
4147 } | |
4148 }, | |
4149 | |
4150 "": function(checkSet, part, isXML){ | |
4151 var nodeCheck, | |
4152 doneName = done++, | |
4153 checkFn = dirCheck; | |
4154 | |
4155 if ( typeof part === "string" && !rNonWord.test( part ) ) { | |
4156 part = part.toLowerCase(); | |
4157 nodeCheck = part; | |
4158 checkFn = dirNodeCheck; | |
4159 } | |
4160 | |
4161 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); | |
4162 }, | |
4163 | |
4164 "~": function( checkSet, part, isXML ) { | |
4165 var nodeCheck, | |
4166 doneName = done++, | |
4167 checkFn = dirCheck; | |
4168 | |
4169 if ( typeof part === "string" && !rNonWord.test( part ) ) { | |
4170 part = part.toLowerCase(); | |
4171 nodeCheck = part; | |
4172 checkFn = dirNodeCheck; | |
4173 } | |
4174 | |
4175 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); | |
4176 } | |
4177 }, | |
4178 | |
4179 find: { | |
4180 ID: function( match, context, isXML ) { | |
4181 if ( typeof context.getElementById !== "undefined" && !isXML ) { | |
4182 var m = context.getElementById(match[1]); | |
4183 // Check parentNode to catch when Blackberry 4.6 returns | |
4184 // nodes that are no longer in the document #6963 | |
4185 return m && m.parentNode ? [m] : []; | |
4186 } | |
4187 }, | |
4188 | |
4189 NAME: function( match, context ) { | |
4190 if ( typeof context.getElementsByName !== "undefined" ) { | |
4191 var ret = [], | |
4192 results = context.getElementsByName( match[1] ); | |
4193 | |
4194 for ( var i = 0, l = results.length; i < l; i++ ) { | |
4195 if ( results[i].getAttribute("name") === match[1] ) { | |
4196 ret.push( results[i] ); | |
4197 } | |
4198 } | |
4199 | |
4200 return ret.length === 0 ? null : ret; | |
4201 } | |
4202 }, | |
4203 | |
4204 TAG: function( match, context ) { | |
4205 if ( typeof context.getElementsByTagName !== "undefined" ) { | |
4206 return context.getElementsByTagName( match[1] ); | |
4207 } | |
4208 } | |
4209 }, | |
4210 preFilter: { | |
4211 CLASS: function( match, curLoop, inplace, result, not, isXML ) { | |
4212 match = " " + match[1].replace( rBackslash, "" ) + " "; | |
4213 | |
4214 if ( isXML ) { | |
4215 return match; | |
4216 } | |
4217 | |
4218 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { | |
4219 if ( elem ) { | |
4220 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { | |
4221 if ( !inplace ) { | |
4222 result.push( elem ); | |
4223 } | |
4224 | |
4225 } else if ( inplace ) { | |
4226 curLoop[i] = false; | |
4227 } | |
4228 } | |
4229 } | |
4230 | |
4231 return false; | |
4232 }, | |
4233 | |
4234 ID: function( match ) { | |
4235 return match[1].replace( rBackslash, "" ); | |
4236 }, | |
4237 | |
4238 TAG: function( match, curLoop ) { | |
4239 return match[1].replace( rBackslash, "" ).toLowerCase(); | |
4240 }, | |
4241 | |
4242 CHILD: function( match ) { | |
4243 if ( match[1] === "nth" ) { | |
4244 if ( !match[2] ) { | |
4245 Sizzle.error( match[0] ); | |
4246 } | |
4247 | |
4248 match[2] = match[2].replace(/^\+|\s*/g, ''); | |
4249 | |
4250 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' | |
4251 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( | |
4252 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || | |
4253 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); | |
4254 | |
4255 // calculate the numbers (first)n+(last) including if they are negative | |
4256 match[2] = (test[1] + (test[2] || 1)) - 0; | |
4257 match[3] = test[3] - 0; | |
4258 } | |
4259 else if ( match[2] ) { | |
4260 Sizzle.error( match[0] ); | |
4261 } | |
4262 | |
4263 // TODO: Move to normal caching system | |
4264 match[0] = done++; | |
4265 | |
4266 return match; | |
4267 }, | |
4268 | |
4269 ATTR: function( match, curLoop, inplace, result, not, isXML ) { | |
4270 var name = match[1] = match[1].replace( rBackslash, "" ); | |
4271 | |
4272 if ( !isXML && Expr.attrMap[name] ) { | |
4273 match[1] = Expr.attrMap[name]; | |
4274 } | |
4275 | |
4276 // Handle if an un-quoted value was used | |
4277 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); | |
4278 | |
4279 if ( match[2] === "~=" ) { | |
4280 match[4] = " " + match[4] + " "; | |
4281 } | |
4282 | |
4283 return match; | |
4284 }, | |
4285 | |
4286 PSEUDO: function( match, curLoop, inplace, result, not ) { | |
4287 if ( match[1] === "not" ) { | |
4288 // If we're dealing with a complex expression, or a simple one | |
4289 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { | |
4290 match[3] = Sizzle(match[3], null, null, curLoop); | |
4291 | |
4292 } else { | |
4293 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); | |
4294 | |
4295 if ( !inplace ) { | |
4296 result.push.apply( result, ret ); | |
4297 } | |
4298 | |
4299 return false; | |
4300 } | |
4301 | |
4302 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { | |
4303 return true; | |
4304 } | |
4305 | |
4306 return match; | |
4307 }, | |
4308 | |
4309 POS: function( match ) { | |
4310 match.unshift( true ); | |
4311 | |
4312 return match; | |
4313 } | |
4314 }, | |
4315 | |
4316 filters: { | |
4317 enabled: function( elem ) { | |
4318 return elem.disabled === false && elem.type !== "hidden"; | |
4319 }, | |
4320 | |
4321 disabled: function( elem ) { | |
4322 return elem.disabled === true; | |
4323 }, | |
4324 | |
4325 checked: function( elem ) { | |
4326 return elem.checked === true; | |
4327 }, | |
4328 | |
4329 selected: function( elem ) { | |
4330 // Accessing this property makes selected-by-default | |
4331 // options in Safari work properly | |
4332 if ( elem.parentNode ) { | |
4333 elem.parentNode.selectedIndex; | |
4334 } | |
4335 | |
4336 return elem.selected === true; | |
4337 }, | |
4338 | |
4339 parent: function( elem ) { | |
4340 return !!elem.firstChild; | |
4341 }, | |
4342 | |
4343 empty: function( elem ) { | |
4344 return !elem.firstChild; | |
4345 }, | |
4346 | |
4347 has: function( elem, i, match ) { | |
4348 return !!Sizzle( match[3], elem ).length; | |
4349 }, | |
4350 | |
4351 header: function( elem ) { | |
4352 return (/h\d/i).test( elem.nodeName ); | |
4353 }, | |
4354 | |
4355 text: function( elem ) { | |
4356 var attr = elem.getAttribute( "type" ), type = elem.type; | |
4357 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) | |
4358 // use getAttribute instead to test this case | |
4359 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); | |
4360 }, | |
4361 | |
4362 radio: function( elem ) { | |
4363 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; | |
4364 }, | |
4365 | |
4366 checkbox: function( elem ) { | |
4367 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; | |
4368 }, | |
4369 | |
4370 file: function( elem ) { | |
4371 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; | |
4372 }, | |
4373 | |
4374 password: function( elem ) { | |
4375 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; | |
4376 }, | |
4377 | |
4378 submit: function( elem ) { | |
4379 var name = elem.nodeName.toLowerCase(); | |
4380 return (name === "input" || name === "button") && "submit" === elem.type; | |
4381 }, | |
4382 | |
4383 image: function( elem ) { | |
4384 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; | |
4385 }, | |
4386 | |
4387 reset: function( elem ) { | |
4388 var name = elem.nodeName.toLowerCase(); | |
4389 return (name === "input" || name === "button") && "reset" === elem.type; | |
4390 }, | |
4391 | |
4392 button: function( elem ) { | |
4393 var name = elem.nodeName.toLowerCase(); | |
4394 return name === "input" && "button" === elem.type || name === "button"; | |
4395 }, | |
4396 | |
4397 input: function( elem ) { | |
4398 return (/input|select|textarea|button/i).test( elem.nodeName ); | |
4399 }, | |
4400 | |
4401 focus: function( elem ) { | |
4402 return elem === elem.ownerDocument.activeElement; | |
4403 } | |
4404 }, | |
4405 setFilters: { | |
4406 first: function( elem, i ) { | |
4407 return i === 0; | |
4408 }, | |
4409 | |
4410 last: function( elem, i, match, array ) { | |
4411 return i === array.length - 1; | |
4412 }, | |
4413 | |
4414 even: function( elem, i ) { | |
4415 return i % 2 === 0; | |
4416 }, | |
4417 | |
4418 odd: function( elem, i ) { | |
4419 return i % 2 === 1; | |
4420 }, | |
4421 | |
4422 lt: function( elem, i, match ) { | |
4423 return i < match[3] - 0; | |
4424 }, | |
4425 | |
4426 gt: function( elem, i, match ) { | |
4427 return i > match[3] - 0; | |
4428 }, | |
4429 | |
4430 nth: function( elem, i, match ) { | |
4431 return match[3] - 0 === i; | |
4432 }, | |
4433 | |
4434 eq: function( elem, i, match ) { | |
4435 return match[3] - 0 === i; | |
4436 } | |
4437 }, | |
4438 filter: { | |
4439 PSEUDO: function( elem, match, i, array ) { | |
4440 var name = match[1], | |
4441 filter = Expr.filters[ name ]; | |
4442 | |
4443 if ( filter ) { | |
4444 return filter( elem, i, match, array ); | |
4445 | |
4446 } else if ( name === "contains" ) { | |
4447 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; | |
4448 | |
4449 } else if ( name === "not" ) { | |
4450 var not = match[3]; | |
4451 | |
4452 for ( var j = 0, l = not.length; j < l; j++ ) { | |
4453 if ( not[j] === elem ) { | |
4454 return false; | |
4455 } | |
4456 } | |
4457 | |
4458 return true; | |
4459 | |
4460 } else { | |
4461 Sizzle.error( name ); | |
4462 } | |
4463 }, | |
4464 | |
4465 CHILD: function( elem, match ) { | |
4466 var type = match[1], | |
4467 node = elem; | |
4468 | |
4469 switch ( type ) { | |
4470 case "only": | |
4471 case "first": | |
4472 while ( (node = node.previousSibling) ) { | |
4473 if ( node.nodeType === 1 ) { | |
4474 return false; | |
4475 } | |
4476 } | |
4477 | |
4478 if ( type === "first" ) { | |
4479 return true; | |
4480 } | |
4481 | |
4482 node = elem; | |
4483 | |
4484 case "last": | |
4485 while ( (node = node.nextSibling) ) { | |
4486 if ( node.nodeType === 1 ) { | |
4487 return false; | |
4488 } | |
4489 } | |
4490 | |
4491 return true; | |
4492 | |
4493 case "nth": | |
4494 var first = match[2], | |
4495 last = match[3]; | |
4496 | |
4497 if ( first === 1 && last === 0 ) { | |
4498 return true; | |
4499 } | |
4500 | |
4501 var doneName = match[0], | |
4502 parent = elem.parentNode; | |
4503 | |
4504 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { | |
4505 var count = 0; | |
4506 | |
4507 for ( node = parent.firstChild; node; node = node.nextSibling ) { | |
4508 if ( node.nodeType === 1 ) { | |
4509 node.nodeIndex = ++count; | |
4510 } | |
4511 } | |
4512 | |
4513 parent.sizcache = doneName; | |
4514 } | |
4515 | |
4516 var diff = elem.nodeIndex - last; | |
4517 | |
4518 if ( first === 0 ) { | |
4519 return diff === 0; | |
4520 | |
4521 } else { | |
4522 return ( diff % first === 0 && diff / first >= 0 ); | |
4523 } | |
4524 } | |
4525 }, | |
4526 | |
4527 ID: function( elem, match ) { | |
4528 return elem.nodeType === 1 && elem.getAttribute("id") === match; | |
4529 }, | |
4530 | |
4531 TAG: function( elem, match ) { | |
4532 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; | |
4533 }, | |
4534 | |
4535 CLASS: function( elem, match ) { | |
4536 return (" " + (elem.className || elem.getAttribute("class")) + " ") | |
4537 .indexOf( match ) > -1; | |
4538 }, | |
4539 | |
4540 ATTR: function( elem, match ) { | |
4541 var name = match[1], | |
4542 result = Expr.attrHandle[ name ] ? | |
4543 Expr.attrHandle[ name ]( elem ) : | |
4544 elem[ name ] != null ? | |
4545 elem[ name ] : | |
4546 elem.getAttribute( name ), | |
4547 value = result + "", | |
4548 type = match[2], | |
4549 check = match[4]; | |
4550 | |
4551 return result == null ? | |
4552 type === "!=" : | |
4553 type === "=" ? | |
4554 value === check : | |
4555 type === "*=" ? | |
4556 value.indexOf(check) >= 0 : | |
4557 type === "~=" ? | |
4558 (" " + value + " ").indexOf(check) >= 0 : | |
4559 !check ? | |
4560 value && result !== false : | |
4561 type === "!=" ? | |
4562 value !== check : | |
4563 type === "^=" ? | |
4564 value.indexOf(check) === 0 : | |
4565 type === "$=" ? | |
4566 value.substr(value.length - check.length) === check : | |
4567 type === "|=" ? | |
4568 value === check || value.substr(0, check.length + 1) === check + "-" : | |
4569 false; | |
4570 }, | |
4571 | |
4572 POS: function( elem, match, i, array ) { | |
4573 var name = match[2], | |
4574 filter = Expr.setFilters[ name ]; | |
4575 | |
4576 if ( filter ) { | |
4577 return filter( elem, i, match, array ); | |
4578 } | |
4579 } | |
4580 } | |
4581 }; | |
4582 | |
4583 var origPOS = Expr.match.POS, | |
4584 fescape = function(all, num){ | |
4585 return "\\" + (num - 0 + 1); | |
4586 }; | |
4587 | |
4588 for ( var type in Expr.match ) { | |
4589 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); | |
4590 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); | |
4591 } | |
4592 | |
4593 var makeArray = function( array, results ) { | |
4594 array = Array.prototype.slice.call( array, 0 ); | |
4595 | |
4596 if ( results ) { | |
4597 results.push.apply( results, array ); | |
4598 return results; | |
4599 } | |
4600 | |
4601 return array; | |
4602 }; | |
4603 | |
4604 // Perform a simple check to determine if the browser is capable of | |
4605 // converting a NodeList to an array using builtin methods. | |
4606 // Also verifies that the returned array holds DOM nodes | |
4607 // (which is not the case in the Blackberry browser) | |
4608 try { | |
4609 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; | |
4610 | |
4611 // Provide a fallback method if it does not work | |
4612 } catch( e ) { | |
4613 makeArray = function( array, results ) { | |
4614 var i = 0, | |
4615 ret = results || []; | |
4616 | |
4617 if ( toString.call(array) === "[object Array]" ) { | |
4618 Array.prototype.push.apply( ret, array ); | |
4619 | |
4620 } else { | |
4621 if ( typeof array.length === "number" ) { | |
4622 for ( var l = array.length; i < l; i++ ) { | |
4623 ret.push( array[i] ); | |
4624 } | |
4625 | |
4626 } else { | |
4627 for ( ; array[i]; i++ ) { | |
4628 ret.push( array[i] ); | |
4629 } | |
4630 } | |
4631 } | |
4632 | |
4633 return ret; | |
4634 }; | |
4635 } | |
4636 | |
4637 var sortOrder, siblingCheck; | |
4638 | |
4639 if ( document.documentElement.compareDocumentPosition ) { | |
4640 sortOrder = function( a, b ) { | |
4641 if ( a === b ) { | |
4642 hasDuplicate = true; | |
4643 return 0; | |
4644 } | |
4645 | |
4646 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { | |
4647 return a.compareDocumentPosition ? -1 : 1; | |
4648 } | |
4649 | |
4650 return a.compareDocumentPosition(b) & 4 ? -1 : 1; | |
4651 }; | |
4652 | |
4653 } else { | |
4654 sortOrder = function( a, b ) { | |
4655 // The nodes are identical, we can exit early | |
4656 if ( a === b ) { | |
4657 hasDuplicate = true; | |
4658 return 0; | |
4659 | |
4660 // Fallback to using sourceIndex (in IE) if it's available on both nodes | |
4661 } else if ( a.sourceIndex && b.sourceIndex ) { | |
4662 return a.sourceIndex - b.sourceIndex; | |
4663 } | |
4664 | |
4665 var al, bl, | |
4666 ap = [], | |
4667 bp = [], | |
4668 aup = a.parentNode, | |
4669 bup = b.parentNode, | |
4670 cur = aup; | |
4671 | |
4672 // If the nodes are siblings (or identical) we can do a quick check | |
4673 if ( aup === bup ) { | |
4674 return siblingCheck( a, b ); | |
4675 | |
4676 // If no parents were found then the nodes are disconnected | |
4677 } else if ( !aup ) { | |
4678 return -1; | |
4679 | |
4680 } else if ( !bup ) { | |
4681 return 1; | |
4682 } | |
4683 | |
4684 // Otherwise they're somewhere else in the tree so we need | |
4685 // to build up a full list of the parentNodes for comparison | |
4686 while ( cur ) { | |
4687 ap.unshift( cur ); | |
4688 cur = cur.parentNode; | |
4689 } | |
4690 | |
4691 cur = bup; | |
4692 | |
4693 while ( cur ) { | |
4694 bp.unshift( cur ); | |
4695 cur = cur.parentNode; | |
4696 } | |
4697 | |
4698 al = ap.length; | |
4699 bl = bp.length; | |
4700 | |
4701 // Start walking down the tree looking for a discrepancy | |
4702 for ( var i = 0; i < al && i < bl; i++ ) { | |
4703 if ( ap[i] !== bp[i] ) { | |
4704 return siblingCheck( ap[i], bp[i] ); | |
4705 } | |
4706 } | |
4707 | |
4708 // We ended someplace up the tree so do a sibling check | |
4709 return i === al ? | |
4710 siblingCheck( a, bp[i], -1 ) : | |
4711 siblingCheck( ap[i], b, 1 ); | |
4712 }; | |
4713 | |
4714 siblingCheck = function( a, b, ret ) { | |
4715 if ( a === b ) { | |
4716 return ret; | |
4717 } | |
4718 | |
4719 var cur = a.nextSibling; | |
4720 | |
4721 while ( cur ) { | |
4722 if ( cur === b ) { | |
4723 return -1; | |
4724 } | |
4725 | |
4726 cur = cur.nextSibling; | |
4727 } | |
4728 | |
4729 return 1; | |
4730 }; | |
4731 } | |
4732 | |
4733 // Utility function for retreiving the text value of an array of DOM nodes | |
4734 Sizzle.getText = function( elems ) { | |
4735 var ret = "", elem; | |
4736 | |
4737 for ( var i = 0; elems[i]; i++ ) { | |
4738 elem = elems[i]; | |
4739 | |
4740 // Get the text from text nodes and CDATA nodes | |
4741 if ( elem.nodeType === 3 || elem.nodeType === 4 ) { | |
4742 ret += elem.nodeValue; | |
4743 | |
4744 // Traverse everything else, except comment nodes | |
4745 } else if ( elem.nodeType !== 8 ) { | |
4746 ret += Sizzle.getText( elem.childNodes ); | |
4747 } | |
4748 } | |
4749 | |
4750 return ret; | |
4751 }; | |
4752 | |
4753 // Check to see if the browser returns elements by name when | |
4754 // querying by getElementById (and provide a workaround) | |
4755 (function(){ | |
4756 // We're going to inject a fake input element with a specified name | |
4757 var form = document.createElement("div"), | |
4758 id = "script" + (new Date()).getTime(), | |
4759 root = document.documentElement; | |
4760 | |
4761 form.innerHTML = "<a name='" + id + "'/>"; | |
4762 | |
4763 // Inject it into the root element, check its status, and remove it quickly | |
4764 root.insertBefore( form, root.firstChild ); | |
4765 | |
4766 // The workaround has to do additional checks after a getElementById | |
4767 // Which slows things down for other browsers (hence the branching) | |
4768 if ( document.getElementById( id ) ) { | |
4769 Expr.find.ID = function( match, context, isXML ) { | |
4770 if ( typeof context.getElementById !== "undefined" && !isXML ) { | |
4771 var m = context.getElementById(match[1]); | |
4772 | |
4773 return m ? | |
4774 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? | |
4775 [m] : | |
4776 undefined : | |
4777 []; | |
4778 } | |
4779 }; | |
4780 | |
4781 Expr.filter.ID = function( elem, match ) { | |
4782 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); | |
4783 | |
4784 return elem.nodeType === 1 && node && node.nodeValue === match; | |
4785 }; | |
4786 } | |
4787 | |
4788 root.removeChild( form ); | |
4789 | |
4790 // release memory in IE | |
4791 root = form = null; | |
4792 })(); | |
4793 | |
4794 (function(){ | |
4795 // Check to see if the browser returns only elements | |
4796 // when doing getElementsByTagName("*") | |
4797 | |
4798 // Create a fake element | |
4799 var div = document.createElement("div"); | |
4800 div.appendChild( document.createComment("") ); | |
4801 | |
4802 // Make sure no comments are found | |
4803 if ( div.getElementsByTagName("*").length > 0 ) { | |
4804 Expr.find.TAG = function( match, context ) { | |
4805 var results = context.getElementsByTagName( match[1] ); | |
4806 | |
4807 // Filter out possible comments | |
4808 if ( match[1] === "*" ) { | |
4809 var tmp = []; | |
4810 | |
4811 for ( var i = 0; results[i]; i++ ) { | |
4812 if ( results[i].nodeType === 1 ) { | |
4813 tmp.push( results[i] ); | |
4814 } | |
4815 } | |
4816 | |
4817 results = tmp; | |
4818 } | |
4819 | |
4820 return results; | |
4821 }; | |
4822 } | |
4823 | |
4824 // Check to see if an attribute returns normalized href attributes | |
4825 div.innerHTML = "<a href='#'></a>"; | |
4826 | |
4827 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && | |
4828 div.firstChild.getAttribute("href") !== "#" ) { | |
4829 | |
4830 Expr.attrHandle.href = function( elem ) { | |
4831 return elem.getAttribute( "href", 2 ); | |
4832 }; | |
4833 } | |
4834 | |
4835 // release memory in IE | |
4836 div = null; | |
4837 })(); | |
4838 | |
4839 if ( document.querySelectorAll ) { | |
4840 (function(){ | |
4841 var oldSizzle = Sizzle, | |
4842 div = document.createElement("div"), | |
4843 id = "__sizzle__"; | |
4844 | |
4845 div.innerHTML = "<p class='TEST'></p>"; | |
4846 | |
4847 // Safari can't handle uppercase or unicode characters when | |
4848 // in quirks mode. | |
4849 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { | |
4850 return; | |
4851 } | |
4852 | |
4853 Sizzle = function( query, context, extra, seed ) { | |
4854 context = context || document; | |
4855 | |
4856 // Only use querySelectorAll on non-XML documents | |
4857 // (ID selectors don't work in non-HTML documents) | |
4858 if ( !seed && !Sizzle.isXML(context) ) { | |
4859 // See if we find a selector to speed up | |
4860 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); | |
4861 | |
4862 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { | |
4863 // Speed-up: Sizzle("TAG") | |
4864 if ( match[1] ) { | |
4865 return makeArray( context.getElementsByTagName( query ), extra ); | |
4866 | |
4867 // Speed-up: Sizzle(".CLASS") | |
4868 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { | |
4869 return makeArray( context.getElementsByClassName( match[2] ), extra ); | |
4870 } | |
4871 } | |
4872 | |
4873 if ( context.nodeType === 9 ) { | |
4874 // Speed-up: Sizzle("body") | |
4875 // The body element only exists once, optimize finding it | |
4876 if ( query === "body" && context.body ) { | |
4877 return makeArray( [ context.body ], extra ); | |
4878 | |
4879 // Speed-up: Sizzle("#ID") | |
4880 } else if ( match && match[3] ) { | |
4881 var elem = context.getElementById( match[3] ); | |
4882 | |
4883 // Check parentNode to catch when Blackberry 4.6 returns | |
4884 // nodes that are no longer in the document #6963 | |
4885 if ( elem && elem.parentNode ) { | |
4886 // Handle the case where IE and Opera return items | |
4887 // by name instead of ID | |
4888 if ( elem.id === match[3] ) { | |
4889 return makeArray( [ elem ], extra ); | |
4890 } | |
4891 | |
4892 } else { | |
4893 return makeArray( [], extra ); | |
4894 } | |
4895 } | |
4896 | |
4897 try { | |
4898 return makeArray( context.querySelectorAll(query), extra ); | |
4899 } catch(qsaError) {} | |
4900 | |
4901 // qSA works strangely on Element-rooted queries | |
4902 // We can work around this by specifying an extra ID on the root | |
4903 // and working up from there (Thanks to Andrew Dupont for the technique) | |
4904 // IE 8 doesn't work on object elements | |
4905 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { | |
4906 var oldContext = context, | |
4907 old = context.getAttribute( "id" ), | |
4908 nid = old || id, | |
4909 hasParent = context.parentNode, | |
4910 relativeHierarchySelector = /^\s*[+~]/.test( query ); | |
4911 | |
4912 if ( !old ) { | |
4913 context.setAttribute( "id", nid ); | |
4914 } else { | |
4915 nid = nid.replace( /'/g, "\\$&" ); | |
4916 } | |
4917 if ( relativeHierarchySelector && hasParent ) { | |
4918 context = context.parentNode; | |
4919 } | |
4920 | |
4921 try { | |
4922 if ( !relativeHierarchySelector || hasParent ) { | |
4923 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); | |
4924 } | |
4925 | |
4926 } catch(pseudoError) { | |
4927 } finally { | |
4928 if ( !old ) { | |
4929 oldContext.removeAttribute( "id" ); | |
4930 } | |
4931 } | |
4932 } | |
4933 } | |
4934 | |
4935 return oldSizzle(query, context, extra, seed); | |
4936 }; | |
4937 | |
4938 for ( var prop in oldSizzle ) { | |
4939 Sizzle[ prop ] = oldSizzle[ prop ]; | |
4940 } | |
4941 | |
4942 // release memory in IE | |
4943 div = null; | |
4944 })(); | |
4945 } | |
4946 | |
4947 (function(){ | |
4948 var html = document.documentElement, | |
4949 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; | |
4950 | |
4951 if ( matches ) { | |
4952 // Check to see if it's possible to do matchesSelector | |
4953 // on a disconnected node (IE 9 fails this) | |
4954 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), | |
4955 pseudoWorks = false; | |
4956 | |
4957 try { | |
4958 // This should fail with an exception | |
4959 // Gecko does not error, returns false instead | |
4960 matches.call( document.documentElement, "[test!='']:sizzle" ); | |
4961 | |
4962 } catch( pseudoError ) { | |
4963 pseudoWorks = true; | |
4964 } | |
4965 | |
4966 Sizzle.matchesSelector = function( node, expr ) { | |
4967 // Make sure that attribute selectors are quoted | |
4968 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); | |
4969 | |
4970 if ( !Sizzle.isXML( node ) ) { | |
4971 try { | |
4972 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { | |
4973 var ret = matches.call( node, expr ); | |
4974 | |
4975 // IE 9's matchesSelector returns false on disconnected nodes | |
4976 if ( ret || !disconnectedMatch || | |
4977 // As well, disconnected nodes are said to be in a document | |
4978 // fragment in IE 9, so check for that | |
4979 node.document && node.document.nodeType !== 11 ) { | |
4980 return ret; | |
4981 } | |
4982 } | |
4983 } catch(e) {} | |
4984 } | |
4985 | |
4986 return Sizzle(expr, null, null, [node]).length > 0; | |
4987 }; | |
4988 } | |
4989 })(); | |
4990 | |
4991 (function(){ | |
4992 var div = document.createElement("div"); | |
4993 | |
4994 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; | |
4995 | |
4996 // Opera can't find a second classname (in 9.6) | |
4997 // Also, make sure that getElementsByClassName actually exists | |
4998 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { | |
4999 return; | |
5000 } | |
5001 | |
5002 // Safari caches class attributes, doesn't catch changes (in 3.2) | |
5003 div.lastChild.className = "e"; | |
5004 | |
5005 if ( div.getElementsByClassName("e").length === 1 ) { | |
5006 return; | |
5007 } | |
5008 | |
5009 Expr.order.splice(1, 0, "CLASS"); | |
5010 Expr.find.CLASS = function( match, context, isXML ) { | |
5011 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { | |
5012 return context.getElementsByClassName(match[1]); | |
5013 } | |
5014 }; | |
5015 | |
5016 // release memory in IE | |
5017 div = null; | |
5018 })(); | |
5019 | |
5020 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { | |
5021 for ( var i = 0, l = checkSet.length; i < l; i++ ) { | |
5022 var elem = checkSet[i]; | |
5023 | |
5024 if ( elem ) { | |
5025 var match = false; | |
5026 | |
5027 elem = elem[dir]; | |
5028 | |
5029 while ( elem ) { | |
5030 if ( elem.sizcache === doneName ) { | |
5031 match = checkSet[elem.sizset]; | |
5032 break; | |
5033 } | |
5034 | |
5035 if ( elem.nodeType === 1 && !isXML ){ | |
5036 elem.sizcache = doneName; | |
5037 elem.sizset = i; | |
5038 } | |
5039 | |
5040 if ( elem.nodeName.toLowerCase() === cur ) { | |
5041 match = elem; | |
5042 break; | |
5043 } | |
5044 | |
5045 elem = elem[dir]; | |
5046 } | |
5047 | |
5048 checkSet[i] = match; | |
5049 } | |
5050 } | |
5051 } | |
5052 | |
5053 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { | |
5054 for ( var i = 0, l = checkSet.length; i < l; i++ ) { | |
5055 var elem = checkSet[i]; | |
5056 | |
5057 if ( elem ) { | |
5058 var match = false; | |
5059 | |
5060 elem = elem[dir]; | |
5061 | |
5062 while ( elem ) { | |
5063 if ( elem.sizcache === doneName ) { | |
5064 match = checkSet[elem.sizset]; | |
5065 break; | |
5066 } | |
5067 | |
5068 if ( elem.nodeType === 1 ) { | |
5069 if ( !isXML ) { | |
5070 elem.sizcache = doneName; | |
5071 elem.sizset = i; | |
5072 } | |
5073 | |
5074 if ( typeof cur !== "string" ) { | |
5075 if ( elem === cur ) { | |
5076 match = true; | |
5077 break; | |
5078 } | |
5079 | |
5080 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { | |
5081 match = elem; | |
5082 break; | |
5083 } | |
5084 } | |
5085 | |
5086 elem = elem[dir]; | |
5087 } | |
5088 | |
5089 checkSet[i] = match; | |
5090 } | |
5091 } | |
5092 } | |
5093 | |
5094 if ( document.documentElement.contains ) { | |
5095 Sizzle.contains = function( a, b ) { | |
5096 return a !== b && (a.contains ? a.contains(b) : true); | |
5097 }; | |
5098 | |
5099 } else if ( document.documentElement.compareDocumentPosition ) { | |
5100 Sizzle.contains = function( a, b ) { | |
5101 return !!(a.compareDocumentPosition(b) & 16); | |
5102 }; | |
5103 | |
5104 } else { | |
5105 Sizzle.contains = function() { | |
5106 return false; | |
5107 }; | |
5108 } | |
5109 | |
5110 Sizzle.isXML = function( elem ) { | |
5111 // documentElement is verified for cases where it doesn't yet exist | |
5112 // (such as loading iframes in IE - #4833) | |
5113 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; | |
5114 | |
5115 return documentElement ? documentElement.nodeName !== "HTML" : false; | |
5116 }; | |
5117 | |
5118 var posProcess = function( selector, context ) { | |
5119 var match, | |
5120 tmpSet = [], | |
5121 later = "", | |
5122 root = context.nodeType ? [context] : context; | |
5123 | |
5124 // Position selectors must be done after the filter | |
5125 // And so must :not(positional) so we move all PSEUDOs to the end | |
5126 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { | |
5127 later += match[0]; | |
5128 selector = selector.replace( Expr.match.PSEUDO, "" ); | |
5129 } | |
5130 | |
5131 selector = Expr.relative[selector] ? selector + "*" : selector; | |
5132 | |
5133 for ( var i = 0, l = root.length; i < l; i++ ) { | |
5134 Sizzle( selector, root[i], tmpSet ); | |
5135 } | |
5136 | |
5137 return Sizzle.filter( later, tmpSet ); | |
5138 }; | |
5139 | |
5140 // EXPOSE | |
5141 jQuery.find = Sizzle; | |
5142 jQuery.expr = Sizzle.selectors; | |
5143 jQuery.expr[":"] = jQuery.expr.filters; | |
5144 jQuery.unique = Sizzle.uniqueSort; | |
5145 jQuery.text = Sizzle.getText; | |
5146 jQuery.isXMLDoc = Sizzle.isXML; | |
5147 jQuery.contains = Sizzle.contains; | |
5148 | |
5149 | |
5150 })(); | |
5151 | |
5152 | |
5153 var runtil = /Until$/, | |
5154 rparentsprev = /^(?:parents|prevUntil|prevAll)/, | |
5155 // Note: This RegExp should be improved, or likely pulled from Sizzle | |
5156 rmultiselector = /,/, | |
5157 isSimple = /^.[^:#\[\.,]*$/, | |
5158 slice = Array.prototype.slice, | |
5159 POS = jQuery.expr.match.POS, | |
5160 // methods guaranteed to produce a unique set when starting from a unique set | |
5161 guaranteedUnique = { | |
5162 children: true, | |
5163 contents: true, | |
5164 next: true, | |
5165 prev: true | |
5166 }; | |
5167 | |
5168 jQuery.fn.extend({ | |
5169 find: function( selector ) { | |
5170 var self = this, | |
5171 i, l; | |
5172 | |
5173 if ( typeof selector !== "string" ) { | |
5174 return jQuery( selector ).filter(function() { | |
5175 for ( i = 0, l = self.length; i < l; i++ ) { | |
5176 if ( jQuery.contains( self[ i ], this ) ) { | |
5177 return true; | |
5178 } | |
5179 } | |
5180 }); | |
5181 } | |
5182 | |
5183 var ret = this.pushStack( "", "find", selector ), | |
5184 length, n, r; | |
5185 | |
5186 for ( i = 0, l = this.length; i < l; i++ ) { | |
5187 length = ret.length; | |
5188 jQuery.find( selector, this[i], ret ); | |
5189 | |
5190 if ( i > 0 ) { | |
5191 // Make sure that the results are unique | |
5192 for ( n = length; n < ret.length; n++ ) { | |
5193 for ( r = 0; r < length; r++ ) { | |
5194 if ( ret[r] === ret[n] ) { | |
5195 ret.splice(n--, 1); | |
5196 break; | |
5197 } | |
5198 } | |
5199 } | |
5200 } | |
5201 } | |
5202 | |
5203 return ret; | |
5204 }, | |
5205 | |
5206 has: function( target ) { | |
5207 var targets = jQuery( target ); | |
5208 return this.filter(function() { | |
5209 for ( var i = 0, l = targets.length; i < l; i++ ) { | |
5210 if ( jQuery.contains( this, targets[i] ) ) { | |
5211 return true; | |
5212 } | |
5213 } | |
5214 }); | |
5215 }, | |
5216 | |
5217 not: function( selector ) { | |
5218 return this.pushStack( winnow(this, selector, false), "not", selector); | |
5219 }, | |
5220 | |
5221 filter: function( selector ) { | |
5222 return this.pushStack( winnow(this, selector, true), "filter", selector ); | |
5223 }, | |
5224 | |
5225 is: function( selector ) { | |
5226 return !!selector && ( typeof selector === "string" ? | |
5227 jQuery.filter( selector, this ).length > 0 : | |
5228 this.filter( selector ).length > 0 ); | |
5229 }, | |
5230 | |
5231 closest: function( selectors, context ) { | |
5232 var ret = [], i, l, cur = this[0]; | |
5233 | |
5234 // Array | |
5235 if ( jQuery.isArray( selectors ) ) { | |
5236 var match, selector, | |
5237 matches = {}, | |
5238 level = 1; | |
5239 | |
5240 if ( cur && selectors.length ) { | |
5241 for ( i = 0, l = selectors.length; i < l; i++ ) { | |
5242 selector = selectors[i]; | |
5243 | |
5244 if ( !matches[ selector ] ) { | |
5245 matches[ selector ] = POS.test( selector ) ? | |
5246 jQuery( selector, context || this.context ) : | |
5247 selector; | |
5248 } | |
5249 } | |
5250 | |
5251 while ( cur && cur.ownerDocument && cur !== context ) { | |
5252 for ( selector in matches ) { | |
5253 match = matches[ selector ]; | |
5254 | |
5255 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { | |
5256 ret.push({ selector: selector, elem: cur, level: level }); | |
5257 } | |
5258 } | |
5259 | |
5260 cur = cur.parentNode; | |
5261 level++; | |
5262 } | |
5263 } | |
5264 | |
5265 return ret; | |
5266 } | |
5267 | |
5268 // String | |
5269 var pos = POS.test( selectors ) || typeof selectors !== "string" ? | |
5270 jQuery( selectors, context || this.context ) : | |
5271 0; | |
5272 | |
5273 for ( i = 0, l = this.length; i < l; i++ ) { | |
5274 cur = this[i]; | |
5275 | |
5276 while ( cur ) { | |
5277 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { | |
5278 ret.push( cur ); | |
5279 break; | |
5280 | |
5281 } else { | |
5282 cur = cur.parentNode; | |
5283 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { | |
5284 break; | |
5285 } | |
5286 } | |
5287 } | |
5288 } | |
5289 | |
5290 ret = ret.length > 1 ? jQuery.unique( ret ) : ret; | |
5291 | |
5292 return this.pushStack( ret, "closest", selectors ); | |
5293 }, | |
5294 | |
5295 // Determine the position of an element within | |
5296 // the matched set of elements | |
5297 index: function( elem ) { | |
5298 if ( !elem || typeof elem === "string" ) { | |
5299 return jQuery.inArray( this[0], | |
5300 // If it receives a string, the selector is used | |
5301 // If it receives nothing, the siblings are used | |
5302 elem ? jQuery( elem ) : this.parent().children() ); | |
5303 } | |
5304 // Locate the position of the desired element | |
5305 return jQuery.inArray( | |
5306 // If it receives a jQuery object, the first element is used | |
5307 elem.jquery ? elem[0] : elem, this ); | |
5308 }, | |
5309 | |
5310 add: function( selector, context ) { | |
5311 var set = typeof selector === "string" ? | |
5312 jQuery( selector, context ) : | |
5313 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), | |
5314 all = jQuery.merge( this.get(), set ); | |
5315 | |
5316 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? | |
5317 all : | |
5318 jQuery.unique( all ) ); | |
5319 }, | |
5320 | |
5321 andSelf: function() { | |
5322 return this.add( this.prevObject ); | |
5323 } | |
5324 }); | |
5325 | |
5326 // A painfully simple check to see if an element is disconnected | |
5327 // from a document (should be improved, where feasible). | |
5328 function isDisconnected( node ) { | |
5329 return !node || !node.parentNode || node.parentNode.nodeType === 11; | |
5330 } | |
5331 | |
5332 jQuery.each({ | |
5333 parent: function( elem ) { | |
5334 var parent = elem.parentNode; | |
5335 return parent && parent.nodeType !== 11 ? parent : null; | |
5336 }, | |
5337 parents: function( elem ) { | |
5338 return jQuery.dir( elem, "parentNode" ); | |
5339 }, | |
5340 parentsUntil: function( elem, i, until ) { | |
5341 return jQuery.dir( elem, "parentNode", until ); | |
5342 }, | |
5343 next: function( elem ) { | |
5344 return jQuery.nth( elem, 2, "nextSibling" ); | |
5345 }, | |
5346 prev: function( elem ) { | |
5347 return jQuery.nth( elem, 2, "previousSibling" ); | |
5348 }, | |
5349 nextAll: function( elem ) { | |
5350 return jQuery.dir( elem, "nextSibling" ); | |
5351 }, | |
5352 prevAll: function( elem ) { | |
5353 return jQuery.dir( elem, "previousSibling" ); | |
5354 }, | |
5355 nextUntil: function( elem, i, until ) { | |
5356 return jQuery.dir( elem, "nextSibling", until ); | |
5357 }, | |
5358 prevUntil: function( elem, i, until ) { | |
5359 return jQuery.dir( elem, "previousSibling", until ); | |
5360 }, | |
5361 siblings: function( elem ) { | |
5362 return jQuery.sibling( elem.parentNode.firstChild, elem ); | |
5363 }, | |
5364 children: function( elem ) { | |
5365 return jQuery.sibling( elem.firstChild ); | |
5366 }, | |
5367 contents: function( elem ) { | |
5368 return jQuery.nodeName( elem, "iframe" ) ? | |
5369 elem.contentDocument || elem.contentWindow.document : | |
5370 jQuery.makeArray( elem.childNodes ); | |
5371 } | |
5372 }, function( name, fn ) { | |
5373 jQuery.fn[ name ] = function( until, selector ) { | |
5374 var ret = jQuery.map( this, fn, until ), | |
5375 // The variable 'args' was introduced in | |
5376 // https://github.com/jquery/jquery/commit/52a0238 | |
5377 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. | |
5378 // http://code.google.com/p/v8/issues/detail?id=1050 | |
5379 args = slice.call(arguments); | |
5380 | |
5381 if ( !runtil.test( name ) ) { | |
5382 selector = until; | |
5383 } | |
5384 | |
5385 if ( selector && typeof selector === "string" ) { | |
5386 ret = jQuery.filter( selector, ret ); | |
5387 } | |
5388 | |
5389 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; | |
5390 | |
5391 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { | |
5392 ret = ret.reverse(); | |
5393 } | |
5394 | |
5395 return this.pushStack( ret, name, args.join(",") ); | |
5396 }; | |
5397 }); | |
5398 | |
5399 jQuery.extend({ | |
5400 filter: function( expr, elems, not ) { | |
5401 if ( not ) { | |
5402 expr = ":not(" + expr + ")"; | |
5403 } | |
5404 | |
5405 return elems.length === 1 ? | |
5406 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : | |
5407 jQuery.find.matches(expr, elems); | |
5408 }, | |
5409 | |
5410 dir: function( elem, dir, until ) { | |
5411 var matched = [], | |
5412 cur = elem[ dir ]; | |
5413 | |
5414 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { | |
5415 if ( cur.nodeType === 1 ) { | |
5416 matched.push( cur ); | |
5417 } | |
5418 cur = cur[dir]; | |
5419 } | |
5420 return matched; | |
5421 }, | |
5422 | |
5423 nth: function( cur, result, dir, elem ) { | |
5424 result = result || 1; | |
5425 var num = 0; | |
5426 | |
5427 for ( ; cur; cur = cur[dir] ) { | |
5428 if ( cur.nodeType === 1 && ++num === result ) { | |
5429 break; | |
5430 } | |
5431 } | |
5432 | |
5433 return cur; | |
5434 }, | |
5435 | |
5436 sibling: function( n, elem ) { | |
5437 var r = []; | |
5438 | |
5439 for ( ; n; n = n.nextSibling ) { | |
5440 if ( n.nodeType === 1 && n !== elem ) { | |
5441 r.push( n ); | |
5442 } | |
5443 } | |
5444 | |
5445 return r; | |
5446 } | |
5447 }); | |
5448 | |
5449 // Implement the identical functionality for filter and not | |
5450 function winnow( elements, qualifier, keep ) { | |
5451 | |
5452 // Can't pass null or undefined to indexOf in Firefox 4 | |
5453 // Set to 0 to skip string check | |
5454 qualifier = qualifier || 0; | |
5455 | |
5456 if ( jQuery.isFunction( qualifier ) ) { | |
5457 return jQuery.grep(elements, function( elem, i ) { | |
5458 var retVal = !!qualifier.call( elem, i, elem ); | |
5459 return retVal === keep; | |
5460 }); | |
5461 | |
5462 } else if ( qualifier.nodeType ) { | |
5463 return jQuery.grep(elements, function( elem, i ) { | |
5464 return (elem === qualifier) === keep; | |
5465 }); | |
5466 | |
5467 } else if ( typeof qualifier === "string" ) { | |
5468 var filtered = jQuery.grep(elements, function( elem ) { | |
5469 return elem.nodeType === 1; | |
5470 }); | |
5471 | |
5472 if ( isSimple.test( qualifier ) ) { | |
5473 return jQuery.filter(qualifier, filtered, !keep); | |
5474 } else { | |
5475 qualifier = jQuery.filter( qualifier, filtered ); | |
5476 } | |
5477 } | |
5478 | |
5479 return jQuery.grep(elements, function( elem, i ) { | |
5480 return (jQuery.inArray( elem, qualifier ) >= 0) === keep; | |
5481 }); | |
5482 } | |
5483 | |
5484 | |
5485 | |
5486 | |
5487 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, | |
5488 rleadingWhitespace = /^\s+/, | |
5489 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, | |
5490 rtagName = /<([\w:]+)/, | |
5491 rtbody = /<tbody/i, | |
5492 rhtml = /<|&#?\w+;/, | |
5493 rnocache = /<(?:script|object|embed|option|style)/i, | |
5494 // checked="checked" or checked | |
5495 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, | |
5496 rscriptType = /\/(java|ecma)script/i, | |
5497 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/, | |
5498 wrapMap = { | |
5499 option: [ 1, "<select multiple='multiple'>", "</select>" ], | |
5500 legend: [ 1, "<fieldset>", "</fieldset>" ], | |
5501 thead: [ 1, "<table>", "</table>" ], | |
5502 tr: [ 2, "<table><tbody>", "</tbody></table>" ], | |
5503 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], | |
5504 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], | |
5505 area: [ 1, "<map>", "</map>" ], | |
5506 _default: [ 0, "", "" ] | |
5507 }; | |
5508 | |
5509 wrapMap.optgroup = wrapMap.option; | |
5510 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; | |
5511 wrapMap.th = wrapMap.td; | |
5512 | |
5513 // IE can't serialize <link> and <script> tags normally | |
5514 if ( !jQuery.support.htmlSerialize ) { | |
5515 wrapMap._default = [ 1, "div<div>", "</div>" ]; | |
5516 } | |
5517 | |
5518 jQuery.fn.extend({ | |
5519 text: function( text ) { | |
5520 if ( jQuery.isFunction(text) ) { | |
5521 return this.each(function(i) { | |
5522 var self = jQuery( this ); | |
5523 | |
5524 self.text( text.call(this, i, self.text()) ); | |
5525 }); | |
5526 } | |
5527 | |
5528 if ( typeof text !== "object" && text !== undefined ) { | |
5529 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); | |
5530 } | |
5531 | |
5532 return jQuery.text( this ); | |
5533 }, | |
5534 | |
5535 wrapAll: function( html ) { | |
5536 if ( jQuery.isFunction( html ) ) { | |
5537 return this.each(function(i) { | |
5538 jQuery(this).wrapAll( html.call(this, i) ); | |
5539 }); | |
5540 } | |
5541 | |
5542 if ( this[0] ) { | |
5543 // The elements to wrap the target around | |
5544 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); | |
5545 | |
5546 if ( this[0].parentNode ) { | |
5547 wrap.insertBefore( this[0] ); | |
5548 } | |
5549 | |
5550 wrap.map(function() { | |
5551 var elem = this; | |
5552 | |
5553 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { | |
5554 elem = elem.firstChild; | |
5555 } | |
5556 | |
5557 return elem; | |
5558 }).append( this ); | |
5559 } | |
5560 | |
5561 return this; | |
5562 }, | |
5563 | |
5564 wrapInner: function( html ) { | |
5565 if ( jQuery.isFunction( html ) ) { | |
5566 return this.each(function(i) { | |
5567 jQuery(this).wrapInner( html.call(this, i) ); | |
5568 }); | |
5569 } | |
5570 | |
5571 return this.each(function() { | |
5572 var self = jQuery( this ), | |
5573 contents = self.contents(); | |
5574 | |
5575 if ( contents.length ) { | |
5576 contents.wrapAll( html ); | |
5577 | |
5578 } else { | |
5579 self.append( html ); | |
5580 } | |
5581 }); | |
5582 }, | |
5583 | |
5584 wrap: function( html ) { | |
5585 return this.each(function() { | |
5586 jQuery( this ).wrapAll( html ); | |
5587 }); | |
5588 }, | |
5589 | |
5590 unwrap: function() { | |
5591 return this.parent().each(function() { | |
5592 if ( !jQuery.nodeName( this, "body" ) ) { | |
5593 jQuery( this ).replaceWith( this.childNodes ); | |
5594 } | |
5595 }).end(); | |
5596 }, | |
5597 | |
5598 append: function() { | |
5599 return this.domManip(arguments, true, function( elem ) { | |
5600 if ( this.nodeType === 1 ) { | |
5601 this.appendChild( elem ); | |
5602 } | |
5603 }); | |
5604 }, | |
5605 | |
5606 prepend: function() { | |
5607 return this.domManip(arguments, true, function( elem ) { | |
5608 if ( this.nodeType === 1 ) { | |
5609 this.insertBefore( elem, this.firstChild ); | |
5610 } | |
5611 }); | |
5612 }, | |
5613 | |
5614 before: function() { | |
5615 if ( this[0] && this[0].parentNode ) { | |
5616 return this.domManip(arguments, false, function( elem ) { | |
5617 this.parentNode.insertBefore( elem, this ); | |
5618 }); | |
5619 } else if ( arguments.length ) { | |
5620 var set = jQuery(arguments[0]); | |
5621 set.push.apply( set, this.toArray() ); | |
5622 return this.pushStack( set, "before", arguments ); | |
5623 } | |
5624 }, | |
5625 | |
5626 after: function() { | |
5627 if ( this[0] && this[0].parentNode ) { | |
5628 return this.domManip(arguments, false, function( elem ) { | |
5629 this.parentNode.insertBefore( elem, this.nextSibling ); | |
5630 }); | |
5631 } else if ( arguments.length ) { | |
5632 var set = this.pushStack( this, "after", arguments ); | |
5633 set.push.apply( set, jQuery(arguments[0]).toArray() ); | |
5634 return set; | |
5635 } | |
5636 }, | |
5637 | |
5638 // keepData is for internal use only--do not document | |
5639 remove: function( selector, keepData ) { | |
5640 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { | |
5641 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { | |
5642 if ( !keepData && elem.nodeType === 1 ) { | |
5643 jQuery.cleanData( elem.getElementsByTagName("*") ); | |
5644 jQuery.cleanData( [ elem ] ); | |
5645 } | |
5646 | |
5647 if ( elem.parentNode ) { | |
5648 elem.parentNode.removeChild( elem ); | |
5649 } | |
5650 } | |
5651 } | |
5652 | |
5653 return this; | |
5654 }, | |
5655 | |
5656 empty: function() { | |
5657 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { | |
5658 // Remove element nodes and prevent memory leaks | |
5659 if ( elem.nodeType === 1 ) { | |
5660 jQuery.cleanData( elem.getElementsByTagName("*") ); | |
5661 } | |
5662 | |
5663 // Remove any remaining nodes | |
5664 while ( elem.firstChild ) { | |
5665 elem.removeChild( elem.firstChild ); | |
5666 } | |
5667 } | |
5668 | |
5669 return this; | |
5670 }, | |
5671 | |
5672 clone: function( dataAndEvents, deepDataAndEvents ) { | |
5673 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; | |
5674 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; | |
5675 | |
5676 return this.map( function () { | |
5677 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); | |
5678 }); | |
5679 }, | |
5680 | |
5681 html: function( value ) { | |
5682 if ( value === undefined ) { | |
5683 return this[0] && this[0].nodeType === 1 ? | |
5684 this[0].innerHTML.replace(rinlinejQuery, "") : | |
5685 null; | |
5686 | |
5687 // See if we can take a shortcut and just use innerHTML | |
5688 } else if ( typeof value === "string" && !rnocache.test( value ) && | |
5689 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && | |
5690 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { | |
5691 | |
5692 value = value.replace(rxhtmlTag, "<$1></$2>"); | |
5693 | |
5694 try { | |
5695 for ( var i = 0, l = this.length; i < l; i++ ) { | |
5696 // Remove element nodes and prevent memory leaks | |
5697 if ( this[i].nodeType === 1 ) { | |
5698 jQuery.cleanData( this[i].getElementsByTagName("*") ); | |
5699 this[i].innerHTML = value; | |
5700 } | |
5701 } | |
5702 | |
5703 // If using innerHTML throws an exception, use the fallback method | |
5704 } catch(e) { | |
5705 this.empty().append( value ); | |
5706 } | |
5707 | |
5708 } else if ( jQuery.isFunction( value ) ) { | |
5709 this.each(function(i){ | |
5710 var self = jQuery( this ); | |
5711 | |
5712 self.html( value.call(this, i, self.html()) ); | |
5713 }); | |
5714 | |
5715 } else { | |
5716 this.empty().append( value ); | |
5717 } | |
5718 | |
5719 return this; | |
5720 }, | |
5721 | |
5722 replaceWith: function( value ) { | |
5723 if ( this[0] && this[0].parentNode ) { | |
5724 // Make sure that the elements are removed from the DOM before they are inserted | |
5725 // this can help fix replacing a parent with child elements | |
5726 if ( jQuery.isFunction( value ) ) { | |
5727 return this.each(function(i) { | |
5728 var self = jQuery(this), old = self.html(); | |
5729 self.replaceWith( value.call( this, i, old ) ); | |
5730 }); | |
5731 } | |
5732 | |
5733 if ( typeof value !== "string" ) { | |
5734 value = jQuery( value ).detach(); | |
5735 } | |
5736 | |
5737 return this.each(function() { | |
5738 var next = this.nextSibling, | |
5739 parent = this.parentNode; | |
5740 | |
5741 jQuery( this ).remove(); | |
5742 | |
5743 if ( next ) { | |
5744 jQuery(next).before( value ); | |
5745 } else { | |
5746 jQuery(parent).append( value ); | |
5747 } | |
5748 }); | |
5749 } else { | |
5750 return this.length ? | |
5751 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : | |
5752 this; | |
5753 } | |
5754 }, | |
5755 | |
5756 detach: function( selector ) { | |
5757 return this.remove( selector, true ); | |
5758 }, | |
5759 | |
5760 domManip: function( args, table, callback ) { | |
5761 var results, first, fragment, parent, | |
5762 value = args[0], | |
5763 scripts = []; | |
5764 | |
5765 // We can't cloneNode fragments that contain checked, in WebKit | |
5766 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { | |
5767 return this.each(function() { | |
5768 jQuery(this).domManip( args, table, callback, true ); | |
5769 }); | |
5770 } | |
5771 | |
5772 if ( jQuery.isFunction(value) ) { | |
5773 return this.each(function(i) { | |
5774 var self = jQuery(this); | |
5775 args[0] = value.call(this, i, table ? self.html() : undefined); | |
5776 self.domManip( args, table, callback ); | |
5777 }); | |
5778 } | |
5779 | |
5780 if ( this[0] ) { | |
5781 parent = value && value.parentNode; | |
5782 | |
5783 // If we're in a fragment, just use that instead of building a new one | |
5784 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { | |
5785 results = { fragment: parent }; | |
5786 | |
5787 } else { | |
5788 results = jQuery.buildFragment( args, this, scripts ); | |
5789 } | |
5790 | |
5791 fragment = results.fragment; | |
5792 | |
5793 if ( fragment.childNodes.length === 1 ) { | |
5794 first = fragment = fragment.firstChild; | |
5795 } else { | |
5796 first = fragment.firstChild; | |
5797 } | |
5798 | |
5799 if ( first ) { | |
5800 table = table && jQuery.nodeName( first, "tr" ); | |
5801 | |
5802 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { | |
5803 callback.call( | |
5804 table ? | |
5805 root(this[i], first) : | |
5806 this[i], | |
5807 // Make sure that we do not leak memory by inadvertently discarding | |
5808 // the original fragment (which might have attached data) instead of | |
5809 // using it; in addition, use the original fragment object for the last | |
5810 // item instead of first because it can end up being emptied incorrectly | |
5811 // in certain situations (Bug #8070). | |
5812 // Fragments from the fragment cache must always be cloned and never used | |
5813 // in place. | |
5814 results.cacheable || (l > 1 && i < lastIndex) ? | |
5815 jQuery.clone( fragment, true, true ) : | |
5816 fragment | |
5817 ); | |
5818 } | |
5819 } | |
5820 | |
5821 if ( scripts.length ) { | |
5822 jQuery.each( scripts, evalScript ); | |
5823 } | |
5824 } | |
5825 | |
5826 return this; | |
5827 } | |
5828 }); | |
5829 | |
5830 function root( elem, cur ) { | |
5831 return jQuery.nodeName(elem, "table") ? | |
5832 (elem.getElementsByTagName("tbody")[0] || | |
5833 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : | |
5834 elem; | |
5835 } | |
5836 | |
5837 function cloneCopyEvent( src, dest ) { | |
5838 | |
5839 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { | |
5840 return; | |
5841 } | |
5842 | |
5843 var internalKey = jQuery.expando, | |
5844 oldData = jQuery.data( src ), | |
5845 curData = jQuery.data( dest, oldData ); | |
5846 | |
5847 // Switch to use the internal data object, if it exists, for the next | |
5848 // stage of data copying | |
5849 if ( (oldData = oldData[ internalKey ]) ) { | |
5850 var events = oldData.events; | |
5851 curData = curData[ internalKey ] = jQuery.extend({}, oldData); | |
5852 | |
5853 if ( events ) { | |
5854 delete curData.handle; | |
5855 curData.events = {}; | |
5856 | |
5857 for ( var type in events ) { | |
5858 for ( var i = 0, l = events[ type ].length; i < l; i++ ) { | |
5859 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); | |
5860 } | |
5861 } | |
5862 } | |
5863 } | |
5864 } | |
5865 | |
5866 function cloneFixAttributes( src, dest ) { | |
5867 var nodeName; | |
5868 | |
5869 // We do not need to do anything for non-Elements | |
5870 if ( dest.nodeType !== 1 ) { | |
5871 return; | |
5872 } | |
5873 | |
5874 // clearAttributes removes the attributes, which we don't want, | |
5875 // but also removes the attachEvent events, which we *do* want | |
5876 if ( dest.clearAttributes ) { | |
5877 dest.clearAttributes(); | |
5878 } | |
5879 | |
5880 // mergeAttributes, in contrast, only merges back on the | |
5881 // original attributes, not the events | |
5882 if ( dest.mergeAttributes ) { | |
5883 dest.mergeAttributes( src ); | |
5884 } | |
5885 | |
5886 nodeName = dest.nodeName.toLowerCase(); | |
5887 | |
5888 // IE6-8 fail to clone children inside object elements that use | |
5889 // the proprietary classid attribute value (rather than the type | |
5890 // attribute) to identify the type of content to display | |
5891 if ( nodeName === "object" ) { | |
5892 dest.outerHTML = src.outerHTML; | |
5893 | |
5894 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { | |
5895 // IE6-8 fails to persist the checked state of a cloned checkbox | |
5896 // or radio button. Worse, IE6-7 fail to give the cloned element | |
5897 // a checked appearance if the defaultChecked value isn't also set | |
5898 if ( src.checked ) { | |
5899 dest.defaultChecked = dest.checked = src.checked; | |
5900 } | |
5901 | |
5902 // IE6-7 get confused and end up setting the value of a cloned | |
5903 // checkbox/radio button to an empty string instead of "on" | |
5904 if ( dest.value !== src.value ) { | |
5905 dest.value = src.value; | |
5906 } | |
5907 | |
5908 // IE6-8 fails to return the selected option to the default selected | |
5909 // state when cloning options | |
5910 } else if ( nodeName === "option" ) { | |
5911 dest.selected = src.defaultSelected; | |
5912 | |
5913 // IE6-8 fails to set the defaultValue to the correct value when | |
5914 // cloning other types of input fields | |
5915 } else if ( nodeName === "input" || nodeName === "textarea" ) { | |
5916 dest.defaultValue = src.defaultValue; | |
5917 } | |
5918 | |
5919 // Event data gets referenced instead of copied if the expando | |
5920 // gets copied too | |
5921 dest.removeAttribute( jQuery.expando ); | |
5922 } | |
5923 | |
5924 jQuery.buildFragment = function( args, nodes, scripts ) { | |
5925 var fragment, cacheable, cacheresults, doc; | |
5926 | |
5927 // nodes may contain either an explicit document object, | |
5928 // a jQuery collection or context object. | |
5929 // If nodes[0] contains a valid object to assign to doc | |
5930 if ( nodes && nodes[0] ) { | |
5931 doc = nodes[0].ownerDocument || nodes[0]; | |
5932 } | |
5933 | |
5934 // Ensure that an attr object doesn't incorrectly stand in as a document object | |
5935 // Chrome and Firefox seem to allow this to occur and will throw exception | |
5936 // Fixes #8950 | |
5937 if ( !doc.createDocumentFragment ) { | |
5938 doc = document; | |
5939 } | |
5940 | |
5941 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document | |
5942 // Cloning options loses the selected state, so don't cache them | |
5943 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment | |
5944 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache | |
5945 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document && | |
5946 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { | |
5947 | |
5948 cacheable = true; | |
5949 | |
5950 cacheresults = jQuery.fragments[ args[0] ]; | |
5951 if ( cacheresults && cacheresults !== 1 ) { | |
5952 fragment = cacheresults; | |
5953 } | |
5954 } | |
5955 | |
5956 if ( !fragment ) { | |
5957 fragment = doc.createDocumentFragment(); | |
5958 jQuery.clean( args, doc, fragment, scripts ); | |
5959 } | |
5960 | |
5961 if ( cacheable ) { | |
5962 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1; | |
5963 } | |
5964 | |
5965 return { fragment: fragment, cacheable: cacheable }; | |
5966 }; | |
5967 | |
5968 jQuery.fragments = {}; | |
5969 | |
5970 jQuery.each({ | |
5971 appendTo: "append", | |
5972 prependTo: "prepend", | |
5973 insertBefore: "before", | |
5974 insertAfter: "after", | |
5975 replaceAll: "replaceWith" | |
5976 }, function( name, original ) { | |
5977 jQuery.fn[ name ] = function( selector ) { | |
5978 var ret = [], | |
5979 insert = jQuery( selector ), | |
5980 parent = this.length === 1 && this[0].parentNode; | |
5981 | |
5982 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { | |
5983 insert[ original ]( this[0] ); | |
5984 return this; | |
5985 | |
5986 } else { | |
5987 for ( var i = 0, l = insert.length; i < l; i++ ) { | |
5988 var elems = (i > 0 ? this.clone(true) : this).get(); | |
5989 jQuery( insert[i] )[ original ]( elems ); | |
5990 ret = ret.concat( elems ); | |
5991 } | |
5992 | |
5993 return this.pushStack( ret, name, insert.selector ); | |
5994 } | |
5995 }; | |
5996 }); | |
5997 | |
5998 function getAll( elem ) { | |
5999 if ( "getElementsByTagName" in elem ) { | |
6000 return elem.getElementsByTagName( "*" ); | |
6001 | |
6002 } else if ( "querySelectorAll" in elem ) { | |
6003 return elem.querySelectorAll( "*" ); | |
6004 | |
6005 } else { | |
6006 return []; | |
6007 } | |
6008 } | |
6009 | |
6010 // Used in clean, fixes the defaultChecked property | |
6011 function fixDefaultChecked( elem ) { | |
6012 if ( elem.type === "checkbox" || elem.type === "radio" ) { | |
6013 elem.defaultChecked = elem.checked; | |
6014 } | |
6015 } | |
6016 // Finds all inputs and passes them to fixDefaultChecked | |
6017 function findInputs( elem ) { | |
6018 if ( jQuery.nodeName( elem, "input" ) ) { | |
6019 fixDefaultChecked( elem ); | |
6020 } else if ( "getElementsByTagName" in elem ) { | |
6021 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); | |
6022 } | |
6023 } | |
6024 | |
6025 jQuery.extend({ | |
6026 clone: function( elem, dataAndEvents, deepDataAndEvents ) { | |
6027 var clone = elem.cloneNode(true), | |
6028 srcElements, | |
6029 destElements, | |
6030 i; | |
6031 | |
6032 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && | |
6033 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { | |
6034 // IE copies events bound via attachEvent when using cloneNode. | |
6035 // Calling detachEvent on the clone will also remove the events | |
6036 // from the original. In order to get around this, we use some | |
6037 // proprietary methods to clear the events. Thanks to MooTools | |
6038 // guys for this hotness. | |
6039 | |
6040 cloneFixAttributes( elem, clone ); | |
6041 | |
6042 // Using Sizzle here is crazy slow, so we use getElementsByTagName | |
6043 // instead | |
6044 srcElements = getAll( elem ); | |
6045 destElements = getAll( clone ); | |
6046 | |
6047 // Weird iteration because IE will replace the length property | |
6048 // with an element if you are cloning the body and one of the | |
6049 // elements on the page has a name or id of "length" | |
6050 for ( i = 0; srcElements[i]; ++i ) { | |
6051 cloneFixAttributes( srcElements[i], destElements[i] ); | |
6052 } | |
6053 } | |
6054 | |
6055 // Copy the events from the original to the clone | |
6056 if ( dataAndEvents ) { | |
6057 cloneCopyEvent( elem, clone ); | |
6058 | |
6059 if ( deepDataAndEvents ) { | |
6060 srcElements = getAll( elem ); | |
6061 destElements = getAll( clone ); | |
6062 | |
6063 for ( i = 0; srcElements[i]; ++i ) { | |
6064 cloneCopyEvent( srcElements[i], destElements[i] ); | |
6065 } | |
6066 } | |
6067 } | |
6068 | |
6069 srcElements = destElements = null; | |
6070 | |
6071 // Return the cloned set | |
6072 return clone; | |
6073 }, | |
6074 | |
6075 clean: function( elems, context, fragment, scripts ) { | |
6076 var checkScriptType; | |
6077 | |
6078 context = context || document; | |
6079 | |
6080 // !context.createElement fails in IE with an error but returns typeof 'object' | |
6081 if ( typeof context.createElement === "undefined" ) { | |
6082 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; | |
6083 } | |
6084 | |
6085 var ret = [], j; | |
6086 | |
6087 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
6088 if ( typeof elem === "number" ) { | |
6089 elem += ""; | |
6090 } | |
6091 | |
6092 if ( !elem ) { | |
6093 continue; | |
6094 } | |
6095 | |
6096 // Convert html string into DOM nodes | |
6097 if ( typeof elem === "string" ) { | |
6098 if ( !rhtml.test( elem ) ) { | |
6099 elem = context.createTextNode( elem ); | |
6100 } else { | |
6101 // Fix "XHTML"-style tags in all browsers | |
6102 elem = elem.replace(rxhtmlTag, "<$1></$2>"); | |
6103 | |
6104 // Trim whitespace, otherwise indexOf won't work as expected | |
6105 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), | |
6106 wrap = wrapMap[ tag ] || wrapMap._default, | |
6107 depth = wrap[0], | |
6108 div = context.createElement("div"); | |
6109 | |
6110 // Go to html and back, then peel off extra wrappers | |
6111 div.innerHTML = wrap[1] + elem + wrap[2]; | |
6112 | |
6113 // Move to the right depth | |
6114 while ( depth-- ) { | |
6115 div = div.lastChild; | |
6116 } | |
6117 | |
6118 // Remove IE's autoinserted <tbody> from table fragments | |
6119 if ( !jQuery.support.tbody ) { | |
6120 | |
6121 // String was a <table>, *may* have spurious <tbody> | |
6122 var hasBody = rtbody.test(elem), | |
6123 tbody = tag === "table" && !hasBody ? | |
6124 div.firstChild && div.firstChild.childNodes : | |
6125 | |
6126 // String was a bare <thead> or <tfoot> | |
6127 wrap[1] === "<table>" && !hasBody ? | |
6128 div.childNodes : | |
6129 []; | |
6130 | |
6131 for ( j = tbody.length - 1; j >= 0 ; --j ) { | |
6132 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { | |
6133 tbody[ j ].parentNode.removeChild( tbody[ j ] ); | |
6134 } | |
6135 } | |
6136 } | |
6137 | |
6138 // IE completely kills leading whitespace when innerHTML is used | |
6139 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { | |
6140 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); | |
6141 } | |
6142 | |
6143 elem = div.childNodes; | |
6144 } | |
6145 } | |
6146 | |
6147 // Resets defaultChecked for any radios and checkboxes | |
6148 // about to be appended to the DOM in IE 6/7 (#8060) | |
6149 var len; | |
6150 if ( !jQuery.support.appendChecked ) { | |
6151 if ( elem[0] && typeof (len = elem.length) === "number" ) { | |
6152 for ( j = 0; j < len; j++ ) { | |
6153 findInputs( elem[j] ); | |
6154 } | |
6155 } else { | |
6156 findInputs( elem ); | |
6157 } | |
6158 } | |
6159 | |
6160 if ( elem.nodeType ) { | |
6161 ret.push( elem ); | |
6162 } else { | |
6163 ret = jQuery.merge( ret, elem ); | |
6164 } | |
6165 } | |
6166 | |
6167 if ( fragment ) { | |
6168 checkScriptType = function( elem ) { | |
6169 return !elem.type || rscriptType.test( elem.type ); | |
6170 }; | |
6171 for ( i = 0; ret[i]; i++ ) { | |
6172 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { | |
6173 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); | |
6174 | |
6175 } else { | |
6176 if ( ret[i].nodeType === 1 ) { | |
6177 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); | |
6178 | |
6179 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); | |
6180 } | |
6181 fragment.appendChild( ret[i] ); | |
6182 } | |
6183 } | |
6184 } | |
6185 | |
6186 return ret; | |
6187 }, | |
6188 | |
6189 cleanData: function( elems ) { | |
6190 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special, | |
6191 deleteExpando = jQuery.support.deleteExpando; | |
6192 | |
6193 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
6194 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { | |
6195 continue; | |
6196 } | |
6197 | |
6198 id = elem[ jQuery.expando ]; | |
6199 | |
6200 if ( id ) { | |
6201 data = cache[ id ] && cache[ id ][ internalKey ]; | |
6202 | |
6203 if ( data && data.events ) { | |
6204 for ( var type in data.events ) { | |
6205 if ( special[ type ] ) { | |
6206 jQuery.event.remove( elem, type ); | |
6207 | |
6208 // This is a shortcut to avoid jQuery.event.remove's overhead | |
6209 } else { | |
6210 jQuery.removeEvent( elem, type, data.handle ); | |
6211 } | |
6212 } | |
6213 | |
6214 // Null the DOM reference to avoid IE6/7/8 leak (#7054) | |
6215 if ( data.handle ) { | |
6216 data.handle.elem = null; | |
6217 } | |
6218 } | |
6219 | |
6220 if ( deleteExpando ) { | |
6221 delete elem[ jQuery.expando ]; | |
6222 | |
6223 } else if ( elem.removeAttribute ) { | |
6224 elem.removeAttribute( jQuery.expando ); | |
6225 } | |
6226 | |
6227 delete cache[ id ]; | |
6228 } | |
6229 } | |
6230 } | |
6231 }); | |
6232 | |
6233 function evalScript( i, elem ) { | |
6234 if ( elem.src ) { | |
6235 jQuery.ajax({ | |
6236 url: elem.src, | |
6237 async: false, | |
6238 dataType: "script" | |
6239 }); | |
6240 } else { | |
6241 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); | |
6242 } | |
6243 | |
6244 if ( elem.parentNode ) { | |
6245 elem.parentNode.removeChild( elem ); | |
6246 } | |
6247 } | |
6248 | |
6249 | |
6250 | |
6251 var ralpha = /alpha\([^)]*\)/i, | |
6252 ropacity = /opacity=([^)]*)/, | |
6253 // fixed for IE9, see #8346 | |
6254 rupper = /([A-Z]|^ms)/g, | |
6255 rnumpx = /^-?\d+(?:px)?$/i, | |
6256 rnum = /^-?\d/, | |
6257 rrelNum = /^[+\-]=/, | |
6258 rrelNumFilter = /[^+\-\.\de]+/g, | |
6259 | |
6260 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, | |
6261 cssWidth = [ "Left", "Right" ], | |
6262 cssHeight = [ "Top", "Bottom" ], | |
6263 curCSS, | |
6264 | |
6265 getComputedStyle, | |
6266 currentStyle; | |
6267 | |
6268 jQuery.fn.css = function( name, value ) { | |
6269 // Setting 'undefined' is a no-op | |
6270 if ( arguments.length === 2 && value === undefined ) { | |
6271 return this; | |
6272 } | |
6273 | |
6274 return jQuery.access( this, name, value, true, function( elem, name, value ) { | |
6275 return value !== undefined ? | |
6276 jQuery.style( elem, name, value ) : | |
6277 jQuery.css( elem, name ); | |
6278 }); | |
6279 }; | |
6280 | |
6281 jQuery.extend({ | |
6282 // Add in style property hooks for overriding the default | |
6283 // behavior of getting and setting a style property | |
6284 cssHooks: { | |
6285 opacity: { | |
6286 get: function( elem, computed ) { | |
6287 if ( computed ) { | |
6288 // We should always get a number back from opacity | |
6289 var ret = curCSS( elem, "opacity", "opacity" ); | |
6290 return ret === "" ? "1" : ret; | |
6291 | |
6292 } else { | |
6293 return elem.style.opacity; | |
6294 } | |
6295 } | |
6296 } | |
6297 }, | |
6298 | |
6299 // Exclude the following css properties to add px | |
6300 cssNumber: { | |
6301 "fillOpacity": true, | |
6302 "fontWeight": true, | |
6303 "lineHeight": true, | |
6304 "opacity": true, | |
6305 "orphans": true, | |
6306 "widows": true, | |
6307 "zIndex": true, | |
6308 "zoom": true | |
6309 }, | |
6310 | |
6311 // Add in properties whose names you wish to fix before | |
6312 // setting or getting the value | |
6313 cssProps: { | |
6314 // normalize float css property | |
6315 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" | |
6316 }, | |
6317 | |
6318 // Get and set the style property on a DOM Node | |
6319 style: function( elem, name, value, extra ) { | |
6320 // Don't set styles on text and comment nodes | |
6321 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { | |
6322 return; | |
6323 } | |
6324 | |
6325 // Make sure that we're working with the right name | |
6326 var ret, type, origName = jQuery.camelCase( name ), | |
6327 style = elem.style, hooks = jQuery.cssHooks[ origName ]; | |
6328 | |
6329 name = jQuery.cssProps[ origName ] || origName; | |
6330 | |
6331 // Check if we're setting a value | |
6332 if ( value !== undefined ) { | |
6333 type = typeof value; | |
6334 | |
6335 // Make sure that NaN and null values aren't set. See: #7116 | |
6336 if ( type === "number" && isNaN( value ) || value == null ) { | |
6337 return; | |
6338 } | |
6339 | |
6340 // convert relative number strings (+= or -=) to relative numbers. #7345 | |
6341 if ( type === "string" && rrelNum.test( value ) ) { | |
6342 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) ); | |
6343 // Fixes bug #9237 | |
6344 type = "number"; | |
6345 } | |
6346 | |
6347 // If a number was passed in, add 'px' to the (except for certain CSS properties) | |
6348 if ( type === "number" && !jQuery.cssNumber[ origName ] ) { | |
6349 value += "px"; | |
6350 } | |
6351 | |
6352 // If a hook was provided, use that value, otherwise just set the specified value | |
6353 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { | |
6354 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided | |
6355 // Fixes bug #5509 | |
6356 try { | |
6357 style[ name ] = value; | |
6358 } catch(e) {} | |
6359 } | |
6360 | |
6361 } else { | |
6362 // If a hook was provided get the non-computed value from there | |
6363 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { | |
6364 return ret; | |
6365 } | |
6366 | |
6367 // Otherwise just get the value from the style object | |
6368 return style[ name ]; | |
6369 } | |
6370 }, | |
6371 | |
6372 css: function( elem, name, extra ) { | |
6373 var ret, hooks; | |
6374 | |
6375 // Make sure that we're working with the right name | |
6376 name = jQuery.camelCase( name ); | |
6377 hooks = jQuery.cssHooks[ name ]; | |
6378 name = jQuery.cssProps[ name ] || name; | |
6379 | |
6380 // cssFloat needs a special treatment | |
6381 if ( name === "cssFloat" ) { | |
6382 name = "float"; | |
6383 } | |
6384 | |
6385 // If a hook was provided get the computed value from there | |
6386 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { | |
6387 return ret; | |
6388 | |
6389 // Otherwise, if a way to get the computed value exists, use that | |
6390 } else if ( curCSS ) { | |
6391 return curCSS( elem, name ); | |
6392 } | |
6393 }, | |
6394 | |
6395 // A method for quickly swapping in/out CSS properties to get correct calculations | |
6396 swap: function( elem, options, callback ) { | |
6397 var old = {}; | |
6398 | |
6399 // Remember the old values, and insert the new ones | |
6400 for ( var name in options ) { | |
6401 old[ name ] = elem.style[ name ]; | |
6402 elem.style[ name ] = options[ name ]; | |
6403 } | |
6404 | |
6405 callback.call( elem ); | |
6406 | |
6407 // Revert the old values | |
6408 for ( name in options ) { | |
6409 elem.style[ name ] = old[ name ]; | |
6410 } | |
6411 } | |
6412 }); | |
6413 | |
6414 // DEPRECATED, Use jQuery.css() instead | |
6415 jQuery.curCSS = jQuery.css; | |
6416 | |
6417 jQuery.each(["height", "width"], function( i, name ) { | |
6418 jQuery.cssHooks[ name ] = { | |
6419 get: function( elem, computed, extra ) { | |
6420 var val; | |
6421 | |
6422 if ( computed ) { | |
6423 if ( elem.offsetWidth !== 0 ) { | |
6424 return getWH( elem, name, extra ); | |
6425 } else { | |
6426 jQuery.swap( elem, cssShow, function() { | |
6427 val = getWH( elem, name, extra ); | |
6428 }); | |
6429 } | |
6430 | |
6431 return val; | |
6432 } | |
6433 }, | |
6434 | |
6435 set: function( elem, value ) { | |
6436 if ( rnumpx.test( value ) ) { | |
6437 // ignore negative width and height values #1599 | |
6438 value = parseFloat( value ); | |
6439 | |
6440 if ( value >= 0 ) { | |
6441 return value + "px"; | |
6442 } | |
6443 | |
6444 } else { | |
6445 return value; | |
6446 } | |
6447 } | |
6448 }; | |
6449 }); | |
6450 | |
6451 if ( !jQuery.support.opacity ) { | |
6452 jQuery.cssHooks.opacity = { | |
6453 get: function( elem, computed ) { | |
6454 // IE uses filters for opacity | |
6455 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? | |
6456 ( parseFloat( RegExp.$1 ) / 100 ) + "" : | |
6457 computed ? "1" : ""; | |
6458 }, | |
6459 | |
6460 set: function( elem, value ) { | |
6461 var style = elem.style, | |
6462 currentStyle = elem.currentStyle; | |
6463 | |
6464 // IE has trouble with opacity if it does not have layout | |
6465 // Force it by setting the zoom level | |
6466 style.zoom = 1; | |
6467 | |
6468 // Set the alpha filter to set the opacity | |
6469 var opacity = jQuery.isNaN( value ) ? | |
6470 "" : | |
6471 "alpha(opacity=" + value * 100 + ")", | |
6472 filter = currentStyle && currentStyle.filter || style.filter || ""; | |
6473 | |
6474 style.filter = ralpha.test( filter ) ? | |
6475 filter.replace( ralpha, opacity ) : | |
6476 filter + " " + opacity; | |
6477 } | |
6478 }; | |
6479 } | |
6480 | |
6481 jQuery(function() { | |
6482 // This hook cannot be added until DOM ready because the support test | |
6483 // for it is not run until after DOM ready | |
6484 if ( !jQuery.support.reliableMarginRight ) { | |
6485 jQuery.cssHooks.marginRight = { | |
6486 get: function( elem, computed ) { | |
6487 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right | |
6488 // Work around by temporarily setting element display to inline-block | |
6489 var ret; | |
6490 jQuery.swap( elem, { "display": "inline-block" }, function() { | |
6491 if ( computed ) { | |
6492 ret = curCSS( elem, "margin-right", "marginRight" ); | |
6493 } else { | |
6494 ret = elem.style.marginRight; | |
6495 } | |
6496 }); | |
6497 return ret; | |
6498 } | |
6499 }; | |
6500 } | |
6501 }); | |
6502 | |
6503 if ( document.defaultView && document.defaultView.getComputedStyle ) { | |
6504 getComputedStyle = function( elem, name ) { | |
6505 var ret, defaultView, computedStyle; | |
6506 | |
6507 name = name.replace( rupper, "-$1" ).toLowerCase(); | |
6508 | |
6509 if ( !(defaultView = elem.ownerDocument.defaultView) ) { | |
6510 return undefined; | |
6511 } | |
6512 | |
6513 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) { | |
6514 ret = computedStyle.getPropertyValue( name ); | |
6515 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { | |
6516 ret = jQuery.style( elem, name ); | |
6517 } | |
6518 } | |
6519 | |
6520 return ret; | |
6521 }; | |
6522 } | |
6523 | |
6524 if ( document.documentElement.currentStyle ) { | |
6525 currentStyle = function( elem, name ) { | |
6526 var left, | |
6527 ret = elem.currentStyle && elem.currentStyle[ name ], | |
6528 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ], | |
6529 style = elem.style; | |
6530 | |
6531 // From the awesome hack by Dean Edwards | |
6532 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 | |
6533 | |
6534 // If we're not dealing with a regular pixel number | |
6535 // but a number that has a weird ending, we need to convert it to pixels | |
6536 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { | |
6537 // Remember the original values | |
6538 left = style.left; | |
6539 | |
6540 // Put in the new values to get a computed value out | |
6541 if ( rsLeft ) { | |
6542 elem.runtimeStyle.left = elem.currentStyle.left; | |
6543 } | |
6544 style.left = name === "fontSize" ? "1em" : (ret || 0); | |
6545 ret = style.pixelLeft + "px"; | |
6546 | |
6547 // Revert the changed values | |
6548 style.left = left; | |
6549 if ( rsLeft ) { | |
6550 elem.runtimeStyle.left = rsLeft; | |
6551 } | |
6552 } | |
6553 | |
6554 return ret === "" ? "auto" : ret; | |
6555 }; | |
6556 } | |
6557 | |
6558 curCSS = getComputedStyle || currentStyle; | |
6559 | |
6560 function getWH( elem, name, extra ) { | |
6561 | |
6562 // Start with offset property | |
6563 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, | |
6564 which = name === "width" ? cssWidth : cssHeight; | |
6565 | |
6566 if ( val > 0 ) { | |
6567 if ( extra !== "border" ) { | |
6568 jQuery.each( which, function() { | |
6569 if ( !extra ) { | |
6570 val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; | |
6571 } | |
6572 if ( extra === "margin" ) { | |
6573 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; | |
6574 } else { | |
6575 val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; | |
6576 } | |
6577 }); | |
6578 } | |
6579 | |
6580 return val + "px"; | |
6581 } | |
6582 | |
6583 // Fall back to computed then uncomputed css if necessary | |
6584 val = curCSS( elem, name, name ); | |
6585 if ( val < 0 || val == null ) { | |
6586 val = elem.style[ name ] || 0; | |
6587 } | |
6588 // Normalize "", auto, and prepare for extra | |
6589 val = parseFloat( val ) || 0; | |
6590 | |
6591 // Add padding, border, margin | |
6592 if ( extra ) { | |
6593 jQuery.each( which, function() { | |
6594 val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; | |
6595 if ( extra !== "padding" ) { | |
6596 val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; | |
6597 } | |
6598 if ( extra === "margin" ) { | |
6599 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; | |
6600 } | |
6601 }); | |
6602 } | |
6603 | |
6604 return val + "px"; | |
6605 } | |
6606 | |
6607 if ( jQuery.expr && jQuery.expr.filters ) { | |
6608 jQuery.expr.filters.hidden = function( elem ) { | |
6609 var width = elem.offsetWidth, | |
6610 height = elem.offsetHeight; | |
6611 | |
6612 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none"); | |
6613 }; | |
6614 | |
6615 jQuery.expr.filters.visible = function( elem ) { | |
6616 return !jQuery.expr.filters.hidden( elem ); | |
6617 }; | |
6618 } | |
6619 | |
6620 | |
6621 | |
6622 | |
6623 var r20 = /%20/g, | |
6624 rbracket = /\[\]$/, | |
6625 rCRLF = /\r?\n/g, | |
6626 rhash = /#.*$/, | |
6627 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL | |
6628 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, | |
6629 // #7653, #8125, #8152: local protocol detection | |
6630 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/, | |
6631 rnoContent = /^(?:GET|HEAD)$/, | |
6632 rprotocol = /^\/\//, | |
6633 rquery = /\?/, | |
6634 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, | |
6635 rselectTextarea = /^(?:select|textarea)/i, | |
6636 rspacesAjax = /\s+/, | |
6637 rts = /([?&])_=[^&]*/, | |
6638 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, | |
6639 | |
6640 // Keep a copy of the old load method | |
6641 _load = jQuery.fn.load, | |
6642 | |
6643 /* Prefilters | |
6644 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) | |
6645 * 2) These are called: | |
6646 * - BEFORE asking for a transport | |
6647 * - AFTER param serialization (s.data is a string if s.processData is true) | |
6648 * 3) key is the dataType | |
6649 * 4) the catchall symbol "*" can be used | |
6650 * 5) execution will start with transport dataType and THEN continue down to "*" if needed | |
6651 */ | |
6652 prefilters = {}, | |
6653 | |
6654 /* Transports bindings | |
6655 * 1) key is the dataType | |
6656 * 2) the catchall symbol "*" can be used | |
6657 * 3) selection will start with transport dataType and THEN go to "*" if needed | |
6658 */ | |
6659 transports = {}, | |
6660 | |
6661 // Document location | |
6662 ajaxLocation, | |
6663 | |
6664 // Document location segments | |
6665 ajaxLocParts; | |
6666 | |
6667 // #8138, IE may throw an exception when accessing | |
6668 // a field from window.location if document.domain has been set | |
6669 try { | |
6670 ajaxLocation = location.href; | |
6671 } catch( e ) { | |
6672 // Use the href attribute of an A element | |
6673 // since IE will modify it given document.location | |
6674 ajaxLocation = document.createElement( "a" ); | |
6675 ajaxLocation.href = ""; | |
6676 ajaxLocation = ajaxLocation.href; | |
6677 } | |
6678 | |
6679 // Segment location into parts | |
6680 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; | |
6681 | |
6682 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport | |
6683 function addToPrefiltersOrTransports( structure ) { | |
6684 | |
6685 // dataTypeExpression is optional and defaults to "*" | |
6686 return function( dataTypeExpression, func ) { | |
6687 | |
6688 if ( typeof dataTypeExpression !== "string" ) { | |
6689 func = dataTypeExpression; | |
6690 dataTypeExpression = "*"; | |
6691 } | |
6692 | |
6693 if ( jQuery.isFunction( func ) ) { | |
6694 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), | |
6695 i = 0, | |
6696 length = dataTypes.length, | |
6697 dataType, | |
6698 list, | |
6699 placeBefore; | |
6700 | |
6701 // For each dataType in the dataTypeExpression | |
6702 for(; i < length; i++ ) { | |
6703 dataType = dataTypes[ i ]; | |
6704 // We control if we're asked to add before | |
6705 // any existing element | |
6706 placeBefore = /^\+/.test( dataType ); | |
6707 if ( placeBefore ) { | |
6708 dataType = dataType.substr( 1 ) || "*"; | |
6709 } | |
6710 list = structure[ dataType ] = structure[ dataType ] || []; | |
6711 // then we add to the structure accordingly | |
6712 list[ placeBefore ? "unshift" : "push" ]( func ); | |
6713 } | |
6714 } | |
6715 }; | |
6716 } | |
6717 | |
6718 // Base inspection function for prefilters and transports | |
6719 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, | |
6720 dataType /* internal */, inspected /* internal */ ) { | |
6721 | |
6722 dataType = dataType || options.dataTypes[ 0 ]; | |
6723 inspected = inspected || {}; | |
6724 | |
6725 inspected[ dataType ] = true; | |
6726 | |
6727 var list = structure[ dataType ], | |
6728 i = 0, | |
6729 length = list ? list.length : 0, | |
6730 executeOnly = ( structure === prefilters ), | |
6731 selection; | |
6732 | |
6733 for(; i < length && ( executeOnly || !selection ); i++ ) { | |
6734 selection = list[ i ]( options, originalOptions, jqXHR ); | |
6735 // If we got redirected to another dataType | |
6736 // we try there if executing only and not done already | |
6737 if ( typeof selection === "string" ) { | |
6738 if ( !executeOnly || inspected[ selection ] ) { | |
6739 selection = undefined; | |
6740 } else { | |
6741 options.dataTypes.unshift( selection ); | |
6742 selection = inspectPrefiltersOrTransports( | |
6743 structure, options, originalOptions, jqXHR, selection, inspected ); | |
6744 } | |
6745 } | |
6746 } | |
6747 // If we're only executing or nothing was selected | |
6748 // we try the catchall dataType if not done already | |
6749 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { | |
6750 selection = inspectPrefiltersOrTransports( | |
6751 structure, options, originalOptions, jqXHR, "*", inspected ); | |
6752 } | |
6753 // unnecessary when only executing (prefilters) | |
6754 // but it'll be ignored by the caller in that case | |
6755 return selection; | |
6756 } | |
6757 | |
6758 jQuery.fn.extend({ | |
6759 load: function( url, params, callback ) { | |
6760 if ( typeof url !== "string" && _load ) { | |
6761 return _load.apply( this, arguments ); | |
6762 | |
6763 // Don't do a request if no elements are being requested | |
6764 } else if ( !this.length ) { | |
6765 return this; | |
6766 } | |
6767 | |
6768 var off = url.indexOf( " " ); | |
6769 if ( off >= 0 ) { | |
6770 var selector = url.slice( off, url.length ); | |
6771 url = url.slice( 0, off ); | |
6772 } | |
6773 | |
6774 // Default to a GET request | |
6775 var type = "GET"; | |
6776 | |
6777 // If the second parameter was provided | |
6778 if ( params ) { | |
6779 // If it's a function | |
6780 if ( jQuery.isFunction( params ) ) { | |
6781 // We assume that it's the callback | |
6782 callback = params; | |
6783 params = undefined; | |
6784 | |
6785 // Otherwise, build a param string | |
6786 } else if ( typeof params === "object" ) { | |
6787 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); | |
6788 type = "POST"; | |
6789 } | |
6790 } | |
6791 | |
6792 var self = this; | |
6793 | |
6794 // Request the remote document | |
6795 jQuery.ajax({ | |
6796 url: url, | |
6797 type: type, | |
6798 dataType: "html", | |
6799 data: params, | |
6800 // Complete callback (responseText is used internally) | |
6801 complete: function( jqXHR, status, responseText ) { | |
6802 // Store the response as specified by the jqXHR object | |
6803 responseText = jqXHR.responseText; | |
6804 // If successful, inject the HTML into all the matched elements | |
6805 if ( jqXHR.isResolved() ) { | |
6806 // #4825: Get the actual response in case | |
6807 // a dataFilter is present in ajaxSettings | |
6808 jqXHR.done(function( r ) { | |
6809 responseText = r; | |
6810 }); | |
6811 // See if a selector was specified | |
6812 self.html( selector ? | |
6813 // Create a dummy div to hold the results | |
6814 jQuery("<div>") | |
6815 // inject the contents of the document in, removing the scripts | |
6816 // to avoid any 'Permission Denied' errors in IE | |
6817 .append(responseText.replace(rscript, "")) | |
6818 | |
6819 // Locate the specified elements | |
6820 .find(selector) : | |
6821 | |
6822 // If not, just inject the full result | |
6823 responseText ); | |
6824 } | |
6825 | |
6826 if ( callback ) { | |
6827 self.each( callback, [ responseText, status, jqXHR ] ); | |
6828 } | |
6829 } | |
6830 }); | |
6831 | |
6832 return this; | |
6833 }, | |
6834 | |
6835 serialize: function() { | |
6836 return jQuery.param( this.serializeArray() ); | |
6837 }, | |
6838 | |
6839 serializeArray: function() { | |
6840 return this.map(function(){ | |
6841 return this.elements ? jQuery.makeArray( this.elements ) : this; | |
6842 }) | |
6843 .filter(function(){ | |
6844 return this.name && !this.disabled && | |
6845 ( this.checked || rselectTextarea.test( this.nodeName ) || | |
6846 rinput.test( this.type ) ); | |
6847 }) | |
6848 .map(function( i, elem ){ | |
6849 var val = jQuery( this ).val(); | |
6850 | |
6851 return val == null ? | |
6852 null : | |
6853 jQuery.isArray( val ) ? | |
6854 jQuery.map( val, function( val, i ){ | |
6855 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
6856 }) : | |
6857 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
6858 }).get(); | |
6859 } | |
6860 }); | |
6861 | |
6862 // Attach a bunch of functions for handling common AJAX events | |
6863 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ | |
6864 jQuery.fn[ o ] = function( f ){ | |
6865 return this.bind( o, f ); | |
6866 }; | |
6867 }); | |
6868 | |
6869 jQuery.each( [ "get", "post" ], function( i, method ) { | |
6870 jQuery[ method ] = function( url, data, callback, type ) { | |
6871 // shift arguments if data argument was omitted | |
6872 if ( jQuery.isFunction( data ) ) { | |
6873 type = type || callback; | |
6874 callback = data; | |
6875 data = undefined; | |
6876 } | |
6877 | |
6878 return jQuery.ajax({ | |
6879 type: method, | |
6880 url: url, | |
6881 data: data, | |
6882 success: callback, | |
6883 dataType: type | |
6884 }); | |
6885 }; | |
6886 }); | |
6887 | |
6888 jQuery.extend({ | |
6889 | |
6890 getScript: function( url, callback ) { | |
6891 return jQuery.get( url, undefined, callback, "script" ); | |
6892 }, | |
6893 | |
6894 getJSON: function( url, data, callback ) { | |
6895 return jQuery.get( url, data, callback, "json" ); | |
6896 }, | |
6897 | |
6898 // Creates a full fledged settings object into target | |
6899 // with both ajaxSettings and settings fields. | |
6900 // If target is omitted, writes into ajaxSettings. | |
6901 ajaxSetup: function ( target, settings ) { | |
6902 if ( !settings ) { | |
6903 // Only one parameter, we extend ajaxSettings | |
6904 settings = target; | |
6905 target = jQuery.extend( true, jQuery.ajaxSettings, settings ); | |
6906 } else { | |
6907 // target was provided, we extend into it | |
6908 jQuery.extend( true, target, jQuery.ajaxSettings, settings ); | |
6909 } | |
6910 // Flatten fields we don't want deep extended | |
6911 for( var field in { context: 1, url: 1 } ) { | |
6912 if ( field in settings ) { | |
6913 target[ field ] = settings[ field ]; | |
6914 } else if( field in jQuery.ajaxSettings ) { | |
6915 target[ field ] = jQuery.ajaxSettings[ field ]; | |
6916 } | |
6917 } | |
6918 return target; | |
6919 }, | |
6920 | |
6921 ajaxSettings: { | |
6922 url: ajaxLocation, | |
6923 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), | |
6924 global: true, | |
6925 type: "GET", | |
6926 contentType: "application/x-www-form-urlencoded", | |
6927 processData: true, | |
6928 async: true, | |
6929 /* | |
6930 timeout: 0, | |
6931 data: null, | |
6932 dataType: null, | |
6933 username: null, | |
6934 password: null, | |
6935 cache: null, | |
6936 traditional: false, | |
6937 headers: {}, | |
6938 */ | |
6939 | |
6940 accepts: { | |
6941 xml: "application/xml, text/xml", | |
6942 html: "text/html", | |
6943 text: "text/plain", | |
6944 json: "application/json, text/javascript", | |
6945 "*": "*/*" | |
6946 }, | |
6947 | |
6948 contents: { | |
6949 xml: /xml/, | |
6950 html: /html/, | |
6951 json: /json/ | |
6952 }, | |
6953 | |
6954 responseFields: { | |
6955 xml: "responseXML", | |
6956 text: "responseText" | |
6957 }, | |
6958 | |
6959 // List of data converters | |
6960 // 1) key format is "source_type destination_type" (a single space in-between) | |
6961 // 2) the catchall symbol "*" can be used for source_type | |
6962 converters: { | |
6963 | |
6964 // Convert anything to text | |
6965 "* text": window.String, | |
6966 | |
6967 // Text to html (true = no transformation) | |
6968 "text html": true, | |
6969 | |
6970 // Evaluate text as a json expression | |
6971 "text json": jQuery.parseJSON, | |
6972 | |
6973 // Parse text as xml | |
6974 "text xml": jQuery.parseXML | |
6975 } | |
6976 }, | |
6977 | |
6978 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), | |
6979 ajaxTransport: addToPrefiltersOrTransports( transports ), | |
6980 | |
6981 // Main method | |
6982 ajax: function( url, options ) { | |
6983 | |
6984 // If url is an object, simulate pre-1.5 signature | |
6985 if ( typeof url === "object" ) { | |
6986 options = url; | |
6987 url = undefined; | |
6988 } | |
6989 | |
6990 // Force options to be an object | |
6991 options = options || {}; | |
6992 | |
6993 var // Create the final options object | |
6994 s = jQuery.ajaxSetup( {}, options ), | |
6995 // Callbacks context | |
6996 callbackContext = s.context || s, | |
6997 // Context for global events | |
6998 // It's the callbackContext if one was provided in the options | |
6999 // and if it's a DOM node or a jQuery collection | |
7000 globalEventContext = callbackContext !== s && | |
7001 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? | |
7002 jQuery( callbackContext ) : jQuery.event, | |
7003 // Deferreds | |
7004 deferred = jQuery.Deferred(), | |
7005 completeDeferred = jQuery._Deferred(), | |
7006 // Status-dependent callbacks | |
7007 statusCode = s.statusCode || {}, | |
7008 // ifModified key | |
7009 ifModifiedKey, | |
7010 // Headers (they are sent all at once) | |
7011 requestHeaders = {}, | |
7012 requestHeadersNames = {}, | |
7013 // Response headers | |
7014 responseHeadersString, | |
7015 responseHeaders, | |
7016 // transport | |
7017 transport, | |
7018 // timeout handle | |
7019 timeoutTimer, | |
7020 // Cross-domain detection vars | |
7021 parts, | |
7022 // The jqXHR state | |
7023 state = 0, | |
7024 // To know if global events are to be dispatched | |
7025 fireGlobals, | |
7026 // Loop variable | |
7027 i, | |
7028 // Fake xhr | |
7029 jqXHR = { | |
7030 | |
7031 readyState: 0, | |
7032 | |
7033 // Caches the header | |
7034 setRequestHeader: function( name, value ) { | |
7035 if ( !state ) { | |
7036 var lname = name.toLowerCase(); | |
7037 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; | |
7038 requestHeaders[ name ] = value; | |
7039 } | |
7040 return this; | |
7041 }, | |
7042 | |
7043 // Raw string | |
7044 getAllResponseHeaders: function() { | |
7045 return state === 2 ? responseHeadersString : null; | |
7046 }, | |
7047 | |
7048 // Builds headers hashtable if needed | |
7049 getResponseHeader: function( key ) { | |
7050 var match; | |
7051 if ( state === 2 ) { | |
7052 if ( !responseHeaders ) { | |
7053 responseHeaders = {}; | |
7054 while( ( match = rheaders.exec( responseHeadersString ) ) ) { | |
7055 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; | |
7056 } | |
7057 } | |
7058 match = responseHeaders[ key.toLowerCase() ]; | |
7059 } | |
7060 return match === undefined ? null : match; | |
7061 }, | |
7062 | |
7063 // Overrides response content-type header | |
7064 overrideMimeType: function( type ) { | |
7065 if ( !state ) { | |
7066 s.mimeType = type; | |
7067 } | |
7068 return this; | |
7069 }, | |
7070 | |
7071 // Cancel the request | |
7072 abort: function( statusText ) { | |
7073 statusText = statusText || "abort"; | |
7074 if ( transport ) { | |
7075 transport.abort( statusText ); | |
7076 } | |
7077 done( 0, statusText ); | |
7078 return this; | |
7079 } | |
7080 }; | |
7081 | |
7082 // Callback for when everything is done | |
7083 // It is defined here because jslint complains if it is declared | |
7084 // at the end of the function (which would be more logical and readable) | |
7085 function done( status, statusText, responses, headers ) { | |
7086 | |
7087 // Called once | |
7088 if ( state === 2 ) { | |
7089 return; | |
7090 } | |
7091 | |
7092 // State is "done" now | |
7093 state = 2; | |
7094 | |
7095 // Clear timeout if it exists | |
7096 if ( timeoutTimer ) { | |
7097 clearTimeout( timeoutTimer ); | |
7098 } | |
7099 | |
7100 // Dereference transport for early garbage collection | |
7101 // (no matter how long the jqXHR object will be used) | |
7102 transport = undefined; | |
7103 | |
7104 // Cache response headers | |
7105 responseHeadersString = headers || ""; | |
7106 | |
7107 // Set readyState | |
7108 jqXHR.readyState = status ? 4 : 0; | |
7109 | |
7110 var isSuccess, | |
7111 success, | |
7112 error, | |
7113 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, | |
7114 lastModified, | |
7115 etag; | |
7116 | |
7117 // If successful, handle type chaining | |
7118 if ( status >= 200 && status < 300 || status === 304 ) { | |
7119 | |
7120 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. | |
7121 if ( s.ifModified ) { | |
7122 | |
7123 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { | |
7124 jQuery.lastModified[ ifModifiedKey ] = lastModified; | |
7125 } | |
7126 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { | |
7127 jQuery.etag[ ifModifiedKey ] = etag; | |
7128 } | |
7129 } | |
7130 | |
7131 // If not modified | |
7132 if ( status === 304 ) { | |
7133 | |
7134 statusText = "notmodified"; | |
7135 isSuccess = true; | |
7136 | |
7137 // If we have data | |
7138 } else { | |
7139 | |
7140 try { | |
7141 success = ajaxConvert( s, response ); | |
7142 statusText = "success"; | |
7143 isSuccess = true; | |
7144 } catch(e) { | |
7145 // We have a parsererror | |
7146 statusText = "parsererror"; | |
7147 error = e; | |
7148 } | |
7149 } | |
7150 } else { | |
7151 // We extract error from statusText | |
7152 // then normalize statusText and status for non-aborts | |
7153 error = statusText; | |
7154 if( !statusText || status ) { | |
7155 statusText = "error"; | |
7156 if ( status < 0 ) { | |
7157 status = 0; | |
7158 } | |
7159 } | |
7160 } | |
7161 | |
7162 // Set data for the fake xhr object | |
7163 jqXHR.status = status; | |
7164 jqXHR.statusText = statusText; | |
7165 | |
7166 // Success/Error | |
7167 if ( isSuccess ) { | |
7168 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); | |
7169 } else { | |
7170 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); | |
7171 } | |
7172 | |
7173 // Status-dependent callbacks | |
7174 jqXHR.statusCode( statusCode ); | |
7175 statusCode = undefined; | |
7176 | |
7177 if ( fireGlobals ) { | |
7178 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), | |
7179 [ jqXHR, s, isSuccess ? success : error ] ); | |
7180 } | |
7181 | |
7182 // Complete | |
7183 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] ); | |
7184 | |
7185 if ( fireGlobals ) { | |
7186 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] ); | |
7187 // Handle the global AJAX counter | |
7188 if ( !( --jQuery.active ) ) { | |
7189 jQuery.event.trigger( "ajaxStop" ); | |
7190 } | |
7191 } | |
7192 } | |
7193 | |
7194 // Attach deferreds | |
7195 deferred.promise( jqXHR ); | |
7196 jqXHR.success = jqXHR.done; | |
7197 jqXHR.error = jqXHR.fail; | |
7198 jqXHR.complete = completeDeferred.done; | |
7199 | |
7200 // Status-dependent callbacks | |
7201 jqXHR.statusCode = function( map ) { | |
7202 if ( map ) { | |
7203 var tmp; | |
7204 if ( state < 2 ) { | |
7205 for( tmp in map ) { | |
7206 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; | |
7207 } | |
7208 } else { | |
7209 tmp = map[ jqXHR.status ]; | |
7210 jqXHR.then( tmp, tmp ); | |
7211 } | |
7212 } | |
7213 return this; | |
7214 }; | |
7215 | |
7216 // Remove hash character (#7531: and string promotion) | |
7217 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) | |
7218 // We also use the url parameter if available | |
7219 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); | |
7220 | |
7221 // Extract dataTypes list | |
7222 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); | |
7223 | |
7224 // Determine if a cross-domain request is in order | |
7225 if ( s.crossDomain == null ) { | |
7226 parts = rurl.exec( s.url.toLowerCase() ); | |
7227 s.crossDomain = !!( parts && | |
7228 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || | |
7229 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != | |
7230 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) | |
7231 ); | |
7232 } | |
7233 | |
7234 // Convert data if not already a string | |
7235 if ( s.data && s.processData && typeof s.data !== "string" ) { | |
7236 s.data = jQuery.param( s.data, s.traditional ); | |
7237 } | |
7238 | |
7239 // Apply prefilters | |
7240 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); | |
7241 | |
7242 // If request was aborted inside a prefiler, stop there | |
7243 if ( state === 2 ) { | |
7244 return false; | |
7245 } | |
7246 | |
7247 // We can fire global events as of now if asked to | |
7248 fireGlobals = s.global; | |
7249 | |
7250 // Uppercase the type | |
7251 s.type = s.type.toUpperCase(); | |
7252 | |
7253 // Determine if request has content | |
7254 s.hasContent = !rnoContent.test( s.type ); | |
7255 | |
7256 // Watch for a new set of requests | |
7257 if ( fireGlobals && jQuery.active++ === 0 ) { | |
7258 jQuery.event.trigger( "ajaxStart" ); | |
7259 } | |
7260 | |
7261 // More options handling for requests with no content | |
7262 if ( !s.hasContent ) { | |
7263 | |
7264 // If data is available, append data to url | |
7265 if ( s.data ) { | |
7266 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; | |
7267 } | |
7268 | |
7269 // Get ifModifiedKey before adding the anti-cache parameter | |
7270 ifModifiedKey = s.url; | |
7271 | |
7272 // Add anti-cache in url if needed | |
7273 if ( s.cache === false ) { | |
7274 | |
7275 var ts = jQuery.now(), | |
7276 // try replacing _= if it is there | |
7277 ret = s.url.replace( rts, "$1_=" + ts ); | |
7278 | |
7279 // if nothing was replaced, add timestamp to the end | |
7280 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); | |
7281 } | |
7282 } | |
7283 | |
7284 // Set the correct header, if data is being sent | |
7285 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { | |
7286 jqXHR.setRequestHeader( "Content-Type", s.contentType ); | |
7287 } | |
7288 | |
7289 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. | |
7290 if ( s.ifModified ) { | |
7291 ifModifiedKey = ifModifiedKey || s.url; | |
7292 if ( jQuery.lastModified[ ifModifiedKey ] ) { | |
7293 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); | |
7294 } | |
7295 if ( jQuery.etag[ ifModifiedKey ] ) { | |
7296 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); | |
7297 } | |
7298 } | |
7299 | |
7300 // Set the Accepts header for the server, depending on the dataType | |
7301 jqXHR.setRequestHeader( | |
7302 "Accept", | |
7303 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? | |
7304 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : | |
7305 s.accepts[ "*" ] | |
7306 ); | |
7307 | |
7308 // Check for headers option | |
7309 for ( i in s.headers ) { | |
7310 jqXHR.setRequestHeader( i, s.headers[ i ] ); | |
7311 } | |
7312 | |
7313 // Allow custom headers/mimetypes and early abort | |
7314 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { | |
7315 // Abort if not done already | |
7316 jqXHR.abort(); | |
7317 return false; | |
7318 | |
7319 } | |
7320 | |
7321 // Install callbacks on deferreds | |
7322 for ( i in { success: 1, error: 1, complete: 1 } ) { | |
7323 jqXHR[ i ]( s[ i ] ); | |
7324 } | |
7325 | |
7326 // Get transport | |
7327 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); | |
7328 | |
7329 // If no transport, we auto-abort | |
7330 if ( !transport ) { | |
7331 done( -1, "No Transport" ); | |
7332 } else { | |
7333 jqXHR.readyState = 1; | |
7334 // Send global event | |
7335 if ( fireGlobals ) { | |
7336 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); | |
7337 } | |
7338 // Timeout | |
7339 if ( s.async && s.timeout > 0 ) { | |
7340 timeoutTimer = setTimeout( function(){ | |
7341 jqXHR.abort( "timeout" ); | |
7342 }, s.timeout ); | |
7343 } | |
7344 | |
7345 try { | |
7346 state = 1; | |
7347 transport.send( requestHeaders, done ); | |
7348 } catch (e) { | |
7349 // Propagate exception as error if not done | |
7350 if ( status < 2 ) { | |
7351 done( -1, e ); | |
7352 // Simply rethrow otherwise | |
7353 } else { | |
7354 jQuery.error( e ); | |
7355 } | |
7356 } | |
7357 } | |
7358 | |
7359 return jqXHR; | |
7360 }, | |
7361 | |
7362 // Serialize an array of form elements or a set of | |
7363 // key/values into a query string | |
7364 param: function( a, traditional ) { | |
7365 var s = [], | |
7366 add = function( key, value ) { | |
7367 // If value is a function, invoke it and return its value | |
7368 value = jQuery.isFunction( value ) ? value() : value; | |
7369 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); | |
7370 }; | |
7371 | |
7372 // Set traditional to true for jQuery <= 1.3.2 behavior. | |
7373 if ( traditional === undefined ) { | |
7374 traditional = jQuery.ajaxSettings.traditional; | |
7375 } | |
7376 | |
7377 // If an array was passed in, assume that it is an array of form elements. | |
7378 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { | |
7379 // Serialize the form elements | |
7380 jQuery.each( a, function() { | |
7381 add( this.name, this.value ); | |
7382 }); | |
7383 | |
7384 } else { | |
7385 // If traditional, encode the "old" way (the way 1.3.2 or older | |
7386 // did it), otherwise encode params recursively. | |
7387 for ( var prefix in a ) { | |
7388 buildParams( prefix, a[ prefix ], traditional, add ); | |
7389 } | |
7390 } | |
7391 | |
7392 // Return the resulting serialization | |
7393 return s.join( "&" ).replace( r20, "+" ); | |
7394 } | |
7395 }); | |
7396 | |
7397 function buildParams( prefix, obj, traditional, add ) { | |
7398 if ( jQuery.isArray( obj ) ) { | |
7399 // Serialize array item. | |
7400 jQuery.each( obj, function( i, v ) { | |
7401 if ( traditional || rbracket.test( prefix ) ) { | |
7402 // Treat each array item as a scalar. | |
7403 add( prefix, v ); | |
7404 | |
7405 } else { | |
7406 // If array item is non-scalar (array or object), encode its | |
7407 // numeric index to resolve deserialization ambiguity issues. | |
7408 // Note that rack (as of 1.0.0) can't currently deserialize | |
7409 // nested arrays properly, and attempting to do so may cause | |
7410 // a server error. Possible fixes are to modify rack's | |
7411 // deserialization algorithm or to provide an option or flag | |
7412 // to force array serialization to be shallow. | |
7413 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add ); | |
7414 } | |
7415 }); | |
7416 | |
7417 } else if ( !traditional && obj != null && typeof obj === "object" ) { | |
7418 // Serialize object item. | |
7419 for ( var name in obj ) { | |
7420 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); | |
7421 } | |
7422 | |
7423 } else { | |
7424 // Serialize scalar item. | |
7425 add( prefix, obj ); | |
7426 } | |
7427 } | |
7428 | |
7429 // This is still on the jQuery object... for now | |
7430 // Want to move this to jQuery.ajax some day | |
7431 jQuery.extend({ | |
7432 | |
7433 // Counter for holding the number of active queries | |
7434 active: 0, | |
7435 | |
7436 // Last-Modified header cache for next request | |
7437 lastModified: {}, | |
7438 etag: {} | |
7439 | |
7440 }); | |
7441 | |
7442 /* Handles responses to an ajax request: | |
7443 * - sets all responseXXX fields accordingly | |
7444 * - finds the right dataType (mediates between content-type and expected dataType) | |
7445 * - returns the corresponding response | |
7446 */ | |
7447 function ajaxHandleResponses( s, jqXHR, responses ) { | |
7448 | |
7449 var contents = s.contents, | |
7450 dataTypes = s.dataTypes, | |
7451 responseFields = s.responseFields, | |
7452 ct, | |
7453 type, | |
7454 finalDataType, | |
7455 firstDataType; | |
7456 | |
7457 // Fill responseXXX fields | |
7458 for( type in responseFields ) { | |
7459 if ( type in responses ) { | |
7460 jqXHR[ responseFields[type] ] = responses[ type ]; | |
7461 } | |
7462 } | |
7463 | |
7464 // Remove auto dataType and get content-type in the process | |
7465 while( dataTypes[ 0 ] === "*" ) { | |
7466 dataTypes.shift(); | |
7467 if ( ct === undefined ) { | |
7468 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); | |
7469 } | |
7470 } | |
7471 | |
7472 // Check if we're dealing with a known content-type | |
7473 if ( ct ) { | |
7474 for ( type in contents ) { | |
7475 if ( contents[ type ] && contents[ type ].test( ct ) ) { | |
7476 dataTypes.unshift( type ); | |
7477 break; | |
7478 } | |
7479 } | |
7480 } | |
7481 | |
7482 // Check to see if we have a response for the expected dataType | |
7483 if ( dataTypes[ 0 ] in responses ) { | |
7484 finalDataType = dataTypes[ 0 ]; | |
7485 } else { | |
7486 // Try convertible dataTypes | |
7487 for ( type in responses ) { | |
7488 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { | |
7489 finalDataType = type; | |
7490 break; | |
7491 } | |
7492 if ( !firstDataType ) { | |
7493 firstDataType = type; | |
7494 } | |
7495 } | |
7496 // Or just use first one | |
7497 finalDataType = finalDataType || firstDataType; | |
7498 } | |
7499 | |
7500 // If we found a dataType | |
7501 // We add the dataType to the list if needed | |
7502 // and return the corresponding response | |
7503 if ( finalDataType ) { | |
7504 if ( finalDataType !== dataTypes[ 0 ] ) { | |
7505 dataTypes.unshift( finalDataType ); | |
7506 } | |
7507 return responses[ finalDataType ]; | |
7508 } | |
7509 } | |
7510 | |
7511 // Chain conversions given the request and the original response | |
7512 function ajaxConvert( s, response ) { | |
7513 | |
7514 // Apply the dataFilter if provided | |
7515 if ( s.dataFilter ) { | |
7516 response = s.dataFilter( response, s.dataType ); | |
7517 } | |
7518 | |
7519 var dataTypes = s.dataTypes, | |
7520 converters = {}, | |
7521 i, | |
7522 key, | |
7523 length = dataTypes.length, | |
7524 tmp, | |
7525 // Current and previous dataTypes | |
7526 current = dataTypes[ 0 ], | |
7527 prev, | |
7528 // Conversion expression | |
7529 conversion, | |
7530 // Conversion function | |
7531 conv, | |
7532 // Conversion functions (transitive conversion) | |
7533 conv1, | |
7534 conv2; | |
7535 | |
7536 // For each dataType in the chain | |
7537 for( i = 1; i < length; i++ ) { | |
7538 | |
7539 // Create converters map | |
7540 // with lowercased keys | |
7541 if ( i === 1 ) { | |
7542 for( key in s.converters ) { | |
7543 if( typeof key === "string" ) { | |
7544 converters[ key.toLowerCase() ] = s.converters[ key ]; | |
7545 } | |
7546 } | |
7547 } | |
7548 | |
7549 // Get the dataTypes | |
7550 prev = current; | |
7551 current = dataTypes[ i ]; | |
7552 | |
7553 // If current is auto dataType, update it to prev | |
7554 if( current === "*" ) { | |
7555 current = prev; | |
7556 // If no auto and dataTypes are actually different | |
7557 } else if ( prev !== "*" && prev !== current ) { | |
7558 | |
7559 // Get the converter | |
7560 conversion = prev + " " + current; | |
7561 conv = converters[ conversion ] || converters[ "* " + current ]; | |
7562 | |
7563 // If there is no direct converter, search transitively | |
7564 if ( !conv ) { | |
7565 conv2 = undefined; | |
7566 for( conv1 in converters ) { | |
7567 tmp = conv1.split( " " ); | |
7568 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { | |
7569 conv2 = converters[ tmp[1] + " " + current ]; | |
7570 if ( conv2 ) { | |
7571 conv1 = converters[ conv1 ]; | |
7572 if ( conv1 === true ) { | |
7573 conv = conv2; | |
7574 } else if ( conv2 === true ) { | |
7575 conv = conv1; | |
7576 } | |
7577 break; | |
7578 } | |
7579 } | |
7580 } | |
7581 } | |
7582 // If we found no converter, dispatch an error | |
7583 if ( !( conv || conv2 ) ) { | |
7584 jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); | |
7585 } | |
7586 // If found converter is not an equivalence | |
7587 if ( conv !== true ) { | |
7588 // Convert with 1 or 2 converters accordingly | |
7589 response = conv ? conv( response ) : conv2( conv1(response) ); | |
7590 } | |
7591 } | |
7592 } | |
7593 return response; | |
7594 } | |
7595 | |
7596 | |
7597 | |
7598 | |
7599 var jsc = jQuery.now(), | |
7600 jsre = /(\=)\?(&|$)|\?\?/i; | |
7601 | |
7602 // Default jsonp settings | |
7603 jQuery.ajaxSetup({ | |
7604 jsonp: "callback", | |
7605 jsonpCallback: function() { | |
7606 return jQuery.expando + "_" + ( jsc++ ); | |
7607 } | |
7608 }); | |
7609 | |
7610 // Detect, normalize options and install callbacks for jsonp requests | |
7611 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { | |
7612 | |
7613 var inspectData = s.contentType === "application/x-www-form-urlencoded" && | |
7614 ( typeof s.data === "string" ); | |
7615 | |
7616 if ( s.dataTypes[ 0 ] === "jsonp" || | |
7617 s.jsonp !== false && ( jsre.test( s.url ) || | |
7618 inspectData && jsre.test( s.data ) ) ) { | |
7619 | |
7620 var responseContainer, | |
7621 jsonpCallback = s.jsonpCallback = | |
7622 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, | |
7623 previous = window[ jsonpCallback ], | |
7624 url = s.url, | |
7625 data = s.data, | |
7626 replace = "$1" + jsonpCallback + "$2"; | |
7627 | |
7628 if ( s.jsonp !== false ) { | |
7629 url = url.replace( jsre, replace ); | |
7630 if ( s.url === url ) { | |
7631 if ( inspectData ) { | |
7632 data = data.replace( jsre, replace ); | |
7633 } | |
7634 if ( s.data === data ) { | |
7635 // Add callback manually | |
7636 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback; | |
7637 } | |
7638 } | |
7639 } | |
7640 | |
7641 s.url = url; | |
7642 s.data = data; | |
7643 | |
7644 // Install callback | |
7645 window[ jsonpCallback ] = function( response ) { | |
7646 responseContainer = [ response ]; | |
7647 }; | |
7648 | |
7649 // Clean-up function | |
7650 jqXHR.always(function() { | |
7651 // Set callback back to previous value | |
7652 window[ jsonpCallback ] = previous; | |
7653 // Call if it was a function and we have a response | |
7654 if ( responseContainer && jQuery.isFunction( previous ) ) { | |
7655 window[ jsonpCallback ]( responseContainer[ 0 ] ); | |
7656 } | |
7657 }); | |
7658 | |
7659 // Use data converter to retrieve json after script execution | |
7660 s.converters["script json"] = function() { | |
7661 if ( !responseContainer ) { | |
7662 jQuery.error( jsonpCallback + " was not called" ); | |
7663 } | |
7664 return responseContainer[ 0 ]; | |
7665 }; | |
7666 | |
7667 // force json dataType | |
7668 s.dataTypes[ 0 ] = "json"; | |
7669 | |
7670 // Delegate to script | |
7671 return "script"; | |
7672 } | |
7673 }); | |
7674 | |
7675 | |
7676 | |
7677 | |
7678 // Install script dataType | |
7679 jQuery.ajaxSetup({ | |
7680 accepts: { | |
7681 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" | |
7682 }, | |
7683 contents: { | |
7684 script: /javascript|ecmascript/ | |
7685 }, | |
7686 converters: { | |
7687 "text script": function( text ) { | |
7688 jQuery.globalEval( text ); | |
7689 return text; | |
7690 } | |
7691 } | |
7692 }); | |
7693 | |
7694 // Handle cache's special case and global | |
7695 jQuery.ajaxPrefilter( "script", function( s ) { | |
7696 if ( s.cache === undefined ) { | |
7697 s.cache = false; | |
7698 } | |
7699 if ( s.crossDomain ) { | |
7700 s.type = "GET"; | |
7701 s.global = false; | |
7702 } | |
7703 }); | |
7704 | |
7705 // Bind script tag hack transport | |
7706 jQuery.ajaxTransport( "script", function(s) { | |
7707 | |
7708 // This transport only deals with cross domain requests | |
7709 if ( s.crossDomain ) { | |
7710 | |
7711 var script, | |
7712 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; | |
7713 | |
7714 return { | |
7715 | |
7716 send: function( _, callback ) { | |
7717 | |
7718 script = document.createElement( "script" ); | |
7719 | |
7720 script.async = "async"; | |
7721 | |
7722 if ( s.scriptCharset ) { | |
7723 script.charset = s.scriptCharset; | |
7724 } | |
7725 | |
7726 script.src = s.url; | |
7727 | |
7728 // Attach handlers for all browsers | |
7729 script.onload = script.onreadystatechange = function( _, isAbort ) { | |
7730 | |
7731 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { | |
7732 | |
7733 // Handle memory leak in IE | |
7734 script.onload = script.onreadystatechange = null; | |
7735 | |
7736 // Remove the script | |
7737 if ( head && script.parentNode ) { | |
7738 head.removeChild( script ); | |
7739 } | |
7740 | |
7741 // Dereference the script | |
7742 script = undefined; | |
7743 | |
7744 // Callback if not abort | |
7745 if ( !isAbort ) { | |
7746 callback( 200, "success" ); | |
7747 } | |
7748 } | |
7749 }; | |
7750 // Use insertBefore instead of appendChild to circumvent an IE6 bug. | |
7751 // This arises when a base node is used (#2709 and #4378). | |
7752 head.insertBefore( script, head.firstChild ); | |
7753 }, | |
7754 | |
7755 abort: function() { | |
7756 if ( script ) { | |
7757 script.onload( 0, 1 ); | |
7758 } | |
7759 } | |
7760 }; | |
7761 } | |
7762 }); | |
7763 | |
7764 | |
7765 | |
7766 | |
7767 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload | |
7768 xhrOnUnloadAbort = window.ActiveXObject ? function() { | |
7769 // Abort all pending requests | |
7770 for ( var key in xhrCallbacks ) { | |
7771 xhrCallbacks[ key ]( 0, 1 ); | |
7772 } | |
7773 } : false, | |
7774 xhrId = 0, | |
7775 xhrCallbacks; | |
7776 | |
7777 // Functions to create xhrs | |
7778 function createStandardXHR() { | |
7779 try { | |
7780 return new window.XMLHttpRequest(); | |
7781 } catch( e ) {} | |
7782 } | |
7783 | |
7784 function createActiveXHR() { | |
7785 try { | |
7786 return new window.ActiveXObject( "Microsoft.XMLHTTP" ); | |
7787 } catch( e ) {} | |
7788 } | |
7789 | |
7790 // Create the request object | |
7791 // (This is still attached to ajaxSettings for backward compatibility) | |
7792 jQuery.ajaxSettings.xhr = window.ActiveXObject ? | |
7793 /* Microsoft failed to properly | |
7794 * implement the XMLHttpRequest in IE7 (can't request local files), | |
7795 * so we use the ActiveXObject when it is available | |
7796 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so | |
7797 * we need a fallback. | |
7798 */ | |
7799 function() { | |
7800 return !this.isLocal && createStandardXHR() || createActiveXHR(); | |
7801 } : | |
7802 // For all other browsers, use the standard XMLHttpRequest object | |
7803 createStandardXHR; | |
7804 | |
7805 // Determine support properties | |
7806 (function( xhr ) { | |
7807 jQuery.extend( jQuery.support, { | |
7808 ajax: !!xhr, | |
7809 cors: !!xhr && ( "withCredentials" in xhr ) | |
7810 }); | |
7811 })( jQuery.ajaxSettings.xhr() ); | |
7812 | |
7813 // Create transport if the browser can provide an xhr | |
7814 if ( jQuery.support.ajax ) { | |
7815 | |
7816 jQuery.ajaxTransport(function( s ) { | |
7817 // Cross domain only allowed if supported through XMLHttpRequest | |
7818 if ( !s.crossDomain || jQuery.support.cors ) { | |
7819 | |
7820 var callback; | |
7821 | |
7822 return { | |
7823 send: function( headers, complete ) { | |
7824 | |
7825 // Get a new xhr | |
7826 var xhr = s.xhr(), | |
7827 handle, | |
7828 i; | |
7829 | |
7830 // Open the socket | |
7831 // Passing null username, generates a login popup on Opera (#2865) | |
7832 if ( s.username ) { | |
7833 xhr.open( s.type, s.url, s.async, s.username, s.password ); | |
7834 } else { | |
7835 xhr.open( s.type, s.url, s.async ); | |
7836 } | |
7837 | |
7838 // Apply custom fields if provided | |
7839 if ( s.xhrFields ) { | |
7840 for ( i in s.xhrFields ) { | |
7841 xhr[ i ] = s.xhrFields[ i ]; | |
7842 } | |
7843 } | |
7844 | |
7845 // Override mime type if needed | |
7846 if ( s.mimeType && xhr.overrideMimeType ) { | |
7847 xhr.overrideMimeType( s.mimeType ); | |
7848 } | |
7849 | |
7850 // X-Requested-With header | |
7851 // For cross-domain requests, seeing as conditions for a preflight are | |
7852 // akin to a jigsaw puzzle, we simply never set it to be sure. | |
7853 // (it can always be set on a per-request basis or even using ajaxSetup) | |
7854 // For same-domain requests, won't change header if already provided. | |
7855 if ( !s.crossDomain && !headers["X-Requested-With"] ) { | |
7856 headers[ "X-Requested-With" ] = "XMLHttpRequest"; | |
7857 } | |
7858 | |
7859 // Need an extra try/catch for cross domain requests in Firefox 3 | |
7860 try { | |
7861 for ( i in headers ) { | |
7862 xhr.setRequestHeader( i, headers[ i ] ); | |
7863 } | |
7864 } catch( _ ) {} | |
7865 | |
7866 // Do send the request | |
7867 // This may raise an exception which is actually | |
7868 // handled in jQuery.ajax (so no try/catch here) | |
7869 xhr.send( ( s.hasContent && s.data ) || null ); | |
7870 | |
7871 // Listener | |
7872 callback = function( _, isAbort ) { | |
7873 | |
7874 var status, | |
7875 statusText, | |
7876 responseHeaders, | |
7877 responses, | |
7878 xml; | |
7879 | |
7880 // Firefox throws exceptions when accessing properties | |
7881 // of an xhr when a network error occured | |
7882 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) | |
7883 try { | |
7884 | |
7885 // Was never called and is aborted or complete | |
7886 if ( callback && ( isAbort || xhr.readyState === 4 ) ) { | |
7887 | |
7888 // Only called once | |
7889 callback = undefined; | |
7890 | |
7891 // Do not keep as active anymore | |
7892 if ( handle ) { | |
7893 xhr.onreadystatechange = jQuery.noop; | |
7894 if ( xhrOnUnloadAbort ) { | |
7895 delete xhrCallbacks[ handle ]; | |
7896 } | |
7897 } | |
7898 | |
7899 // If it's an abort | |
7900 if ( isAbort ) { | |
7901 // Abort it manually if needed | |
7902 if ( xhr.readyState !== 4 ) { | |
7903 xhr.abort(); | |
7904 } | |
7905 } else { | |
7906 status = xhr.status; | |
7907 responseHeaders = xhr.getAllResponseHeaders(); | |
7908 responses = {}; | |
7909 xml = xhr.responseXML; | |
7910 | |
7911 // Construct response list | |
7912 if ( xml && xml.documentElement /* #4958 */ ) { | |
7913 responses.xml = xml; | |
7914 } | |
7915 responses.text = xhr.responseText; | |
7916 | |
7917 // Firefox throws an exception when accessing | |
7918 // statusText for faulty cross-domain requests | |
7919 try { | |
7920 statusText = xhr.statusText; | |
7921 } catch( e ) { | |
7922 // We normalize with Webkit giving an empty statusText | |
7923 statusText = ""; | |
7924 } | |
7925 | |
7926 // Filter status for non standard behaviors | |
7927 | |
7928 // If the request is local and we have data: assume a success | |
7929 // (success with no data won't get notified, that's the best we | |
7930 // can do given current implementations) | |
7931 if ( !status && s.isLocal && !s.crossDomain ) { | |
7932 status = responses.text ? 200 : 404; | |
7933 // IE - #1450: sometimes returns 1223 when it should be 204 | |
7934 } else if ( status === 1223 ) { | |
7935 status = 204; | |
7936 } | |
7937 } | |
7938 } | |
7939 } catch( firefoxAccessException ) { | |
7940 if ( !isAbort ) { | |
7941 complete( -1, firefoxAccessException ); | |
7942 } | |
7943 } | |
7944 | |
7945 // Call complete if needed | |
7946 if ( responses ) { | |
7947 complete( status, statusText, responses, responseHeaders ); | |
7948 } | |
7949 }; | |
7950 | |
7951 // if we're in sync mode or it's in cache | |
7952 // and has been retrieved directly (IE6 & IE7) | |
7953 // we need to manually fire the callback | |
7954 if ( !s.async || xhr.readyState === 4 ) { | |
7955 callback(); | |
7956 } else { | |
7957 handle = ++xhrId; | |
7958 if ( xhrOnUnloadAbort ) { | |
7959 // Create the active xhrs callbacks list if needed | |
7960 // and attach the unload handler | |
7961 if ( !xhrCallbacks ) { | |
7962 xhrCallbacks = {}; | |
7963 jQuery( window ).unload( xhrOnUnloadAbort ); | |
7964 } | |
7965 // Add to list of active xhrs callbacks | |
7966 xhrCallbacks[ handle ] = callback; | |
7967 } | |
7968 xhr.onreadystatechange = callback; | |
7969 } | |
7970 }, | |
7971 | |
7972 abort: function() { | |
7973 if ( callback ) { | |
7974 callback(0,1); | |
7975 } | |
7976 } | |
7977 }; | |
7978 } | |
7979 }); | |
7980 } | |
7981 | |
7982 | |
7983 | |
7984 | |
7985 var elemdisplay = {}, | |
7986 iframe, iframeDoc, | |
7987 rfxtypes = /^(?:toggle|show|hide)$/, | |
7988 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, | |
7989 timerId, | |
7990 fxAttrs = [ | |
7991 // height animations | |
7992 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], | |
7993 // width animations | |
7994 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], | |
7995 // opacity animations | |
7996 [ "opacity" ] | |
7997 ], | |
7998 fxNow, | |
7999 requestAnimationFrame = window.webkitRequestAnimationFrame || | |
8000 window.mozRequestAnimationFrame || | |
8001 window.oRequestAnimationFrame; | |
8002 | |
8003 jQuery.fn.extend({ | |
8004 show: function( speed, easing, callback ) { | |
8005 var elem, display; | |
8006 | |
8007 if ( speed || speed === 0 ) { | |
8008 return this.animate( genFx("show", 3), speed, easing, callback); | |
8009 | |
8010 } else { | |
8011 for ( var i = 0, j = this.length; i < j; i++ ) { | |
8012 elem = this[i]; | |
8013 | |
8014 if ( elem.style ) { | |
8015 display = elem.style.display; | |
8016 | |
8017 // Reset the inline display of this element to learn if it is | |
8018 // being hidden by cascaded rules or not | |
8019 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { | |
8020 display = elem.style.display = ""; | |
8021 } | |
8022 | |
8023 // Set elements which have been overridden with display: none | |
8024 // in a stylesheet to whatever the default browser style is | |
8025 // for such an element | |
8026 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { | |
8027 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); | |
8028 } | |
8029 } | |
8030 } | |
8031 | |
8032 // Set the display of most of the elements in a second loop | |
8033 // to avoid the constant reflow | |
8034 for ( i = 0; i < j; i++ ) { | |
8035 elem = this[i]; | |
8036 | |
8037 if ( elem.style ) { | |
8038 display = elem.style.display; | |
8039 | |
8040 if ( display === "" || display === "none" ) { | |
8041 elem.style.display = jQuery._data(elem, "olddisplay") || ""; | |
8042 } | |
8043 } | |
8044 } | |
8045 | |
8046 return this; | |
8047 } | |
8048 }, | |
8049 | |
8050 hide: function( speed, easing, callback ) { | |
8051 if ( speed || speed === 0 ) { | |
8052 return this.animate( genFx("hide", 3), speed, easing, callback); | |
8053 | |
8054 } else { | |
8055 for ( var i = 0, j = this.length; i < j; i++ ) { | |
8056 if ( this[i].style ) { | |
8057 var display = jQuery.css( this[i], "display" ); | |
8058 | |
8059 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { | |
8060 jQuery._data( this[i], "olddisplay", display ); | |
8061 } | |
8062 } | |
8063 } | |
8064 | |
8065 // Set the display of the elements in a second loop | |
8066 // to avoid the constant reflow | |
8067 for ( i = 0; i < j; i++ ) { | |
8068 if ( this[i].style ) { | |
8069 this[i].style.display = "none"; | |
8070 } | |
8071 } | |
8072 | |
8073 return this; | |
8074 } | |
8075 }, | |
8076 | |
8077 // Save the old toggle function | |
8078 _toggle: jQuery.fn.toggle, | |
8079 | |
8080 toggle: function( fn, fn2, callback ) { | |
8081 var bool = typeof fn === "boolean"; | |
8082 | |
8083 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { | |
8084 this._toggle.apply( this, arguments ); | |
8085 | |
8086 } else if ( fn == null || bool ) { | |
8087 this.each(function() { | |
8088 var state = bool ? fn : jQuery(this).is(":hidden"); | |
8089 jQuery(this)[ state ? "show" : "hide" ](); | |
8090 }); | |
8091 | |
8092 } else { | |
8093 this.animate(genFx("toggle", 3), fn, fn2, callback); | |
8094 } | |
8095 | |
8096 return this; | |
8097 }, | |
8098 | |
8099 fadeTo: function( speed, to, easing, callback ) { | |
8100 return this.filter(":hidden").css("opacity", 0).show().end() | |
8101 .animate({opacity: to}, speed, easing, callback); | |
8102 }, | |
8103 | |
8104 animate: function( prop, speed, easing, callback ) { | |
8105 var optall = jQuery.speed(speed, easing, callback); | |
8106 | |
8107 if ( jQuery.isEmptyObject( prop ) ) { | |
8108 return this.each( optall.complete, [ false ] ); | |
8109 } | |
8110 | |
8111 // Do not change referenced properties as per-property easing will be lost | |
8112 prop = jQuery.extend( {}, prop ); | |
8113 | |
8114 return this[ optall.queue === false ? "each" : "queue" ](function() { | |
8115 // XXX 'this' does not always have a nodeName when running the | |
8116 // test suite | |
8117 | |
8118 if ( optall.queue === false ) { | |
8119 jQuery._mark( this ); | |
8120 } | |
8121 | |
8122 var opt = jQuery.extend( {}, optall ), | |
8123 isElement = this.nodeType === 1, | |
8124 hidden = isElement && jQuery(this).is(":hidden"), | |
8125 name, val, p, | |
8126 display, e, | |
8127 parts, start, end, unit; | |
8128 | |
8129 // will store per property easing and be used to determine when an animation is complete | |
8130 opt.animatedProperties = {}; | |
8131 | |
8132 for ( p in prop ) { | |
8133 | |
8134 // property name normalization | |
8135 name = jQuery.camelCase( p ); | |
8136 if ( p !== name ) { | |
8137 prop[ name ] = prop[ p ]; | |
8138 delete prop[ p ]; | |
8139 } | |
8140 | |
8141 val = prop[ name ]; | |
8142 | |
8143 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) | |
8144 if ( jQuery.isArray( val ) ) { | |
8145 opt.animatedProperties[ name ] = val[ 1 ]; | |
8146 val = prop[ name ] = val[ 0 ]; | |
8147 } else { | |
8148 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; | |
8149 } | |
8150 | |
8151 if ( val === "hide" && hidden || val === "show" && !hidden ) { | |
8152 return opt.complete.call( this ); | |
8153 } | |
8154 | |
8155 if ( isElement && ( name === "height" || name === "width" ) ) { | |
8156 // Make sure that nothing sneaks out | |
8157 // Record all 3 overflow attributes because IE does not | |
8158 // change the overflow attribute when overflowX and | |
8159 // overflowY are set to the same value | |
8160 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; | |
8161 | |
8162 // Set display property to inline-block for height/width | |
8163 // animations on inline elements that are having width/height | |
8164 // animated | |
8165 if ( jQuery.css( this, "display" ) === "inline" && | |
8166 jQuery.css( this, "float" ) === "none" ) { | |
8167 if ( !jQuery.support.inlineBlockNeedsLayout ) { | |
8168 this.style.display = "inline-block"; | |
8169 | |
8170 } else { | |
8171 display = defaultDisplay( this.nodeName ); | |
8172 | |
8173 // inline-level elements accept inline-block; | |
8174 // block-level elements need to be inline with layout | |
8175 if ( display === "inline" ) { | |
8176 this.style.display = "inline-block"; | |
8177 | |
8178 } else { | |
8179 this.style.display = "inline"; | |
8180 this.style.zoom = 1; | |
8181 } | |
8182 } | |
8183 } | |
8184 } | |
8185 } | |
8186 | |
8187 if ( opt.overflow != null ) { | |
8188 this.style.overflow = "hidden"; | |
8189 } | |
8190 | |
8191 for ( p in prop ) { | |
8192 e = new jQuery.fx( this, opt, p ); | |
8193 val = prop[ p ]; | |
8194 | |
8195 if ( rfxtypes.test(val) ) { | |
8196 e[ val === "toggle" ? hidden ? "show" : "hide" : val ](); | |
8197 | |
8198 } else { | |
8199 parts = rfxnum.exec( val ); | |
8200 start = e.cur(); | |
8201 | |
8202 if ( parts ) { | |
8203 end = parseFloat( parts[2] ); | |
8204 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); | |
8205 | |
8206 // We need to compute starting value | |
8207 if ( unit !== "px" ) { | |
8208 jQuery.style( this, p, (end || 1) + unit); | |
8209 start = ((end || 1) / e.cur()) * start; | |
8210 jQuery.style( this, p, start + unit); | |
8211 } | |
8212 | |
8213 // If a +=/-= token was provided, we're doing a relative animation | |
8214 if ( parts[1] ) { | |
8215 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; | |
8216 } | |
8217 | |
8218 e.custom( start, end, unit ); | |
8219 | |
8220 } else { | |
8221 e.custom( start, val, "" ); | |
8222 } | |
8223 } | |
8224 } | |
8225 | |
8226 // For JS strict compliance | |
8227 return true; | |
8228 }); | |
8229 }, | |
8230 | |
8231 stop: function( clearQueue, gotoEnd ) { | |
8232 if ( clearQueue ) { | |
8233 this.queue([]); | |
8234 } | |
8235 | |
8236 this.each(function() { | |
8237 var timers = jQuery.timers, | |
8238 i = timers.length; | |
8239 // clear marker counters if we know they won't be | |
8240 if ( !gotoEnd ) { | |
8241 jQuery._unmark( true, this ); | |
8242 } | |
8243 while ( i-- ) { | |
8244 if ( timers[i].elem === this ) { | |
8245 if (gotoEnd) { | |
8246 // force the next step to be the last | |
8247 timers[i](true); | |
8248 } | |
8249 | |
8250 timers.splice(i, 1); | |
8251 } | |
8252 } | |
8253 }); | |
8254 | |
8255 // start the next in the queue if the last step wasn't forced | |
8256 if ( !gotoEnd ) { | |
8257 this.dequeue(); | |
8258 } | |
8259 | |
8260 return this; | |
8261 } | |
8262 | |
8263 }); | |
8264 | |
8265 // Animations created synchronously will run synchronously | |
8266 function createFxNow() { | |
8267 setTimeout( clearFxNow, 0 ); | |
8268 return ( fxNow = jQuery.now() ); | |
8269 } | |
8270 | |
8271 function clearFxNow() { | |
8272 fxNow = undefined; | |
8273 } | |
8274 | |
8275 // Generate parameters to create a standard animation | |
8276 function genFx( type, num ) { | |
8277 var obj = {}; | |
8278 | |
8279 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() { | |
8280 obj[ this ] = type; | |
8281 }); | |
8282 | |
8283 return obj; | |
8284 } | |
8285 | |
8286 // Generate shortcuts for custom animations | |
8287 jQuery.each({ | |
8288 slideDown: genFx("show", 1), | |
8289 slideUp: genFx("hide", 1), | |
8290 slideToggle: genFx("toggle", 1), | |
8291 fadeIn: { opacity: "show" }, | |
8292 fadeOut: { opacity: "hide" }, | |
8293 fadeToggle: { opacity: "toggle" } | |
8294 }, function( name, props ) { | |
8295 jQuery.fn[ name ] = function( speed, easing, callback ) { | |
8296 return this.animate( props, speed, easing, callback ); | |
8297 }; | |
8298 }); | |
8299 | |
8300 jQuery.extend({ | |
8301 speed: function( speed, easing, fn ) { | |
8302 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { | |
8303 complete: fn || !fn && easing || | |
8304 jQuery.isFunction( speed ) && speed, | |
8305 duration: speed, | |
8306 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing | |
8307 }; | |
8308 | |
8309 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : | |
8310 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; | |
8311 | |
8312 // Queueing | |
8313 opt.old = opt.complete; | |
8314 opt.complete = function( noUnmark ) { | |
8315 if ( jQuery.isFunction( opt.old ) ) { | |
8316 opt.old.call( this ); | |
8317 } | |
8318 | |
8319 if ( opt.queue !== false ) { | |
8320 jQuery.dequeue( this ); | |
8321 } else if ( noUnmark !== false ) { | |
8322 jQuery._unmark( this ); | |
8323 } | |
8324 }; | |
8325 | |
8326 return opt; | |
8327 }, | |
8328 | |
8329 easing: { | |
8330 linear: function( p, n, firstNum, diff ) { | |
8331 return firstNum + diff * p; | |
8332 }, | |
8333 swing: function( p, n, firstNum, diff ) { | |
8334 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; | |
8335 } | |
8336 }, | |
8337 | |
8338 timers: [], | |
8339 | |
8340 fx: function( elem, options, prop ) { | |
8341 this.options = options; | |
8342 this.elem = elem; | |
8343 this.prop = prop; | |
8344 | |
8345 options.orig = options.orig || {}; | |
8346 } | |
8347 | |
8348 }); | |
8349 | |
8350 jQuery.fx.prototype = { | |
8351 // Simple function for setting a style value | |
8352 update: function() { | |
8353 if ( this.options.step ) { | |
8354 this.options.step.call( this.elem, this.now, this ); | |
8355 } | |
8356 | |
8357 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); | |
8358 }, | |
8359 | |
8360 // Get the current size | |
8361 cur: function() { | |
8362 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) { | |
8363 return this.elem[ this.prop ]; | |
8364 } | |
8365 | |
8366 var parsed, | |
8367 r = jQuery.css( this.elem, this.prop ); | |
8368 // Empty strings, null, undefined and "auto" are converted to 0, | |
8369 // complex values such as "rotate(1rad)" are returned as is, | |
8370 // simple values such as "10px" are parsed to Float. | |
8371 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; | |
8372 }, | |
8373 | |
8374 // Start an animation from one number to another | |
8375 custom: function( from, to, unit ) { | |
8376 var self = this, | |
8377 fx = jQuery.fx, | |
8378 raf; | |
8379 | |
8380 this.startTime = fxNow || createFxNow(); | |
8381 this.start = from; | |
8382 this.end = to; | |
8383 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); | |
8384 this.now = this.start; | |
8385 this.pos = this.state = 0; | |
8386 | |
8387 function t( gotoEnd ) { | |
8388 return self.step(gotoEnd); | |
8389 } | |
8390 | |
8391 t.elem = this.elem; | |
8392 | |
8393 if ( t() && jQuery.timers.push(t) && !timerId ) { | |
8394 // Use requestAnimationFrame instead of setInterval if available | |
8395 if ( requestAnimationFrame ) { | |
8396 timerId = true; | |
8397 raf = function() { | |
8398 // When timerId gets set to null at any point, this stops | |
8399 if ( timerId ) { | |
8400 requestAnimationFrame( raf ); | |
8401 fx.tick(); | |
8402 } | |
8403 }; | |
8404 requestAnimationFrame( raf ); | |
8405 } else { | |
8406 timerId = setInterval( fx.tick, fx.interval ); | |
8407 } | |
8408 } | |
8409 }, | |
8410 | |
8411 // Simple 'show' function | |
8412 show: function() { | |
8413 // Remember where we started, so that we can go back to it later | |
8414 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); | |
8415 this.options.show = true; | |
8416 | |
8417 // Begin the animation | |
8418 // Make sure that we start at a small width/height to avoid any | |
8419 // flash of content | |
8420 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur()); | |
8421 | |
8422 // Start by showing the element | |
8423 jQuery( this.elem ).show(); | |
8424 }, | |
8425 | |
8426 // Simple 'hide' function | |
8427 hide: function() { | |
8428 // Remember where we started, so that we can go back to it later | |
8429 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); | |
8430 this.options.hide = true; | |
8431 | |
8432 // Begin the animation | |
8433 this.custom(this.cur(), 0); | |
8434 }, | |
8435 | |
8436 // Each step of an animation | |
8437 step: function( gotoEnd ) { | |
8438 var t = fxNow || createFxNow(), | |
8439 done = true, | |
8440 elem = this.elem, | |
8441 options = this.options, | |
8442 i, n; | |
8443 | |
8444 if ( gotoEnd || t >= options.duration + this.startTime ) { | |
8445 this.now = this.end; | |
8446 this.pos = this.state = 1; | |
8447 this.update(); | |
8448 | |
8449 options.animatedProperties[ this.prop ] = true; | |
8450 | |
8451 for ( i in options.animatedProperties ) { | |
8452 if ( options.animatedProperties[i] !== true ) { | |
8453 done = false; | |
8454 } | |
8455 } | |
8456 | |
8457 if ( done ) { | |
8458 // Reset the overflow | |
8459 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { | |
8460 | |
8461 jQuery.each( [ "", "X", "Y" ], function (index, value) { | |
8462 elem.style[ "overflow" + value ] = options.overflow[index]; | |
8463 }); | |
8464 } | |
8465 | |
8466 // Hide the element if the "hide" operation was done | |
8467 if ( options.hide ) { | |
8468 jQuery(elem).hide(); | |
8469 } | |
8470 | |
8471 // Reset the properties, if the item has been hidden or shown | |
8472 if ( options.hide || options.show ) { | |
8473 for ( var p in options.animatedProperties ) { | |
8474 jQuery.style( elem, p, options.orig[p] ); | |
8475 } | |
8476 } | |
8477 | |
8478 // Execute the complete function | |
8479 options.complete.call( elem ); | |
8480 } | |
8481 | |
8482 return false; | |
8483 | |
8484 } else { | |
8485 // classical easing cannot be used with an Infinity duration | |
8486 if ( options.duration == Infinity ) { | |
8487 this.now = t; | |
8488 } else { | |
8489 n = t - this.startTime; | |
8490 this.state = n / options.duration; | |
8491 | |
8492 // Perform the easing function, defaults to swing | |
8493 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration ); | |
8494 this.now = this.start + ((this.end - this.start) * this.pos); | |
8495 } | |
8496 // Perform the next step of the animation | |
8497 this.update(); | |
8498 } | |
8499 | |
8500 return true; | |
8501 } | |
8502 }; | |
8503 | |
8504 jQuery.extend( jQuery.fx, { | |
8505 tick: function() { | |
8506 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) { | |
8507 if ( !timers[i]() ) { | |
8508 timers.splice(i--, 1); | |
8509 } | |
8510 } | |
8511 | |
8512 if ( !timers.length ) { | |
8513 jQuery.fx.stop(); | |
8514 } | |
8515 }, | |
8516 | |
8517 interval: 13, | |
8518 | |
8519 stop: function() { | |
8520 clearInterval( timerId ); | |
8521 timerId = null; | |
8522 }, | |
8523 | |
8524 speeds: { | |
8525 slow: 600, | |
8526 fast: 200, | |
8527 // Default speed | |
8528 _default: 400 | |
8529 }, | |
8530 | |
8531 step: { | |
8532 opacity: function( fx ) { | |
8533 jQuery.style( fx.elem, "opacity", fx.now ); | |
8534 }, | |
8535 | |
8536 _default: function( fx ) { | |
8537 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { | |
8538 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit; | |
8539 } else { | |
8540 fx.elem[ fx.prop ] = fx.now; | |
8541 } | |
8542 } | |
8543 } | |
8544 }); | |
8545 | |
8546 if ( jQuery.expr && jQuery.expr.filters ) { | |
8547 jQuery.expr.filters.animated = function( elem ) { | |
8548 return jQuery.grep(jQuery.timers, function( fn ) { | |
8549 return elem === fn.elem; | |
8550 }).length; | |
8551 }; | |
8552 } | |
8553 | |
8554 // Try to restore the default display value of an element | |
8555 function defaultDisplay( nodeName ) { | |
8556 | |
8557 if ( !elemdisplay[ nodeName ] ) { | |
8558 | |
8559 var body = document.body, | |
8560 elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), | |
8561 display = elem.css( "display" ); | |
8562 | |
8563 elem.remove(); | |
8564 | |
8565 // If the simple way fails, | |
8566 // get element's real default display by attaching it to a temp iframe | |
8567 if ( display === "none" || display === "" ) { | |
8568 // No iframe to use yet, so create it | |
8569 if ( !iframe ) { | |
8570 iframe = document.createElement( "iframe" ); | |
8571 iframe.frameBorder = iframe.width = iframe.height = 0; | |
8572 } | |
8573 | |
8574 body.appendChild( iframe ); | |
8575 | |
8576 // Create a cacheable copy of the iframe document on first call. | |
8577 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML | |
8578 // document to it; WebKit & Firefox won't allow reusing the iframe document. | |
8579 if ( !iframeDoc || !iframe.createElement ) { | |
8580 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; | |
8581 iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" ); | |
8582 iframeDoc.close(); | |
8583 } | |
8584 | |
8585 elem = iframeDoc.createElement( nodeName ); | |
8586 | |
8587 iframeDoc.body.appendChild( elem ); | |
8588 | |
8589 display = jQuery.css( elem, "display" ); | |
8590 | |
8591 body.removeChild( iframe ); | |
8592 } | |
8593 | |
8594 // Store the correct default display | |
8595 elemdisplay[ nodeName ] = display; | |
8596 } | |
8597 | |
8598 return elemdisplay[ nodeName ]; | |
8599 } | |
8600 | |
8601 | |
8602 | |
8603 | |
8604 var rtable = /^t(?:able|d|h)$/i, | |
8605 rroot = /^(?:body|html)$/i; | |
8606 | |
8607 if ( "getBoundingClientRect" in document.documentElement ) { | |
8608 jQuery.fn.offset = function( options ) { | |
8609 var elem = this[0], box; | |
8610 | |
8611 if ( options ) { | |
8612 return this.each(function( i ) { | |
8613 jQuery.offset.setOffset( this, options, i ); | |
8614 }); | |
8615 } | |
8616 | |
8617 if ( !elem || !elem.ownerDocument ) { | |
8618 return null; | |
8619 } | |
8620 | |
8621 if ( elem === elem.ownerDocument.body ) { | |
8622 return jQuery.offset.bodyOffset( elem ); | |
8623 } | |
8624 | |
8625 try { | |
8626 box = elem.getBoundingClientRect(); | |
8627 } catch(e) {} | |
8628 | |
8629 var doc = elem.ownerDocument, | |
8630 docElem = doc.documentElement; | |
8631 | |
8632 // Make sure we're not dealing with a disconnected DOM node | |
8633 if ( !box || !jQuery.contains( docElem, elem ) ) { | |
8634 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; | |
8635 } | |
8636 | |
8637 var body = doc.body, | |
8638 win = getWindow(doc), | |
8639 clientTop = docElem.clientTop || body.clientTop || 0, | |
8640 clientLeft = docElem.clientLeft || body.clientLeft || 0, | |
8641 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, | |
8642 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, | |
8643 top = box.top + scrollTop - clientTop, | |
8644 left = box.left + scrollLeft - clientLeft; | |
8645 | |
8646 return { top: top, left: left }; | |
8647 }; | |
8648 | |
8649 } else { | |
8650 jQuery.fn.offset = function( options ) { | |
8651 var elem = this[0]; | |
8652 | |
8653 if ( options ) { | |
8654 return this.each(function( i ) { | |
8655 jQuery.offset.setOffset( this, options, i ); | |
8656 }); | |
8657 } | |
8658 | |
8659 if ( !elem || !elem.ownerDocument ) { | |
8660 return null; | |
8661 } | |
8662 | |
8663 if ( elem === elem.ownerDocument.body ) { | |
8664 return jQuery.offset.bodyOffset( elem ); | |
8665 } | |
8666 | |
8667 jQuery.offset.initialize(); | |
8668 | |
8669 var computedStyle, | |
8670 offsetParent = elem.offsetParent, | |
8671 prevOffsetParent = elem, | |
8672 doc = elem.ownerDocument, | |
8673 docElem = doc.documentElement, | |
8674 body = doc.body, | |
8675 defaultView = doc.defaultView, | |
8676 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, | |
8677 top = elem.offsetTop, | |
8678 left = elem.offsetLeft; | |
8679 | |
8680 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { | |
8681 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { | |
8682 break; | |
8683 } | |
8684 | |
8685 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; | |
8686 top -= elem.scrollTop; | |
8687 left -= elem.scrollLeft; | |
8688 | |
8689 if ( elem === offsetParent ) { | |
8690 top += elem.offsetTop; | |
8691 left += elem.offsetLeft; | |
8692 | |
8693 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { | |
8694 top += parseFloat( computedStyle.borderTopWidth ) || 0; | |
8695 left += parseFloat( computedStyle.borderLeftWidth ) || 0; | |
8696 } | |
8697 | |
8698 prevOffsetParent = offsetParent; | |
8699 offsetParent = elem.offsetParent; | |
8700 } | |
8701 | |
8702 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { | |
8703 top += parseFloat( computedStyle.borderTopWidth ) || 0; | |
8704 left += parseFloat( computedStyle.borderLeftWidth ) || 0; | |
8705 } | |
8706 | |
8707 prevComputedStyle = computedStyle; | |
8708 } | |
8709 | |
8710 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { | |
8711 top += body.offsetTop; | |
8712 left += body.offsetLeft; | |
8713 } | |
8714 | |
8715 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { | |
8716 top += Math.max( docElem.scrollTop, body.scrollTop ); | |
8717 left += Math.max( docElem.scrollLeft, body.scrollLeft ); | |
8718 } | |
8719 | |
8720 return { top: top, left: left }; | |
8721 }; | |
8722 } | |
8723 | |
8724 jQuery.offset = { | |
8725 initialize: function() { | |
8726 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0, | |
8727 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; | |
8728 | |
8729 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } ); | |
8730 | |
8731 container.innerHTML = html; | |
8732 body.insertBefore( container, body.firstChild ); | |
8733 innerDiv = container.firstChild; | |
8734 checkDiv = innerDiv.firstChild; | |
8735 td = innerDiv.nextSibling.firstChild.firstChild; | |
8736 | |
8737 this.doesNotAddBorder = (checkDiv.offsetTop !== 5); | |
8738 this.doesAddBorderForTableAndCells = (td.offsetTop === 5); | |
8739 | |
8740 checkDiv.style.position = "fixed"; | |
8741 checkDiv.style.top = "20px"; | |
8742 | |
8743 // safari subtracts parent border width here which is 5px | |
8744 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); | |
8745 checkDiv.style.position = checkDiv.style.top = ""; | |
8746 | |
8747 innerDiv.style.overflow = "hidden"; | |
8748 innerDiv.style.position = "relative"; | |
8749 | |
8750 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); | |
8751 | |
8752 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); | |
8753 | |
8754 body.removeChild( container ); | |
8755 jQuery.offset.initialize = jQuery.noop; | |
8756 }, | |
8757 | |
8758 bodyOffset: function( body ) { | |
8759 var top = body.offsetTop, | |
8760 left = body.offsetLeft; | |
8761 | |
8762 jQuery.offset.initialize(); | |
8763 | |
8764 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) { | |
8765 top += parseFloat( jQuery.css(body, "marginTop") ) || 0; | |
8766 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; | |
8767 } | |
8768 | |
8769 return { top: top, left: left }; | |
8770 }, | |
8771 | |
8772 setOffset: function( elem, options, i ) { | |
8773 var position = jQuery.css( elem, "position" ); | |
8774 | |
8775 // set position first, in-case top/left are set even on static elem | |
8776 if ( position === "static" ) { | |
8777 elem.style.position = "relative"; | |
8778 } | |
8779 | |
8780 var curElem = jQuery( elem ), | |
8781 curOffset = curElem.offset(), | |
8782 curCSSTop = jQuery.css( elem, "top" ), | |
8783 curCSSLeft = jQuery.css( elem, "left" ), | |
8784 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, | |
8785 props = {}, curPosition = {}, curTop, curLeft; | |
8786 | |
8787 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed | |
8788 if ( calculatePosition ) { | |
8789 curPosition = curElem.position(); | |
8790 curTop = curPosition.top; | |
8791 curLeft = curPosition.left; | |
8792 } else { | |
8793 curTop = parseFloat( curCSSTop ) || 0; | |
8794 curLeft = parseFloat( curCSSLeft ) || 0; | |
8795 } | |
8796 | |
8797 if ( jQuery.isFunction( options ) ) { | |
8798 options = options.call( elem, i, curOffset ); | |
8799 } | |
8800 | |
8801 if (options.top != null) { | |
8802 props.top = (options.top - curOffset.top) + curTop; | |
8803 } | |
8804 if (options.left != null) { | |
8805 props.left = (options.left - curOffset.left) + curLeft; | |
8806 } | |
8807 | |
8808 if ( "using" in options ) { | |
8809 options.using.call( elem, props ); | |
8810 } else { | |
8811 curElem.css( props ); | |
8812 } | |
8813 } | |
8814 }; | |
8815 | |
8816 | |
8817 jQuery.fn.extend({ | |
8818 position: function() { | |
8819 if ( !this[0] ) { | |
8820 return null; | |
8821 } | |
8822 | |
8823 var elem = this[0], | |
8824 | |
8825 // Get *real* offsetParent | |
8826 offsetParent = this.offsetParent(), | |
8827 | |
8828 // Get correct offsets | |
8829 offset = this.offset(), | |
8830 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); | |
8831 | |
8832 // Subtract element margins | |
8833 // note: when an element has margin: auto the offsetLeft and marginLeft | |
8834 // are the same in Safari causing offset.left to incorrectly be 0 | |
8835 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; | |
8836 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; | |
8837 | |
8838 // Add offsetParent borders | |
8839 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; | |
8840 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; | |
8841 | |
8842 // Subtract the two offsets | |
8843 return { | |
8844 top: offset.top - parentOffset.top, | |
8845 left: offset.left - parentOffset.left | |
8846 }; | |
8847 }, | |
8848 | |
8849 offsetParent: function() { | |
8850 return this.map(function() { | |
8851 var offsetParent = this.offsetParent || document.body; | |
8852 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { | |
8853 offsetParent = offsetParent.offsetParent; | |
8854 } | |
8855 return offsetParent; | |
8856 }); | |
8857 } | |
8858 }); | |
8859 | |
8860 | |
8861 // Create scrollLeft and scrollTop methods | |
8862 jQuery.each( ["Left", "Top"], function( i, name ) { | |
8863 var method = "scroll" + name; | |
8864 | |
8865 jQuery.fn[ method ] = function( val ) { | |
8866 var elem, win; | |
8867 | |
8868 if ( val === undefined ) { | |
8869 elem = this[ 0 ]; | |
8870 | |
8871 if ( !elem ) { | |
8872 return null; | |
8873 } | |
8874 | |
8875 win = getWindow( elem ); | |
8876 | |
8877 // Return the scroll offset | |
8878 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : | |
8879 jQuery.support.boxModel && win.document.documentElement[ method ] || | |
8880 win.document.body[ method ] : | |
8881 elem[ method ]; | |
8882 } | |
8883 | |
8884 // Set the scroll offset | |
8885 return this.each(function() { | |
8886 win = getWindow( this ); | |
8887 | |
8888 if ( win ) { | |
8889 win.scrollTo( | |
8890 !i ? val : jQuery( win ).scrollLeft(), | |
8891 i ? val : jQuery( win ).scrollTop() | |
8892 ); | |
8893 | |
8894 } else { | |
8895 this[ method ] = val; | |
8896 } | |
8897 }); | |
8898 }; | |
8899 }); | |
8900 | |
8901 function getWindow( elem ) { | |
8902 return jQuery.isWindow( elem ) ? | |
8903 elem : | |
8904 elem.nodeType === 9 ? | |
8905 elem.defaultView || elem.parentWindow : | |
8906 false; | |
8907 } | |
8908 | |
8909 | |
8910 | |
8911 | |
8912 // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods | |
8913 jQuery.each([ "Height", "Width" ], function( i, name ) { | |
8914 | |
8915 var type = name.toLowerCase(); | |
8916 | |
8917 // innerHeight and innerWidth | |
8918 jQuery.fn[ "inner" + name ] = function() { | |
8919 var elem = this[0]; | |
8920 return elem && elem.style ? | |
8921 parseFloat( jQuery.css( elem, type, "padding" ) ) : | |
8922 null; | |
8923 }; | |
8924 | |
8925 // outerHeight and outerWidth | |
8926 jQuery.fn[ "outer" + name ] = function( margin ) { | |
8927 var elem = this[0]; | |
8928 return elem && elem.style ? | |
8929 parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : | |
8930 null; | |
8931 }; | |
8932 | |
8933 jQuery.fn[ type ] = function( size ) { | |
8934 // Get window width or height | |
8935 var elem = this[0]; | |
8936 if ( !elem ) { | |
8937 return size == null ? null : this; | |
8938 } | |
8939 | |
8940 if ( jQuery.isFunction( size ) ) { | |
8941 return this.each(function( i ) { | |
8942 var self = jQuery( this ); | |
8943 self[ type ]( size.call( this, i, self[ type ]() ) ); | |
8944 }); | |
8945 } | |
8946 | |
8947 if ( jQuery.isWindow( elem ) ) { | |
8948 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode | |
8949 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat | |
8950 var docElemProp = elem.document.documentElement[ "client" + name ]; | |
8951 return elem.document.compatMode === "CSS1Compat" && docElemProp || | |
8952 elem.document.body[ "client" + name ] || docElemProp; | |
8953 | |
8954 // Get document width or height | |
8955 } else if ( elem.nodeType === 9 ) { | |
8956 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater | |
8957 return Math.max( | |
8958 elem.documentElement["client" + name], | |
8959 elem.body["scroll" + name], elem.documentElement["scroll" + name], | |
8960 elem.body["offset" + name], elem.documentElement["offset" + name] | |
8961 ); | |
8962 | |
8963 // Get or set width or height on the element | |
8964 } else if ( size === undefined ) { | |
8965 var orig = jQuery.css( elem, type ), | |
8966 ret = parseFloat( orig ); | |
8967 | |
8968 return jQuery.isNaN( ret ) ? orig : ret; | |
8969 | |
8970 // Set the width or height on the element (default to pixels if value is unitless) | |
8971 } else { | |
8972 return this.css( type, typeof size === "string" ? size : size + "px" ); | |
8973 } | |
8974 }; | |
8975 | |
8976 }); | |
8977 | |
8978 | |
8979 // Expose jQuery to the global object | |
8980 window.jQuery = window.$ = jQuery; | |
8981 })(window); |