Mercurial > repos > saskia-hiltemann > ireport
comparison DataTables-1.9.4/docs/media/js/jquery.js @ 0:ac5f9272033b draft
first upload
author | saskia-hiltemann |
---|---|
date | Tue, 01 Jul 2014 11:42:23 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ac5f9272033b |
---|---|
1 /*! | |
2 * jQuery JavaScript Library v1.5.1 | |
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: Wed Feb 23 13:55:29 2011 -0500 | |
15 */ | |
16 (function( window, undefined ) { | |
17 | |
18 // Use the correct document accordingly with window argument (sandbox) | |
19 var document = window.document; | |
20 var jQuery = (function() { | |
21 | |
22 // Define a local copy of jQuery | |
23 var jQuery = function( selector, context ) { | |
24 // The jQuery object is actually just the init constructor 'enhanced' | |
25 return new jQuery.fn.init( selector, context, rootjQuery ); | |
26 }, | |
27 | |
28 // Map over jQuery in case of overwrite | |
29 _jQuery = window.jQuery, | |
30 | |
31 // Map over the $ in case of overwrite | |
32 _$ = window.$, | |
33 | |
34 // A central reference to the root jQuery(document) | |
35 rootjQuery, | |
36 | |
37 // A simple way to check for HTML strings or ID strings | |
38 // (both of which we optimize for) | |
39 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, | |
40 | |
41 // Check if a string has a non-whitespace character in it | |
42 rnotwhite = /\S/, | |
43 | |
44 // Used for trimming whitespace | |
45 trimLeft = /^\s+/, | |
46 trimRight = /\s+$/, | |
47 | |
48 // Check for digits | |
49 rdigit = /\d/, | |
50 | |
51 // Match a standalone tag | |
52 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, | |
53 | |
54 // JSON RegExp | |
55 rvalidchars = /^[\],:{}\s]*$/, | |
56 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, | |
57 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, | |
58 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, | |
59 | |
60 // Useragent RegExp | |
61 rwebkit = /(webkit)[ \/]([\w.]+)/, | |
62 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, | |
63 rmsie = /(msie) ([\w.]+)/, | |
64 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, | |
65 | |
66 // Keep a UserAgent string for use with jQuery.browser | |
67 userAgent = navigator.userAgent, | |
68 | |
69 // For matching the engine and version of the browser | |
70 browserMatch, | |
71 | |
72 // Has the ready events already been bound? | |
73 readyBound = false, | |
74 | |
75 // The deferred used on DOM ready | |
76 readyList, | |
77 | |
78 // Promise methods | |
79 promiseMethods = "then done fail isResolved isRejected promise".split( " " ), | |
80 | |
81 // The ready event handler | |
82 DOMContentLoaded, | |
83 | |
84 // Save a reference to some core methods | |
85 toString = Object.prototype.toString, | |
86 hasOwn = Object.prototype.hasOwnProperty, | |
87 push = Array.prototype.push, | |
88 slice = Array.prototype.slice, | |
89 trim = String.prototype.trim, | |
90 indexOf = Array.prototype.indexOf, | |
91 | |
92 // [[Class]] -> type pairs | |
93 class2type = {}; | |
94 | |
95 jQuery.fn = jQuery.prototype = { | |
96 constructor: jQuery, | |
97 init: function( selector, context, rootjQuery ) { | |
98 var match, elem, ret, doc; | |
99 | |
100 // Handle $(""), $(null), or $(undefined) | |
101 if ( !selector ) { | |
102 return this; | |
103 } | |
104 | |
105 // Handle $(DOMElement) | |
106 if ( selector.nodeType ) { | |
107 this.context = this[0] = selector; | |
108 this.length = 1; | |
109 return this; | |
110 } | |
111 | |
112 // The body element only exists once, optimize finding it | |
113 if ( selector === "body" && !context && document.body ) { | |
114 this.context = document; | |
115 this[0] = document.body; | |
116 this.selector = "body"; | |
117 this.length = 1; | |
118 return this; | |
119 } | |
120 | |
121 // Handle HTML strings | |
122 if ( typeof selector === "string" ) { | |
123 // Are we dealing with HTML string or an ID? | |
124 match = quickExpr.exec( selector ); | |
125 | |
126 // Verify a match, and that no context was specified for #id | |
127 if ( match && (match[1] || !context) ) { | |
128 | |
129 // HANDLE: $(html) -> $(array) | |
130 if ( match[1] ) { | |
131 context = context instanceof jQuery ? context[0] : context; | |
132 doc = (context ? context.ownerDocument || context : document); | |
133 | |
134 // If a single string is passed in and it's a single tag | |
135 // just do a createElement and skip the rest | |
136 ret = rsingleTag.exec( selector ); | |
137 | |
138 if ( ret ) { | |
139 if ( jQuery.isPlainObject( context ) ) { | |
140 selector = [ document.createElement( ret[1] ) ]; | |
141 jQuery.fn.attr.call( selector, context, true ); | |
142 | |
143 } else { | |
144 selector = [ doc.createElement( ret[1] ) ]; | |
145 } | |
146 | |
147 } else { | |
148 ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); | |
149 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; | |
150 } | |
151 | |
152 return jQuery.merge( this, selector ); | |
153 | |
154 // HANDLE: $("#id") | |
155 } else { | |
156 elem = document.getElementById( match[2] ); | |
157 | |
158 // Check parentNode to catch when Blackberry 4.6 returns | |
159 // nodes that are no longer in the document #6963 | |
160 if ( elem && elem.parentNode ) { | |
161 // Handle the case where IE and Opera return items | |
162 // by name instead of ID | |
163 if ( elem.id !== match[2] ) { | |
164 return rootjQuery.find( selector ); | |
165 } | |
166 | |
167 // Otherwise, we inject the element directly into the jQuery object | |
168 this.length = 1; | |
169 this[0] = elem; | |
170 } | |
171 | |
172 this.context = document; | |
173 this.selector = selector; | |
174 return this; | |
175 } | |
176 | |
177 // HANDLE: $(expr, $(...)) | |
178 } else if ( !context || context.jquery ) { | |
179 return (context || rootjQuery).find( selector ); | |
180 | |
181 // HANDLE: $(expr, context) | |
182 // (which is just equivalent to: $(context).find(expr) | |
183 } else { | |
184 return this.constructor( context ).find( selector ); | |
185 } | |
186 | |
187 // HANDLE: $(function) | |
188 // Shortcut for document ready | |
189 } else if ( jQuery.isFunction( selector ) ) { | |
190 return rootjQuery.ready( selector ); | |
191 } | |
192 | |
193 if (selector.selector !== undefined) { | |
194 this.selector = selector.selector; | |
195 this.context = selector.context; | |
196 } | |
197 | |
198 return jQuery.makeArray( selector, this ); | |
199 }, | |
200 | |
201 // Start with an empty selector | |
202 selector: "", | |
203 | |
204 // The current version of jQuery being used | |
205 jquery: "1.5.1", | |
206 | |
207 // The default length of a jQuery object is 0 | |
208 length: 0, | |
209 | |
210 // The number of elements contained in the matched element set | |
211 size: function() { | |
212 return this.length; | |
213 }, | |
214 | |
215 toArray: function() { | |
216 return slice.call( this, 0 ); | |
217 }, | |
218 | |
219 // Get the Nth element in the matched element set OR | |
220 // Get the whole matched element set as a clean array | |
221 get: function( num ) { | |
222 return num == null ? | |
223 | |
224 // Return a 'clean' array | |
225 this.toArray() : | |
226 | |
227 // Return just the object | |
228 ( num < 0 ? this[ this.length + num ] : this[ num ] ); | |
229 }, | |
230 | |
231 // Take an array of elements and push it onto the stack | |
232 // (returning the new matched element set) | |
233 pushStack: function( elems, name, selector ) { | |
234 // Build a new jQuery matched element set | |
235 var ret = this.constructor(); | |
236 | |
237 if ( jQuery.isArray( elems ) ) { | |
238 push.apply( ret, elems ); | |
239 | |
240 } else { | |
241 jQuery.merge( ret, elems ); | |
242 } | |
243 | |
244 // Add the old object onto the stack (as a reference) | |
245 ret.prevObject = this; | |
246 | |
247 ret.context = this.context; | |
248 | |
249 if ( name === "find" ) { | |
250 ret.selector = this.selector + (this.selector ? " " : "") + selector; | |
251 } else if ( name ) { | |
252 ret.selector = this.selector + "." + name + "(" + selector + ")"; | |
253 } | |
254 | |
255 // Return the newly-formed element set | |
256 return ret; | |
257 }, | |
258 | |
259 // Execute a callback for every element in the matched set. | |
260 // (You can seed the arguments with an array of args, but this is | |
261 // only used internally.) | |
262 each: function( callback, args ) { | |
263 return jQuery.each( this, callback, args ); | |
264 }, | |
265 | |
266 ready: function( fn ) { | |
267 // Attach the listeners | |
268 jQuery.bindReady(); | |
269 | |
270 // Add the callback | |
271 readyList.done( fn ); | |
272 | |
273 return this; | |
274 }, | |
275 | |
276 eq: function( i ) { | |
277 return i === -1 ? | |
278 this.slice( i ) : | |
279 this.slice( i, +i + 1 ); | |
280 }, | |
281 | |
282 first: function() { | |
283 return this.eq( 0 ); | |
284 }, | |
285 | |
286 last: function() { | |
287 return this.eq( -1 ); | |
288 }, | |
289 | |
290 slice: function() { | |
291 return this.pushStack( slice.apply( this, arguments ), | |
292 "slice", slice.call(arguments).join(",") ); | |
293 }, | |
294 | |
295 map: function( callback ) { | |
296 return this.pushStack( jQuery.map(this, function( elem, i ) { | |
297 return callback.call( elem, i, elem ); | |
298 })); | |
299 }, | |
300 | |
301 end: function() { | |
302 return this.prevObject || this.constructor(null); | |
303 }, | |
304 | |
305 // For internal use only. | |
306 // Behaves like an Array's method, not like a jQuery method. | |
307 push: push, | |
308 sort: [].sort, | |
309 splice: [].splice | |
310 }; | |
311 | |
312 // Give the init function the jQuery prototype for later instantiation | |
313 jQuery.fn.init.prototype = jQuery.fn; | |
314 | |
315 jQuery.extend = jQuery.fn.extend = function() { | |
316 var options, name, src, copy, copyIsArray, clone, | |
317 target = arguments[0] || {}, | |
318 i = 1, | |
319 length = arguments.length, | |
320 deep = false; | |
321 | |
322 // Handle a deep copy situation | |
323 if ( typeof target === "boolean" ) { | |
324 deep = target; | |
325 target = arguments[1] || {}; | |
326 // skip the boolean and the target | |
327 i = 2; | |
328 } | |
329 | |
330 // Handle case when target is a string or something (possible in deep copy) | |
331 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { | |
332 target = {}; | |
333 } | |
334 | |
335 // extend jQuery itself if only one argument is passed | |
336 if ( length === i ) { | |
337 target = this; | |
338 --i; | |
339 } | |
340 | |
341 for ( ; i < length; i++ ) { | |
342 // Only deal with non-null/undefined values | |
343 if ( (options = arguments[ i ]) != null ) { | |
344 // Extend the base object | |
345 for ( name in options ) { | |
346 src = target[ name ]; | |
347 copy = options[ name ]; | |
348 | |
349 // Prevent never-ending loop | |
350 if ( target === copy ) { | |
351 continue; | |
352 } | |
353 | |
354 // Recurse if we're merging plain objects or arrays | |
355 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { | |
356 if ( copyIsArray ) { | |
357 copyIsArray = false; | |
358 clone = src && jQuery.isArray(src) ? src : []; | |
359 | |
360 } else { | |
361 clone = src && jQuery.isPlainObject(src) ? src : {}; | |
362 } | |
363 | |
364 // Never move original objects, clone them | |
365 target[ name ] = jQuery.extend( deep, clone, copy ); | |
366 | |
367 // Don't bring in undefined values | |
368 } else if ( copy !== undefined ) { | |
369 target[ name ] = copy; | |
370 } | |
371 } | |
372 } | |
373 } | |
374 | |
375 // Return the modified object | |
376 return target; | |
377 }; | |
378 | |
379 jQuery.extend({ | |
380 noConflict: function( deep ) { | |
381 window.$ = _$; | |
382 | |
383 if ( deep ) { | |
384 window.jQuery = _jQuery; | |
385 } | |
386 | |
387 return jQuery; | |
388 }, | |
389 | |
390 // Is the DOM ready to be used? Set to true once it occurs. | |
391 isReady: false, | |
392 | |
393 // A counter to track how many items to wait for before | |
394 // the ready event fires. See #6781 | |
395 readyWait: 1, | |
396 | |
397 // Handle when the DOM is ready | |
398 ready: function( wait ) { | |
399 // A third-party is pushing the ready event forwards | |
400 if ( wait === true ) { | |
401 jQuery.readyWait--; | |
402 } | |
403 | |
404 // Make sure that the DOM is not already loaded | |
405 if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { | |
406 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). | |
407 if ( !document.body ) { | |
408 return setTimeout( jQuery.ready, 1 ); | |
409 } | |
410 | |
411 // Remember that the DOM is ready | |
412 jQuery.isReady = true; | |
413 | |
414 // If a normal DOM Ready event fired, decrement, and wait if need be | |
415 if ( wait !== true && --jQuery.readyWait > 0 ) { | |
416 return; | |
417 } | |
418 | |
419 // If there are functions bound, to execute | |
420 readyList.resolveWith( document, [ jQuery ] ); | |
421 | |
422 // Trigger any bound ready events | |
423 if ( jQuery.fn.trigger ) { | |
424 jQuery( document ).trigger( "ready" ).unbind( "ready" ); | |
425 } | |
426 } | |
427 }, | |
428 | |
429 bindReady: function() { | |
430 if ( readyBound ) { | |
431 return; | |
432 } | |
433 | |
434 readyBound = true; | |
435 | |
436 // Catch cases where $(document).ready() is called after the | |
437 // browser event has already occurred. | |
438 if ( document.readyState === "complete" ) { | |
439 // Handle it asynchronously to allow scripts the opportunity to delay ready | |
440 return setTimeout( jQuery.ready, 1 ); | |
441 } | |
442 | |
443 // Mozilla, Opera and webkit nightlies currently support this event | |
444 if ( document.addEventListener ) { | |
445 // Use the handy event callback | |
446 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); | |
447 | |
448 // A fallback to window.onload, that will always work | |
449 window.addEventListener( "load", jQuery.ready, false ); | |
450 | |
451 // If IE event model is used | |
452 } else if ( document.attachEvent ) { | |
453 // ensure firing before onload, | |
454 // maybe late but safe also for iframes | |
455 document.attachEvent("onreadystatechange", DOMContentLoaded); | |
456 | |
457 // A fallback to window.onload, that will always work | |
458 window.attachEvent( "onload", jQuery.ready ); | |
459 | |
460 // If IE and not a frame | |
461 // continually check to see if the document is ready | |
462 var toplevel = false; | |
463 | |
464 try { | |
465 toplevel = window.frameElement == null; | |
466 } catch(e) {} | |
467 | |
468 if ( document.documentElement.doScroll && toplevel ) { | |
469 doScrollCheck(); | |
470 } | |
471 } | |
472 }, | |
473 | |
474 // See test/unit/core.js for details concerning isFunction. | |
475 // Since version 1.3, DOM methods and functions like alert | |
476 // aren't supported. They return false on IE (#2968). | |
477 isFunction: function( obj ) { | |
478 return jQuery.type(obj) === "function"; | |
479 }, | |
480 | |
481 isArray: Array.isArray || function( obj ) { | |
482 return jQuery.type(obj) === "array"; | |
483 }, | |
484 | |
485 // A crude way of determining if an object is a window | |
486 isWindow: function( obj ) { | |
487 return obj && typeof obj === "object" && "setInterval" in obj; | |
488 }, | |
489 | |
490 isNaN: function( obj ) { | |
491 return obj == null || !rdigit.test( obj ) || isNaN( obj ); | |
492 }, | |
493 | |
494 type: function( obj ) { | |
495 return obj == null ? | |
496 String( obj ) : | |
497 class2type[ toString.call(obj) ] || "object"; | |
498 }, | |
499 | |
500 isPlainObject: function( obj ) { | |
501 // Must be an Object. | |
502 // Because of IE, we also have to check the presence of the constructor property. | |
503 // Make sure that DOM nodes and window objects don't pass through, as well | |
504 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { | |
505 return false; | |
506 } | |
507 | |
508 // Not own constructor property must be Object | |
509 if ( obj.constructor && | |
510 !hasOwn.call(obj, "constructor") && | |
511 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { | |
512 return false; | |
513 } | |
514 | |
515 // Own properties are enumerated firstly, so to speed up, | |
516 // if last one is own, then all properties are own. | |
517 | |
518 var key; | |
519 for ( key in obj ) {} | |
520 | |
521 return key === undefined || hasOwn.call( obj, key ); | |
522 }, | |
523 | |
524 isEmptyObject: function( obj ) { | |
525 for ( var name in obj ) { | |
526 return false; | |
527 } | |
528 return true; | |
529 }, | |
530 | |
531 error: function( msg ) { | |
532 throw msg; | |
533 }, | |
534 | |
535 parseJSON: function( data ) { | |
536 if ( typeof data !== "string" || !data ) { | |
537 return null; | |
538 } | |
539 | |
540 // Make sure leading/trailing whitespace is removed (IE can't handle it) | |
541 data = jQuery.trim( data ); | |
542 | |
543 // Make sure the incoming data is actual JSON | |
544 // Logic borrowed from http://json.org/json2.js | |
545 if ( rvalidchars.test(data.replace(rvalidescape, "@") | |
546 .replace(rvalidtokens, "]") | |
547 .replace(rvalidbraces, "")) ) { | |
548 | |
549 // Try to use the native JSON parser first | |
550 return window.JSON && window.JSON.parse ? | |
551 window.JSON.parse( data ) : | |
552 (new Function("return " + data))(); | |
553 | |
554 } else { | |
555 jQuery.error( "Invalid JSON: " + data ); | |
556 } | |
557 }, | |
558 | |
559 // Cross-browser xml parsing | |
560 // (xml & tmp used internally) | |
561 parseXML: function( data , xml , tmp ) { | |
562 | |
563 if ( window.DOMParser ) { // Standard | |
564 tmp = new DOMParser(); | |
565 xml = tmp.parseFromString( data , "text/xml" ); | |
566 } else { // IE | |
567 xml = new ActiveXObject( "Microsoft.XMLDOM" ); | |
568 xml.async = "false"; | |
569 xml.loadXML( data ); | |
570 } | |
571 | |
572 tmp = xml.documentElement; | |
573 | |
574 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { | |
575 jQuery.error( "Invalid XML: " + data ); | |
576 } | |
577 | |
578 return xml; | |
579 }, | |
580 | |
581 noop: function() {}, | |
582 | |
583 // Evalulates a script in a global context | |
584 globalEval: function( data ) { | |
585 if ( data && rnotwhite.test(data) ) { | |
586 // Inspired by code by Andrea Giammarchi | |
587 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html | |
588 var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, | |
589 script = document.createElement( "script" ); | |
590 | |
591 if ( jQuery.support.scriptEval() ) { | |
592 script.appendChild( document.createTextNode( data ) ); | |
593 } else { | |
594 script.text = data; | |
595 } | |
596 | |
597 // Use insertBefore instead of appendChild to circumvent an IE6 bug. | |
598 // This arises when a base node is used (#2709). | |
599 head.insertBefore( script, head.firstChild ); | |
600 head.removeChild( script ); | |
601 } | |
602 }, | |
603 | |
604 nodeName: function( elem, name ) { | |
605 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); | |
606 }, | |
607 | |
608 // args is for internal usage only | |
609 each: function( object, callback, args ) { | |
610 var name, i = 0, | |
611 length = object.length, | |
612 isObj = length === undefined || jQuery.isFunction(object); | |
613 | |
614 if ( args ) { | |
615 if ( isObj ) { | |
616 for ( name in object ) { | |
617 if ( callback.apply( object[ name ], args ) === false ) { | |
618 break; | |
619 } | |
620 } | |
621 } else { | |
622 for ( ; i < length; ) { | |
623 if ( callback.apply( object[ i++ ], args ) === false ) { | |
624 break; | |
625 } | |
626 } | |
627 } | |
628 | |
629 // A special, fast, case for the most common use of each | |
630 } else { | |
631 if ( isObj ) { | |
632 for ( name in object ) { | |
633 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { | |
634 break; | |
635 } | |
636 } | |
637 } else { | |
638 for ( var value = object[0]; | |
639 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} | |
640 } | |
641 } | |
642 | |
643 return object; | |
644 }, | |
645 | |
646 // Use native String.trim function wherever possible | |
647 trim: trim ? | |
648 function( text ) { | |
649 return text == null ? | |
650 "" : | |
651 trim.call( text ); | |
652 } : | |
653 | |
654 // Otherwise use our own trimming functionality | |
655 function( text ) { | |
656 return text == null ? | |
657 "" : | |
658 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); | |
659 }, | |
660 | |
661 // results is for internal usage only | |
662 makeArray: function( array, results ) { | |
663 var ret = results || []; | |
664 | |
665 if ( array != null ) { | |
666 // The window, strings (and functions) also have 'length' | |
667 // The extra typeof function check is to prevent crashes | |
668 // in Safari 2 (See: #3039) | |
669 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 | |
670 var type = jQuery.type(array); | |
671 | |
672 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { | |
673 push.call( ret, array ); | |
674 } else { | |
675 jQuery.merge( ret, array ); | |
676 } | |
677 } | |
678 | |
679 return ret; | |
680 }, | |
681 | |
682 inArray: function( elem, array ) { | |
683 if ( array.indexOf ) { | |
684 return array.indexOf( elem ); | |
685 } | |
686 | |
687 for ( var i = 0, length = array.length; i < length; i++ ) { | |
688 if ( array[ i ] === elem ) { | |
689 return i; | |
690 } | |
691 } | |
692 | |
693 return -1; | |
694 }, | |
695 | |
696 merge: function( first, second ) { | |
697 var i = first.length, | |
698 j = 0; | |
699 | |
700 if ( typeof second.length === "number" ) { | |
701 for ( var l = second.length; j < l; j++ ) { | |
702 first[ i++ ] = second[ j ]; | |
703 } | |
704 | |
705 } else { | |
706 while ( second[j] !== undefined ) { | |
707 first[ i++ ] = second[ j++ ]; | |
708 } | |
709 } | |
710 | |
711 first.length = i; | |
712 | |
713 return first; | |
714 }, | |
715 | |
716 grep: function( elems, callback, inv ) { | |
717 var ret = [], retVal; | |
718 inv = !!inv; | |
719 | |
720 // Go through the array, only saving the items | |
721 // that pass the validator function | |
722 for ( var i = 0, length = elems.length; i < length; i++ ) { | |
723 retVal = !!callback( elems[ i ], i ); | |
724 if ( inv !== retVal ) { | |
725 ret.push( elems[ i ] ); | |
726 } | |
727 } | |
728 | |
729 return ret; | |
730 }, | |
731 | |
732 // arg is for internal usage only | |
733 map: function( elems, callback, arg ) { | |
734 var ret = [], value; | |
735 | |
736 // Go through the array, translating each of the items to their | |
737 // new value (or values). | |
738 for ( var i = 0, length = elems.length; i < length; i++ ) { | |
739 value = callback( elems[ i ], i, arg ); | |
740 | |
741 if ( value != null ) { | |
742 ret[ ret.length ] = value; | |
743 } | |
744 } | |
745 | |
746 // Flatten any nested arrays | |
747 return ret.concat.apply( [], ret ); | |
748 }, | |
749 | |
750 // A global GUID counter for objects | |
751 guid: 1, | |
752 | |
753 proxy: function( fn, proxy, thisObject ) { | |
754 if ( arguments.length === 2 ) { | |
755 if ( typeof proxy === "string" ) { | |
756 thisObject = fn; | |
757 fn = thisObject[ proxy ]; | |
758 proxy = undefined; | |
759 | |
760 } else if ( proxy && !jQuery.isFunction( proxy ) ) { | |
761 thisObject = proxy; | |
762 proxy = undefined; | |
763 } | |
764 } | |
765 | |
766 if ( !proxy && fn ) { | |
767 proxy = function() { | |
768 return fn.apply( thisObject || this, arguments ); | |
769 }; | |
770 } | |
771 | |
772 // Set the guid of unique handler to the same of original handler, so it can be removed | |
773 if ( fn ) { | |
774 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; | |
775 } | |
776 | |
777 // So proxy can be declared as an argument | |
778 return proxy; | |
779 }, | |
780 | |
781 // Mutifunctional method to get and set values to a collection | |
782 // The value/s can be optionally by executed if its a function | |
783 access: function( elems, key, value, exec, fn, pass ) { | |
784 var length = elems.length; | |
785 | |
786 // Setting many attributes | |
787 if ( typeof key === "object" ) { | |
788 for ( var k in key ) { | |
789 jQuery.access( elems, k, key[k], exec, fn, value ); | |
790 } | |
791 return elems; | |
792 } | |
793 | |
794 // Setting one attribute | |
795 if ( value !== undefined ) { | |
796 // Optionally, function values get executed if exec is true | |
797 exec = !pass && exec && jQuery.isFunction(value); | |
798 | |
799 for ( var i = 0; i < length; i++ ) { | |
800 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); | |
801 } | |
802 | |
803 return elems; | |
804 } | |
805 | |
806 // Getting an attribute | |
807 return length ? fn( elems[0], key ) : undefined; | |
808 }, | |
809 | |
810 now: function() { | |
811 return (new Date()).getTime(); | |
812 }, | |
813 | |
814 // Create a simple deferred (one callbacks list) | |
815 _Deferred: function() { | |
816 var // callbacks list | |
817 callbacks = [], | |
818 // stored [ context , args ] | |
819 fired, | |
820 // to avoid firing when already doing so | |
821 firing, | |
822 // flag to know if the deferred has been cancelled | |
823 cancelled, | |
824 // the deferred itself | |
825 deferred = { | |
826 | |
827 // done( f1, f2, ...) | |
828 done: function() { | |
829 if ( !cancelled ) { | |
830 var args = arguments, | |
831 i, | |
832 length, | |
833 elem, | |
834 type, | |
835 _fired; | |
836 if ( fired ) { | |
837 _fired = fired; | |
838 fired = 0; | |
839 } | |
840 for ( i = 0, length = args.length; i < length; i++ ) { | |
841 elem = args[ i ]; | |
842 type = jQuery.type( elem ); | |
843 if ( type === "array" ) { | |
844 deferred.done.apply( deferred, elem ); | |
845 } else if ( type === "function" ) { | |
846 callbacks.push( elem ); | |
847 } | |
848 } | |
849 if ( _fired ) { | |
850 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); | |
851 } | |
852 } | |
853 return this; | |
854 }, | |
855 | |
856 // resolve with given context and args | |
857 resolveWith: function( context, args ) { | |
858 if ( !cancelled && !fired && !firing ) { | |
859 firing = 1; | |
860 try { | |
861 while( callbacks[ 0 ] ) { | |
862 callbacks.shift().apply( context, args ); | |
863 } | |
864 } | |
865 // We have to add a catch block for | |
866 // IE prior to 8 or else the finally | |
867 // block will never get executed | |
868 catch (e) { | |
869 throw e; | |
870 } | |
871 finally { | |
872 fired = [ context, args ]; | |
873 firing = 0; | |
874 } | |
875 } | |
876 return this; | |
877 }, | |
878 | |
879 // resolve with this as context and given arguments | |
880 resolve: function() { | |
881 deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments ); | |
882 return this; | |
883 }, | |
884 | |
885 // Has this deferred been resolved? | |
886 isResolved: function() { | |
887 return !!( firing || fired ); | |
888 }, | |
889 | |
890 // Cancel | |
891 cancel: function() { | |
892 cancelled = 1; | |
893 callbacks = []; | |
894 return this; | |
895 } | |
896 }; | |
897 | |
898 return deferred; | |
899 }, | |
900 | |
901 // Full fledged deferred (two callbacks list) | |
902 Deferred: function( func ) { | |
903 var deferred = jQuery._Deferred(), | |
904 failDeferred = jQuery._Deferred(), | |
905 promise; | |
906 // Add errorDeferred methods, then and promise | |
907 jQuery.extend( deferred, { | |
908 then: function( doneCallbacks, failCallbacks ) { | |
909 deferred.done( doneCallbacks ).fail( failCallbacks ); | |
910 return this; | |
911 }, | |
912 fail: failDeferred.done, | |
913 rejectWith: failDeferred.resolveWith, | |
914 reject: failDeferred.resolve, | |
915 isRejected: failDeferred.isResolved, | |
916 // Get a promise for this deferred | |
917 // If obj is provided, the promise aspect is added to the object | |
918 promise: function( obj ) { | |
919 if ( obj == null ) { | |
920 if ( promise ) { | |
921 return promise; | |
922 } | |
923 promise = obj = {}; | |
924 } | |
925 var i = promiseMethods.length; | |
926 while( i-- ) { | |
927 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; | |
928 } | |
929 return obj; | |
930 } | |
931 } ); | |
932 // Make sure only one callback list will be used | |
933 deferred.done( failDeferred.cancel ).fail( deferred.cancel ); | |
934 // Unexpose cancel | |
935 delete deferred.cancel; | |
936 // Call given func if any | |
937 if ( func ) { | |
938 func.call( deferred, deferred ); | |
939 } | |
940 return deferred; | |
941 }, | |
942 | |
943 // Deferred helper | |
944 when: function( object ) { | |
945 var lastIndex = arguments.length, | |
946 deferred = lastIndex <= 1 && object && jQuery.isFunction( object.promise ) ? | |
947 object : | |
948 jQuery.Deferred(), | |
949 promise = deferred.promise(); | |
950 | |
951 if ( lastIndex > 1 ) { | |
952 var array = slice.call( arguments, 0 ), | |
953 count = lastIndex, | |
954 iCallback = function( index ) { | |
955 return function( value ) { | |
956 array[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; | |
957 if ( !( --count ) ) { | |
958 deferred.resolveWith( promise, array ); | |
959 } | |
960 }; | |
961 }; | |
962 while( ( lastIndex-- ) ) { | |
963 object = array[ lastIndex ]; | |
964 if ( object && jQuery.isFunction( object.promise ) ) { | |
965 object.promise().then( iCallback(lastIndex), deferred.reject ); | |
966 } else { | |
967 --count; | |
968 } | |
969 } | |
970 if ( !count ) { | |
971 deferred.resolveWith( promise, array ); | |
972 } | |
973 } else if ( deferred !== object ) { | |
974 deferred.resolve( object ); | |
975 } | |
976 return promise; | |
977 }, | |
978 | |
979 // Use of jQuery.browser is frowned upon. | |
980 // More details: http://docs.jquery.com/Utilities/jQuery.browser | |
981 uaMatch: function( ua ) { | |
982 ua = ua.toLowerCase(); | |
983 | |
984 var match = rwebkit.exec( ua ) || | |
985 ropera.exec( ua ) || | |
986 rmsie.exec( ua ) || | |
987 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || | |
988 []; | |
989 | |
990 return { browser: match[1] || "", version: match[2] || "0" }; | |
991 }, | |
992 | |
993 sub: function() { | |
994 function jQuerySubclass( selector, context ) { | |
995 return new jQuerySubclass.fn.init( selector, context ); | |
996 } | |
997 jQuery.extend( true, jQuerySubclass, this ); | |
998 jQuerySubclass.superclass = this; | |
999 jQuerySubclass.fn = jQuerySubclass.prototype = this(); | |
1000 jQuerySubclass.fn.constructor = jQuerySubclass; | |
1001 jQuerySubclass.subclass = this.subclass; | |
1002 jQuerySubclass.fn.init = function init( selector, context ) { | |
1003 if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { | |
1004 context = jQuerySubclass(context); | |
1005 } | |
1006 | |
1007 return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); | |
1008 }; | |
1009 jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; | |
1010 var rootjQuerySubclass = jQuerySubclass(document); | |
1011 return jQuerySubclass; | |
1012 }, | |
1013 | |
1014 browser: {} | |
1015 }); | |
1016 | |
1017 // Create readyList deferred | |
1018 readyList = jQuery._Deferred(); | |
1019 | |
1020 // Populate the class2type map | |
1021 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { | |
1022 class2type[ "[object " + name + "]" ] = name.toLowerCase(); | |
1023 }); | |
1024 | |
1025 browserMatch = jQuery.uaMatch( userAgent ); | |
1026 if ( browserMatch.browser ) { | |
1027 jQuery.browser[ browserMatch.browser ] = true; | |
1028 jQuery.browser.version = browserMatch.version; | |
1029 } | |
1030 | |
1031 // Deprecated, use jQuery.browser.webkit instead | |
1032 if ( jQuery.browser.webkit ) { | |
1033 jQuery.browser.safari = true; | |
1034 } | |
1035 | |
1036 if ( indexOf ) { | |
1037 jQuery.inArray = function( elem, array ) { | |
1038 return indexOf.call( array, elem ); | |
1039 }; | |
1040 } | |
1041 | |
1042 // IE doesn't match non-breaking spaces with \s | |
1043 if ( rnotwhite.test( "\xA0" ) ) { | |
1044 trimLeft = /^[\s\xA0]+/; | |
1045 trimRight = /[\s\xA0]+$/; | |
1046 } | |
1047 | |
1048 // All jQuery objects should point back to these | |
1049 rootjQuery = jQuery(document); | |
1050 | |
1051 // Cleanup functions for the document ready method | |
1052 if ( document.addEventListener ) { | |
1053 DOMContentLoaded = function() { | |
1054 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); | |
1055 jQuery.ready(); | |
1056 }; | |
1057 | |
1058 } else if ( document.attachEvent ) { | |
1059 DOMContentLoaded = function() { | |
1060 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). | |
1061 if ( document.readyState === "complete" ) { | |
1062 document.detachEvent( "onreadystatechange", DOMContentLoaded ); | |
1063 jQuery.ready(); | |
1064 } | |
1065 }; | |
1066 } | |
1067 | |
1068 // The DOM ready check for Internet Explorer | |
1069 function doScrollCheck() { | |
1070 if ( jQuery.isReady ) { | |
1071 return; | |
1072 } | |
1073 | |
1074 try { | |
1075 // If IE is used, use the trick by Diego Perini | |
1076 // http://javascript.nwbox.com/IEContentLoaded/ | |
1077 document.documentElement.doScroll("left"); | |
1078 } catch(e) { | |
1079 setTimeout( doScrollCheck, 1 ); | |
1080 return; | |
1081 } | |
1082 | |
1083 // and execute any waiting functions | |
1084 jQuery.ready(); | |
1085 } | |
1086 | |
1087 // Expose jQuery to the global object | |
1088 return jQuery; | |
1089 | |
1090 })(); | |
1091 | |
1092 | |
1093 (function() { | |
1094 | |
1095 jQuery.support = {}; | |
1096 | |
1097 var div = document.createElement("div"); | |
1098 | |
1099 div.style.display = "none"; | |
1100 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; | |
1101 | |
1102 var all = div.getElementsByTagName("*"), | |
1103 a = div.getElementsByTagName("a")[0], | |
1104 select = document.createElement("select"), | |
1105 opt = select.appendChild( document.createElement("option") ), | |
1106 input = div.getElementsByTagName("input")[0]; | |
1107 | |
1108 // Can't get basic test support | |
1109 if ( !all || !all.length || !a ) { | |
1110 return; | |
1111 } | |
1112 | |
1113 jQuery.support = { | |
1114 // IE strips leading whitespace when .innerHTML is used | |
1115 leadingWhitespace: div.firstChild.nodeType === 3, | |
1116 | |
1117 // Make sure that tbody elements aren't automatically inserted | |
1118 // IE will insert them into empty tables | |
1119 tbody: !div.getElementsByTagName("tbody").length, | |
1120 | |
1121 // Make sure that link elements get serialized correctly by innerHTML | |
1122 // This requires a wrapper element in IE | |
1123 htmlSerialize: !!div.getElementsByTagName("link").length, | |
1124 | |
1125 // Get the style information from getAttribute | |
1126 // (IE uses .cssText insted) | |
1127 style: /red/.test( a.getAttribute("style") ), | |
1128 | |
1129 // Make sure that URLs aren't manipulated | |
1130 // (IE normalizes it by default) | |
1131 hrefNormalized: a.getAttribute("href") === "/a", | |
1132 | |
1133 // Make sure that element opacity exists | |
1134 // (IE uses filter instead) | |
1135 // Use a regex to work around a WebKit issue. See #5145 | |
1136 opacity: /^0.55$/.test( a.style.opacity ), | |
1137 | |
1138 // Verify style float existence | |
1139 // (IE uses styleFloat instead of cssFloat) | |
1140 cssFloat: !!a.style.cssFloat, | |
1141 | |
1142 // Make sure that if no value is specified for a checkbox | |
1143 // that it defaults to "on". | |
1144 // (WebKit defaults to "" instead) | |
1145 checkOn: input.value === "on", | |
1146 | |
1147 // Make sure that a selected-by-default option has a working selected property. | |
1148 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) | |
1149 optSelected: opt.selected, | |
1150 | |
1151 // Will be defined later | |
1152 deleteExpando: true, | |
1153 optDisabled: false, | |
1154 checkClone: false, | |
1155 noCloneEvent: true, | |
1156 noCloneChecked: true, | |
1157 boxModel: null, | |
1158 inlineBlockNeedsLayout: false, | |
1159 shrinkWrapBlocks: false, | |
1160 reliableHiddenOffsets: true | |
1161 }; | |
1162 | |
1163 input.checked = true; | |
1164 jQuery.support.noCloneChecked = input.cloneNode( true ).checked; | |
1165 | |
1166 // Make sure that the options inside disabled selects aren't marked as disabled | |
1167 // (WebKit marks them as diabled) | |
1168 select.disabled = true; | |
1169 jQuery.support.optDisabled = !opt.disabled; | |
1170 | |
1171 var _scriptEval = null; | |
1172 jQuery.support.scriptEval = function() { | |
1173 if ( _scriptEval === null ) { | |
1174 var root = document.documentElement, | |
1175 script = document.createElement("script"), | |
1176 id = "script" + jQuery.now(); | |
1177 | |
1178 try { | |
1179 script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); | |
1180 } catch(e) {} | |
1181 | |
1182 root.insertBefore( script, root.firstChild ); | |
1183 | |
1184 // Make sure that the execution of code works by injecting a script | |
1185 // tag with appendChild/createTextNode | |
1186 // (IE doesn't support this, fails, and uses .text instead) | |
1187 if ( window[ id ] ) { | |
1188 _scriptEval = true; | |
1189 delete window[ id ]; | |
1190 } else { | |
1191 _scriptEval = false; | |
1192 } | |
1193 | |
1194 root.removeChild( script ); | |
1195 // release memory in IE | |
1196 root = script = id = null; | |
1197 } | |
1198 | |
1199 return _scriptEval; | |
1200 }; | |
1201 | |
1202 // Test to see if it's possible to delete an expando from an element | |
1203 // Fails in Internet Explorer | |
1204 try { | |
1205 delete div.test; | |
1206 | |
1207 } catch(e) { | |
1208 jQuery.support.deleteExpando = false; | |
1209 } | |
1210 | |
1211 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { | |
1212 div.attachEvent("onclick", function click() { | |
1213 // Cloning a node shouldn't copy over any | |
1214 // bound event handlers (IE does this) | |
1215 jQuery.support.noCloneEvent = false; | |
1216 div.detachEvent("onclick", click); | |
1217 }); | |
1218 div.cloneNode(true).fireEvent("onclick"); | |
1219 } | |
1220 | |
1221 div = document.createElement("div"); | |
1222 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>"; | |
1223 | |
1224 var fragment = document.createDocumentFragment(); | |
1225 fragment.appendChild( div.firstChild ); | |
1226 | |
1227 // WebKit doesn't clone checked state correctly in fragments | |
1228 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; | |
1229 | |
1230 // Figure out if the W3C box model works as expected | |
1231 // document.body must exist before we can do this | |
1232 jQuery(function() { | |
1233 var div = document.createElement("div"), | |
1234 body = document.getElementsByTagName("body")[0]; | |
1235 | |
1236 // Frameset documents with no body should not run this code | |
1237 if ( !body ) { | |
1238 return; | |
1239 } | |
1240 | |
1241 div.style.width = div.style.paddingLeft = "1px"; | |
1242 body.appendChild( div ); | |
1243 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; | |
1244 | |
1245 if ( "zoom" in div.style ) { | |
1246 // Check if natively block-level elements act like inline-block | |
1247 // elements when setting their display to 'inline' and giving | |
1248 // them layout | |
1249 // (IE < 8 does this) | |
1250 div.style.display = "inline"; | |
1251 div.style.zoom = 1; | |
1252 jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; | |
1253 | |
1254 // Check if elements with layout shrink-wrap their children | |
1255 // (IE 6 does this) | |
1256 div.style.display = ""; | |
1257 div.innerHTML = "<div style='width:4px;'></div>"; | |
1258 jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; | |
1259 } | |
1260 | |
1261 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>"; | |
1262 var tds = div.getElementsByTagName("td"); | |
1263 | |
1264 // Check if table cells still have offsetWidth/Height when they are set | |
1265 // to display:none and there are still other visible table cells in a | |
1266 // table row; if so, offsetWidth/Height are not reliable for use when | |
1267 // determining if an element has been hidden directly using | |
1268 // display:none (it is still safe to use offsets if a parent element is | |
1269 // hidden; don safety goggles and see bug #4512 for more information). | |
1270 // (only IE 8 fails this test) | |
1271 jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; | |
1272 | |
1273 tds[0].style.display = ""; | |
1274 tds[1].style.display = "none"; | |
1275 | |
1276 // Check if empty table cells still have offsetWidth/Height | |
1277 // (IE < 8 fail this test) | |
1278 jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; | |
1279 div.innerHTML = ""; | |
1280 | |
1281 body.removeChild( div ).style.display = "none"; | |
1282 div = tds = null; | |
1283 }); | |
1284 | |
1285 // Technique from Juriy Zaytsev | |
1286 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ | |
1287 var eventSupported = function( eventName ) { | |
1288 var el = document.createElement("div"); | |
1289 eventName = "on" + eventName; | |
1290 | |
1291 // We only care about the case where non-standard event systems | |
1292 // are used, namely in IE. Short-circuiting here helps us to | |
1293 // avoid an eval call (in setAttribute) which can cause CSP | |
1294 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP | |
1295 if ( !el.attachEvent ) { | |
1296 return true; | |
1297 } | |
1298 | |
1299 var isSupported = (eventName in el); | |
1300 if ( !isSupported ) { | |
1301 el.setAttribute(eventName, "return;"); | |
1302 isSupported = typeof el[eventName] === "function"; | |
1303 } | |
1304 el = null; | |
1305 | |
1306 return isSupported; | |
1307 }; | |
1308 | |
1309 jQuery.support.submitBubbles = eventSupported("submit"); | |
1310 jQuery.support.changeBubbles = eventSupported("change"); | |
1311 | |
1312 // release memory in IE | |
1313 div = all = a = null; | |
1314 })(); | |
1315 | |
1316 | |
1317 | |
1318 var rbrace = /^(?:\{.*\}|\[.*\])$/; | |
1319 | |
1320 jQuery.extend({ | |
1321 cache: {}, | |
1322 | |
1323 // Please use with caution | |
1324 uuid: 0, | |
1325 | |
1326 // Unique for each copy of jQuery on the page | |
1327 // Non-digits removed to match rinlinejQuery | |
1328 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), | |
1329 | |
1330 // The following elements throw uncatchable exceptions if you | |
1331 // attempt to add expando properties to them. | |
1332 noData: { | |
1333 "embed": true, | |
1334 // Ban all objects except for Flash (which handle expandos) | |
1335 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", | |
1336 "applet": true | |
1337 }, | |
1338 | |
1339 hasData: function( elem ) { | |
1340 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; | |
1341 | |
1342 return !!elem && !isEmptyDataObject( elem ); | |
1343 }, | |
1344 | |
1345 data: function( elem, name, data, pvt /* Internal Use Only */ ) { | |
1346 if ( !jQuery.acceptData( elem ) ) { | |
1347 return; | |
1348 } | |
1349 | |
1350 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, | |
1351 | |
1352 // We have to handle DOM nodes and JS objects differently because IE6-7 | |
1353 // can't GC object references properly across the DOM-JS boundary | |
1354 isNode = elem.nodeType, | |
1355 | |
1356 // Only DOM nodes need the global jQuery cache; JS object data is | |
1357 // attached directly to the object so GC can occur automatically | |
1358 cache = isNode ? jQuery.cache : elem, | |
1359 | |
1360 // Only defining an ID for JS objects if its cache already exists allows | |
1361 // the code to shortcut on the same path as a DOM node with no cache | |
1362 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; | |
1363 | |
1364 // Avoid doing any more work than we need to when trying to get data on an | |
1365 // object that has no data at all | |
1366 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { | |
1367 return; | |
1368 } | |
1369 | |
1370 if ( !id ) { | |
1371 // Only DOM nodes need a new unique ID for each element since their data | |
1372 // ends up in the global cache | |
1373 if ( isNode ) { | |
1374 elem[ jQuery.expando ] = id = ++jQuery.uuid; | |
1375 } else { | |
1376 id = jQuery.expando; | |
1377 } | |
1378 } | |
1379 | |
1380 if ( !cache[ id ] ) { | |
1381 cache[ id ] = {}; | |
1382 | |
1383 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery | |
1384 // metadata on plain JS objects when the object is serialized using | |
1385 // JSON.stringify | |
1386 if ( !isNode ) { | |
1387 cache[ id ].toJSON = jQuery.noop; | |
1388 } | |
1389 } | |
1390 | |
1391 // An object can be passed to jQuery.data instead of a key/value pair; this gets | |
1392 // shallow copied over onto the existing cache | |
1393 if ( typeof name === "object" || typeof name === "function" ) { | |
1394 if ( pvt ) { | |
1395 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); | |
1396 } else { | |
1397 cache[ id ] = jQuery.extend(cache[ id ], name); | |
1398 } | |
1399 } | |
1400 | |
1401 thisCache = cache[ id ]; | |
1402 | |
1403 // Internal jQuery data is stored in a separate object inside the object's data | |
1404 // cache in order to avoid key collisions between internal data and user-defined | |
1405 // data | |
1406 if ( pvt ) { | |
1407 if ( !thisCache[ internalKey ] ) { | |
1408 thisCache[ internalKey ] = {}; | |
1409 } | |
1410 | |
1411 thisCache = thisCache[ internalKey ]; | |
1412 } | |
1413 | |
1414 if ( data !== undefined ) { | |
1415 thisCache[ name ] = data; | |
1416 } | |
1417 | |
1418 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should | |
1419 // not attempt to inspect the internal events object using jQuery.data, as this | |
1420 // internal data object is undocumented and subject to change. | |
1421 if ( name === "events" && !thisCache[name] ) { | |
1422 return thisCache[ internalKey ] && thisCache[ internalKey ].events; | |
1423 } | |
1424 | |
1425 return getByName ? thisCache[ name ] : thisCache; | |
1426 }, | |
1427 | |
1428 removeData: function( elem, name, pvt /* Internal Use Only */ ) { | |
1429 if ( !jQuery.acceptData( elem ) ) { | |
1430 return; | |
1431 } | |
1432 | |
1433 var internalKey = jQuery.expando, isNode = elem.nodeType, | |
1434 | |
1435 // See jQuery.data for more information | |
1436 cache = isNode ? jQuery.cache : elem, | |
1437 | |
1438 // See jQuery.data for more information | |
1439 id = isNode ? elem[ jQuery.expando ] : jQuery.expando; | |
1440 | |
1441 // If there is already no cache entry for this object, there is no | |
1442 // purpose in continuing | |
1443 if ( !cache[ id ] ) { | |
1444 return; | |
1445 } | |
1446 | |
1447 if ( name ) { | |
1448 var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; | |
1449 | |
1450 if ( thisCache ) { | |
1451 delete thisCache[ name ]; | |
1452 | |
1453 // If there is no data left in the cache, we want to continue | |
1454 // and let the cache object itself get destroyed | |
1455 if ( !isEmptyDataObject(thisCache) ) { | |
1456 return; | |
1457 } | |
1458 } | |
1459 } | |
1460 | |
1461 // See jQuery.data for more information | |
1462 if ( pvt ) { | |
1463 delete cache[ id ][ internalKey ]; | |
1464 | |
1465 // Don't destroy the parent cache unless the internal data object | |
1466 // had been the only thing left in it | |
1467 if ( !isEmptyDataObject(cache[ id ]) ) { | |
1468 return; | |
1469 } | |
1470 } | |
1471 | |
1472 var internalCache = cache[ id ][ internalKey ]; | |
1473 | |
1474 // Browsers that fail expando deletion also refuse to delete expandos on | |
1475 // the window, but it will allow it on all other JS objects; other browsers | |
1476 // don't care | |
1477 if ( jQuery.support.deleteExpando || cache != window ) { | |
1478 delete cache[ id ]; | |
1479 } else { | |
1480 cache[ id ] = null; | |
1481 } | |
1482 | |
1483 // We destroyed the entire user cache at once because it's faster than | |
1484 // iterating through each key, but we need to continue to persist internal | |
1485 // data if it existed | |
1486 if ( internalCache ) { | |
1487 cache[ id ] = {}; | |
1488 // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery | |
1489 // metadata on plain JS objects when the object is serialized using | |
1490 // JSON.stringify | |
1491 if ( !isNode ) { | |
1492 cache[ id ].toJSON = jQuery.noop; | |
1493 } | |
1494 | |
1495 cache[ id ][ internalKey ] = internalCache; | |
1496 | |
1497 // Otherwise, we need to eliminate the expando on the node to avoid | |
1498 // false lookups in the cache for entries that no longer exist | |
1499 } else if ( isNode ) { | |
1500 // IE does not allow us to delete expando properties from nodes, | |
1501 // nor does it have a removeAttribute function on Document nodes; | |
1502 // we must handle all of these cases | |
1503 if ( jQuery.support.deleteExpando ) { | |
1504 delete elem[ jQuery.expando ]; | |
1505 } else if ( elem.removeAttribute ) { | |
1506 elem.removeAttribute( jQuery.expando ); | |
1507 } else { | |
1508 elem[ jQuery.expando ] = null; | |
1509 } | |
1510 } | |
1511 }, | |
1512 | |
1513 // For internal use only. | |
1514 _data: function( elem, name, data ) { | |
1515 return jQuery.data( elem, name, data, true ); | |
1516 }, | |
1517 | |
1518 // A method for determining if a DOM node can handle the data expando | |
1519 acceptData: function( elem ) { | |
1520 if ( elem.nodeName ) { | |
1521 var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; | |
1522 | |
1523 if ( match ) { | |
1524 return !(match === true || elem.getAttribute("classid") !== match); | |
1525 } | |
1526 } | |
1527 | |
1528 return true; | |
1529 } | |
1530 }); | |
1531 | |
1532 jQuery.fn.extend({ | |
1533 data: function( key, value ) { | |
1534 var data = null; | |
1535 | |
1536 if ( typeof key === "undefined" ) { | |
1537 if ( this.length ) { | |
1538 data = jQuery.data( this[0] ); | |
1539 | |
1540 if ( this[0].nodeType === 1 ) { | |
1541 var attr = this[0].attributes, name; | |
1542 for ( var i = 0, l = attr.length; i < l; i++ ) { | |
1543 name = attr[i].name; | |
1544 | |
1545 if ( name.indexOf( "data-" ) === 0 ) { | |
1546 name = name.substr( 5 ); | |
1547 dataAttr( this[0], name, data[ name ] ); | |
1548 } | |
1549 } | |
1550 } | |
1551 } | |
1552 | |
1553 return data; | |
1554 | |
1555 } else if ( typeof key === "object" ) { | |
1556 return this.each(function() { | |
1557 jQuery.data( this, key ); | |
1558 }); | |
1559 } | |
1560 | |
1561 var parts = key.split("."); | |
1562 parts[1] = parts[1] ? "." + parts[1] : ""; | |
1563 | |
1564 if ( value === undefined ) { | |
1565 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); | |
1566 | |
1567 // Try to fetch any internally stored data first | |
1568 if ( data === undefined && this.length ) { | |
1569 data = jQuery.data( this[0], key ); | |
1570 data = dataAttr( this[0], key, data ); | |
1571 } | |
1572 | |
1573 return data === undefined && parts[1] ? | |
1574 this.data( parts[0] ) : | |
1575 data; | |
1576 | |
1577 } else { | |
1578 return this.each(function() { | |
1579 var $this = jQuery( this ), | |
1580 args = [ parts[0], value ]; | |
1581 | |
1582 $this.triggerHandler( "setData" + parts[1] + "!", args ); | |
1583 jQuery.data( this, key, value ); | |
1584 $this.triggerHandler( "changeData" + parts[1] + "!", args ); | |
1585 }); | |
1586 } | |
1587 }, | |
1588 | |
1589 removeData: function( key ) { | |
1590 return this.each(function() { | |
1591 jQuery.removeData( this, key ); | |
1592 }); | |
1593 } | |
1594 }); | |
1595 | |
1596 function dataAttr( elem, key, data ) { | |
1597 // If nothing was found internally, try to fetch any | |
1598 // data from the HTML5 data-* attribute | |
1599 if ( data === undefined && elem.nodeType === 1 ) { | |
1600 data = elem.getAttribute( "data-" + key ); | |
1601 | |
1602 if ( typeof data === "string" ) { | |
1603 try { | |
1604 data = data === "true" ? true : | |
1605 data === "false" ? false : | |
1606 data === "null" ? null : | |
1607 !jQuery.isNaN( data ) ? parseFloat( data ) : | |
1608 rbrace.test( data ) ? jQuery.parseJSON( data ) : | |
1609 data; | |
1610 } catch( e ) {} | |
1611 | |
1612 // Make sure we set the data so it isn't changed later | |
1613 jQuery.data( elem, key, data ); | |
1614 | |
1615 } else { | |
1616 data = undefined; | |
1617 } | |
1618 } | |
1619 | |
1620 return data; | |
1621 } | |
1622 | |
1623 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON | |
1624 // property to be considered empty objects; this property always exists in | |
1625 // order to make sure JSON.stringify does not expose internal metadata | |
1626 function isEmptyDataObject( obj ) { | |
1627 for ( var name in obj ) { | |
1628 if ( name !== "toJSON" ) { | |
1629 return false; | |
1630 } | |
1631 } | |
1632 | |
1633 return true; | |
1634 } | |
1635 | |
1636 | |
1637 | |
1638 | |
1639 jQuery.extend({ | |
1640 queue: function( elem, type, data ) { | |
1641 if ( !elem ) { | |
1642 return; | |
1643 } | |
1644 | |
1645 type = (type || "fx") + "queue"; | |
1646 var q = jQuery._data( elem, type ); | |
1647 | |
1648 // Speed up dequeue by getting out quickly if this is just a lookup | |
1649 if ( !data ) { | |
1650 return q || []; | |
1651 } | |
1652 | |
1653 if ( !q || jQuery.isArray(data) ) { | |
1654 q = jQuery._data( elem, type, jQuery.makeArray(data) ); | |
1655 | |
1656 } else { | |
1657 q.push( data ); | |
1658 } | |
1659 | |
1660 return q; | |
1661 }, | |
1662 | |
1663 dequeue: function( elem, type ) { | |
1664 type = type || "fx"; | |
1665 | |
1666 var queue = jQuery.queue( elem, type ), | |
1667 fn = queue.shift(); | |
1668 | |
1669 // If the fx queue is dequeued, always remove the progress sentinel | |
1670 if ( fn === "inprogress" ) { | |
1671 fn = queue.shift(); | |
1672 } | |
1673 | |
1674 if ( fn ) { | |
1675 // Add a progress sentinel to prevent the fx queue from being | |
1676 // automatically dequeued | |
1677 if ( type === "fx" ) { | |
1678 queue.unshift("inprogress"); | |
1679 } | |
1680 | |
1681 fn.call(elem, function() { | |
1682 jQuery.dequeue(elem, type); | |
1683 }); | |
1684 } | |
1685 | |
1686 if ( !queue.length ) { | |
1687 jQuery.removeData( elem, type + "queue", true ); | |
1688 } | |
1689 } | |
1690 }); | |
1691 | |
1692 jQuery.fn.extend({ | |
1693 queue: function( type, data ) { | |
1694 if ( typeof type !== "string" ) { | |
1695 data = type; | |
1696 type = "fx"; | |
1697 } | |
1698 | |
1699 if ( data === undefined ) { | |
1700 return jQuery.queue( this[0], type ); | |
1701 } | |
1702 return this.each(function( i ) { | |
1703 var queue = jQuery.queue( this, type, data ); | |
1704 | |
1705 if ( type === "fx" && queue[0] !== "inprogress" ) { | |
1706 jQuery.dequeue( this, type ); | |
1707 } | |
1708 }); | |
1709 }, | |
1710 dequeue: function( type ) { | |
1711 return this.each(function() { | |
1712 jQuery.dequeue( this, type ); | |
1713 }); | |
1714 }, | |
1715 | |
1716 // Based off of the plugin by Clint Helfers, with permission. | |
1717 // http://blindsignals.com/index.php/2009/07/jquery-delay/ | |
1718 delay: function( time, type ) { | |
1719 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; | |
1720 type = type || "fx"; | |
1721 | |
1722 return this.queue( type, function() { | |
1723 var elem = this; | |
1724 setTimeout(function() { | |
1725 jQuery.dequeue( elem, type ); | |
1726 }, time ); | |
1727 }); | |
1728 }, | |
1729 | |
1730 clearQueue: function( type ) { | |
1731 return this.queue( type || "fx", [] ); | |
1732 } | |
1733 }); | |
1734 | |
1735 | |
1736 | |
1737 | |
1738 var rclass = /[\n\t\r]/g, | |
1739 rspaces = /\s+/, | |
1740 rreturn = /\r/g, | |
1741 rspecialurl = /^(?:href|src|style)$/, | |
1742 rtype = /^(?:button|input)$/i, | |
1743 rfocusable = /^(?:button|input|object|select|textarea)$/i, | |
1744 rclickable = /^a(?:rea)?$/i, | |
1745 rradiocheck = /^(?:radio|checkbox)$/i; | |
1746 | |
1747 jQuery.props = { | |
1748 "for": "htmlFor", | |
1749 "class": "className", | |
1750 readonly: "readOnly", | |
1751 maxlength: "maxLength", | |
1752 cellspacing: "cellSpacing", | |
1753 rowspan: "rowSpan", | |
1754 colspan: "colSpan", | |
1755 tabindex: "tabIndex", | |
1756 usemap: "useMap", | |
1757 frameborder: "frameBorder" | |
1758 }; | |
1759 | |
1760 jQuery.fn.extend({ | |
1761 attr: function( name, value ) { | |
1762 return jQuery.access( this, name, value, true, jQuery.attr ); | |
1763 }, | |
1764 | |
1765 removeAttr: function( name, fn ) { | |
1766 return this.each(function(){ | |
1767 jQuery.attr( this, name, "" ); | |
1768 if ( this.nodeType === 1 ) { | |
1769 this.removeAttribute( name ); | |
1770 } | |
1771 }); | |
1772 }, | |
1773 | |
1774 addClass: function( value ) { | |
1775 if ( jQuery.isFunction(value) ) { | |
1776 return this.each(function(i) { | |
1777 var self = jQuery(this); | |
1778 self.addClass( value.call(this, i, self.attr("class")) ); | |
1779 }); | |
1780 } | |
1781 | |
1782 if ( value && typeof value === "string" ) { | |
1783 var classNames = (value || "").split( rspaces ); | |
1784 | |
1785 for ( var i = 0, l = this.length; i < l; i++ ) { | |
1786 var elem = this[i]; | |
1787 | |
1788 if ( elem.nodeType === 1 ) { | |
1789 if ( !elem.className ) { | |
1790 elem.className = value; | |
1791 | |
1792 } else { | |
1793 var className = " " + elem.className + " ", | |
1794 setClass = elem.className; | |
1795 | |
1796 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { | |
1797 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { | |
1798 setClass += " " + classNames[c]; | |
1799 } | |
1800 } | |
1801 elem.className = jQuery.trim( setClass ); | |
1802 } | |
1803 } | |
1804 } | |
1805 } | |
1806 | |
1807 return this; | |
1808 }, | |
1809 | |
1810 removeClass: function( value ) { | |
1811 if ( jQuery.isFunction(value) ) { | |
1812 return this.each(function(i) { | |
1813 var self = jQuery(this); | |
1814 self.removeClass( value.call(this, i, self.attr("class")) ); | |
1815 }); | |
1816 } | |
1817 | |
1818 if ( (value && typeof value === "string") || value === undefined ) { | |
1819 var classNames = (value || "").split( rspaces ); | |
1820 | |
1821 for ( var i = 0, l = this.length; i < l; i++ ) { | |
1822 var elem = this[i]; | |
1823 | |
1824 if ( elem.nodeType === 1 && elem.className ) { | |
1825 if ( value ) { | |
1826 var className = (" " + elem.className + " ").replace(rclass, " "); | |
1827 for ( var c = 0, cl = classNames.length; c < cl; c++ ) { | |
1828 className = className.replace(" " + classNames[c] + " ", " "); | |
1829 } | |
1830 elem.className = jQuery.trim( className ); | |
1831 | |
1832 } else { | |
1833 elem.className = ""; | |
1834 } | |
1835 } | |
1836 } | |
1837 } | |
1838 | |
1839 return this; | |
1840 }, | |
1841 | |
1842 toggleClass: function( value, stateVal ) { | |
1843 var type = typeof value, | |
1844 isBool = typeof stateVal === "boolean"; | |
1845 | |
1846 if ( jQuery.isFunction( value ) ) { | |
1847 return this.each(function(i) { | |
1848 var self = jQuery(this); | |
1849 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); | |
1850 }); | |
1851 } | |
1852 | |
1853 return this.each(function() { | |
1854 if ( type === "string" ) { | |
1855 // toggle individual class names | |
1856 var className, | |
1857 i = 0, | |
1858 self = jQuery( this ), | |
1859 state = stateVal, | |
1860 classNames = value.split( rspaces ); | |
1861 | |
1862 while ( (className = classNames[ i++ ]) ) { | |
1863 // check each className given, space seperated list | |
1864 state = isBool ? state : !self.hasClass( className ); | |
1865 self[ state ? "addClass" : "removeClass" ]( className ); | |
1866 } | |
1867 | |
1868 } else if ( type === "undefined" || type === "boolean" ) { | |
1869 if ( this.className ) { | |
1870 // store className if set | |
1871 jQuery._data( this, "__className__", this.className ); | |
1872 } | |
1873 | |
1874 // toggle whole className | |
1875 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; | |
1876 } | |
1877 }); | |
1878 }, | |
1879 | |
1880 hasClass: function( selector ) { | |
1881 var className = " " + selector + " "; | |
1882 for ( var i = 0, l = this.length; i < l; i++ ) { | |
1883 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { | |
1884 return true; | |
1885 } | |
1886 } | |
1887 | |
1888 return false; | |
1889 }, | |
1890 | |
1891 val: function( value ) { | |
1892 if ( !arguments.length ) { | |
1893 var elem = this[0]; | |
1894 | |
1895 if ( elem ) { | |
1896 if ( jQuery.nodeName( elem, "option" ) ) { | |
1897 // attributes.value is undefined in Blackberry 4.7 but | |
1898 // uses .value. See #6932 | |
1899 var val = elem.attributes.value; | |
1900 return !val || val.specified ? elem.value : elem.text; | |
1901 } | |
1902 | |
1903 // We need to handle select boxes special | |
1904 if ( jQuery.nodeName( elem, "select" ) ) { | |
1905 var index = elem.selectedIndex, | |
1906 values = [], | |
1907 options = elem.options, | |
1908 one = elem.type === "select-one"; | |
1909 | |
1910 // Nothing was selected | |
1911 if ( index < 0 ) { | |
1912 return null; | |
1913 } | |
1914 | |
1915 // Loop through all the selected options | |
1916 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { | |
1917 var option = options[ i ]; | |
1918 | |
1919 // Don't return options that are disabled or in a disabled optgroup | |
1920 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && | |
1921 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { | |
1922 | |
1923 // Get the specific value for the option | |
1924 value = jQuery(option).val(); | |
1925 | |
1926 // We don't need an array for one selects | |
1927 if ( one ) { | |
1928 return value; | |
1929 } | |
1930 | |
1931 // Multi-Selects return an array | |
1932 values.push( value ); | |
1933 } | |
1934 } | |
1935 | |
1936 // Fixes Bug #2551 -- select.val() broken in IE after form.reset() | |
1937 if ( one && !values.length && options.length ) { | |
1938 return jQuery( options[ index ] ).val(); | |
1939 } | |
1940 | |
1941 return values; | |
1942 } | |
1943 | |
1944 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified | |
1945 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { | |
1946 return elem.getAttribute("value") === null ? "on" : elem.value; | |
1947 } | |
1948 | |
1949 // Everything else, we just grab the value | |
1950 return (elem.value || "").replace(rreturn, ""); | |
1951 | |
1952 } | |
1953 | |
1954 return undefined; | |
1955 } | |
1956 | |
1957 var isFunction = jQuery.isFunction(value); | |
1958 | |
1959 return this.each(function(i) { | |
1960 var self = jQuery(this), val = value; | |
1961 | |
1962 if ( this.nodeType !== 1 ) { | |
1963 return; | |
1964 } | |
1965 | |
1966 if ( isFunction ) { | |
1967 val = value.call(this, i, self.val()); | |
1968 } | |
1969 | |
1970 // Treat null/undefined as ""; convert numbers to string | |
1971 if ( val == null ) { | |
1972 val = ""; | |
1973 } else if ( typeof val === "number" ) { | |
1974 val += ""; | |
1975 } else if ( jQuery.isArray(val) ) { | |
1976 val = jQuery.map(val, function (value) { | |
1977 return value == null ? "" : value + ""; | |
1978 }); | |
1979 } | |
1980 | |
1981 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { | |
1982 this.checked = jQuery.inArray( self.val(), val ) >= 0; | |
1983 | |
1984 } else if ( jQuery.nodeName( this, "select" ) ) { | |
1985 var values = jQuery.makeArray(val); | |
1986 | |
1987 jQuery( "option", this ).each(function() { | |
1988 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; | |
1989 }); | |
1990 | |
1991 if ( !values.length ) { | |
1992 this.selectedIndex = -1; | |
1993 } | |
1994 | |
1995 } else { | |
1996 this.value = val; | |
1997 } | |
1998 }); | |
1999 } | |
2000 }); | |
2001 | |
2002 jQuery.extend({ | |
2003 attrFn: { | |
2004 val: true, | |
2005 css: true, | |
2006 html: true, | |
2007 text: true, | |
2008 data: true, | |
2009 width: true, | |
2010 height: true, | |
2011 offset: true | |
2012 }, | |
2013 | |
2014 attr: function( elem, name, value, pass ) { | |
2015 // don't get/set attributes on text, comment and attribute nodes | |
2016 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { | |
2017 return undefined; | |
2018 } | |
2019 | |
2020 if ( pass && name in jQuery.attrFn ) { | |
2021 return jQuery(elem)[name](value); | |
2022 } | |
2023 | |
2024 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), | |
2025 // Whether we are setting (or getting) | |
2026 set = value !== undefined; | |
2027 | |
2028 // Try to normalize/fix the name | |
2029 name = notxml && jQuery.props[ name ] || name; | |
2030 | |
2031 // Only do all the following if this is a node (faster for style) | |
2032 if ( elem.nodeType === 1 ) { | |
2033 // These attributes require special treatment | |
2034 var special = rspecialurl.test( name ); | |
2035 | |
2036 // Safari mis-reports the default selected property of an option | |
2037 // Accessing the parent's selectedIndex property fixes it | |
2038 if ( name === "selected" && !jQuery.support.optSelected ) { | |
2039 var parent = elem.parentNode; | |
2040 if ( parent ) { | |
2041 parent.selectedIndex; | |
2042 | |
2043 // Make sure that it also works with optgroups, see #5701 | |
2044 if ( parent.parentNode ) { | |
2045 parent.parentNode.selectedIndex; | |
2046 } | |
2047 } | |
2048 } | |
2049 | |
2050 // If applicable, access the attribute via the DOM 0 way | |
2051 // 'in' checks fail in Blackberry 4.7 #6931 | |
2052 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { | |
2053 if ( set ) { | |
2054 // We can't allow the type property to be changed (since it causes problems in IE) | |
2055 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { | |
2056 jQuery.error( "type property can't be changed" ); | |
2057 } | |
2058 | |
2059 if ( value === null ) { | |
2060 if ( elem.nodeType === 1 ) { | |
2061 elem.removeAttribute( name ); | |
2062 } | |
2063 | |
2064 } else { | |
2065 elem[ name ] = value; | |
2066 } | |
2067 } | |
2068 | |
2069 // browsers index elements by id/name on forms, give priority to attributes. | |
2070 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { | |
2071 return elem.getAttributeNode( name ).nodeValue; | |
2072 } | |
2073 | |
2074 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set | |
2075 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ | |
2076 if ( name === "tabIndex" ) { | |
2077 var attributeNode = elem.getAttributeNode( "tabIndex" ); | |
2078 | |
2079 return attributeNode && attributeNode.specified ? | |
2080 attributeNode.value : | |
2081 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? | |
2082 0 : | |
2083 undefined; | |
2084 } | |
2085 | |
2086 return elem[ name ]; | |
2087 } | |
2088 | |
2089 if ( !jQuery.support.style && notxml && name === "style" ) { | |
2090 if ( set ) { | |
2091 elem.style.cssText = "" + value; | |
2092 } | |
2093 | |
2094 return elem.style.cssText; | |
2095 } | |
2096 | |
2097 if ( set ) { | |
2098 // convert the value to a string (all browsers do this but IE) see #1070 | |
2099 elem.setAttribute( name, "" + value ); | |
2100 } | |
2101 | |
2102 // Ensure that missing attributes return undefined | |
2103 // Blackberry 4.7 returns "" from getAttribute #6938 | |
2104 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { | |
2105 return undefined; | |
2106 } | |
2107 | |
2108 var attr = !jQuery.support.hrefNormalized && notxml && special ? | |
2109 // Some attributes require a special call on IE | |
2110 elem.getAttribute( name, 2 ) : | |
2111 elem.getAttribute( name ); | |
2112 | |
2113 // Non-existent attributes return null, we normalize to undefined | |
2114 return attr === null ? undefined : attr; | |
2115 } | |
2116 // Handle everything which isn't a DOM element node | |
2117 if ( set ) { | |
2118 elem[ name ] = value; | |
2119 } | |
2120 return elem[ name ]; | |
2121 } | |
2122 }); | |
2123 | |
2124 | |
2125 | |
2126 | |
2127 var rnamespaces = /\.(.*)$/, | |
2128 rformElems = /^(?:textarea|input|select)$/i, | |
2129 rperiod = /\./g, | |
2130 rspace = / /g, | |
2131 rescape = /[^\w\s.|`]/g, | |
2132 fcleanup = function( nm ) { | |
2133 return nm.replace(rescape, "\\$&"); | |
2134 }; | |
2135 | |
2136 /* | |
2137 * A number of helper functions used for managing events. | |
2138 * Many of the ideas behind this code originated from | |
2139 * Dean Edwards' addEvent library. | |
2140 */ | |
2141 jQuery.event = { | |
2142 | |
2143 // Bind an event to an element | |
2144 // Original by Dean Edwards | |
2145 add: function( elem, types, handler, data ) { | |
2146 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { | |
2147 return; | |
2148 } | |
2149 | |
2150 // TODO :: Use a try/catch until it's safe to pull this out (likely 1.6) | |
2151 // Minor release fix for bug #8018 | |
2152 try { | |
2153 // For whatever reason, IE has trouble passing the window object | |
2154 // around, causing it to be cloned in the process | |
2155 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { | |
2156 elem = window; | |
2157 } | |
2158 } | |
2159 catch ( e ) {} | |
2160 | |
2161 if ( handler === false ) { | |
2162 handler = returnFalse; | |
2163 } else if ( !handler ) { | |
2164 // Fixes bug #7229. Fix recommended by jdalton | |
2165 return; | |
2166 } | |
2167 | |
2168 var handleObjIn, handleObj; | |
2169 | |
2170 if ( handler.handler ) { | |
2171 handleObjIn = handler; | |
2172 handler = handleObjIn.handler; | |
2173 } | |
2174 | |
2175 // Make sure that the function being executed has a unique ID | |
2176 if ( !handler.guid ) { | |
2177 handler.guid = jQuery.guid++; | |
2178 } | |
2179 | |
2180 // Init the element's event structure | |
2181 var elemData = jQuery._data( elem ); | |
2182 | |
2183 // If no elemData is found then we must be trying to bind to one of the | |
2184 // banned noData elements | |
2185 if ( !elemData ) { | |
2186 return; | |
2187 } | |
2188 | |
2189 var events = elemData.events, | |
2190 eventHandle = elemData.handle; | |
2191 | |
2192 if ( !events ) { | |
2193 elemData.events = events = {}; | |
2194 } | |
2195 | |
2196 if ( !eventHandle ) { | |
2197 elemData.handle = eventHandle = function() { | |
2198 // Handle the second event of a trigger and when | |
2199 // an event is called after a page has unloaded | |
2200 return typeof jQuery !== "undefined" && !jQuery.event.triggered ? | |
2201 jQuery.event.handle.apply( eventHandle.elem, arguments ) : | |
2202 undefined; | |
2203 }; | |
2204 } | |
2205 | |
2206 // Add elem as a property of the handle function | |
2207 // This is to prevent a memory leak with non-native events in IE. | |
2208 eventHandle.elem = elem; | |
2209 | |
2210 // Handle multiple events separated by a space | |
2211 // jQuery(...).bind("mouseover mouseout", fn); | |
2212 types = types.split(" "); | |
2213 | |
2214 var type, i = 0, namespaces; | |
2215 | |
2216 while ( (type = types[ i++ ]) ) { | |
2217 handleObj = handleObjIn ? | |
2218 jQuery.extend({}, handleObjIn) : | |
2219 { handler: handler, data: data }; | |
2220 | |
2221 // Namespaced event handlers | |
2222 if ( type.indexOf(".") > -1 ) { | |
2223 namespaces = type.split("."); | |
2224 type = namespaces.shift(); | |
2225 handleObj.namespace = namespaces.slice(0).sort().join("."); | |
2226 | |
2227 } else { | |
2228 namespaces = []; | |
2229 handleObj.namespace = ""; | |
2230 } | |
2231 | |
2232 handleObj.type = type; | |
2233 if ( !handleObj.guid ) { | |
2234 handleObj.guid = handler.guid; | |
2235 } | |
2236 | |
2237 // Get the current list of functions bound to this event | |
2238 var handlers = events[ type ], | |
2239 special = jQuery.event.special[ type ] || {}; | |
2240 | |
2241 // Init the event handler queue | |
2242 if ( !handlers ) { | |
2243 handlers = events[ type ] = []; | |
2244 | |
2245 // Check for a special event handler | |
2246 // Only use addEventListener/attachEvent if the special | |
2247 // events handler returns false | |
2248 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { | |
2249 // Bind the global event handler to the element | |
2250 if ( elem.addEventListener ) { | |
2251 elem.addEventListener( type, eventHandle, false ); | |
2252 | |
2253 } else if ( elem.attachEvent ) { | |
2254 elem.attachEvent( "on" + type, eventHandle ); | |
2255 } | |
2256 } | |
2257 } | |
2258 | |
2259 if ( special.add ) { | |
2260 special.add.call( elem, handleObj ); | |
2261 | |
2262 if ( !handleObj.handler.guid ) { | |
2263 handleObj.handler.guid = handler.guid; | |
2264 } | |
2265 } | |
2266 | |
2267 // Add the function to the element's handler list | |
2268 handlers.push( handleObj ); | |
2269 | |
2270 // Keep track of which events have been used, for global triggering | |
2271 jQuery.event.global[ type ] = true; | |
2272 } | |
2273 | |
2274 // Nullify elem to prevent memory leaks in IE | |
2275 elem = null; | |
2276 }, | |
2277 | |
2278 global: {}, | |
2279 | |
2280 // Detach an event or set of events from an element | |
2281 remove: function( elem, types, handler, pos ) { | |
2282 // don't do events on text and comment nodes | |
2283 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { | |
2284 return; | |
2285 } | |
2286 | |
2287 if ( handler === false ) { | |
2288 handler = returnFalse; | |
2289 } | |
2290 | |
2291 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, | |
2292 elemData = jQuery.hasData( elem ) && jQuery._data( elem ), | |
2293 events = elemData && elemData.events; | |
2294 | |
2295 if ( !elemData || !events ) { | |
2296 return; | |
2297 } | |
2298 | |
2299 // types is actually an event object here | |
2300 if ( types && types.type ) { | |
2301 handler = types.handler; | |
2302 types = types.type; | |
2303 } | |
2304 | |
2305 // Unbind all events for the element | |
2306 if ( !types || typeof types === "string" && types.charAt(0) === "." ) { | |
2307 types = types || ""; | |
2308 | |
2309 for ( type in events ) { | |
2310 jQuery.event.remove( elem, type + types ); | |
2311 } | |
2312 | |
2313 return; | |
2314 } | |
2315 | |
2316 // Handle multiple events separated by a space | |
2317 // jQuery(...).unbind("mouseover mouseout", fn); | |
2318 types = types.split(" "); | |
2319 | |
2320 while ( (type = types[ i++ ]) ) { | |
2321 origType = type; | |
2322 handleObj = null; | |
2323 all = type.indexOf(".") < 0; | |
2324 namespaces = []; | |
2325 | |
2326 if ( !all ) { | |
2327 // Namespaced event handlers | |
2328 namespaces = type.split("."); | |
2329 type = namespaces.shift(); | |
2330 | |
2331 namespace = new RegExp("(^|\\.)" + | |
2332 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); | |
2333 } | |
2334 | |
2335 eventType = events[ type ]; | |
2336 | |
2337 if ( !eventType ) { | |
2338 continue; | |
2339 } | |
2340 | |
2341 if ( !handler ) { | |
2342 for ( j = 0; j < eventType.length; j++ ) { | |
2343 handleObj = eventType[ j ]; | |
2344 | |
2345 if ( all || namespace.test( handleObj.namespace ) ) { | |
2346 jQuery.event.remove( elem, origType, handleObj.handler, j ); | |
2347 eventType.splice( j--, 1 ); | |
2348 } | |
2349 } | |
2350 | |
2351 continue; | |
2352 } | |
2353 | |
2354 special = jQuery.event.special[ type ] || {}; | |
2355 | |
2356 for ( j = pos || 0; j < eventType.length; j++ ) { | |
2357 handleObj = eventType[ j ]; | |
2358 | |
2359 if ( handler.guid === handleObj.guid ) { | |
2360 // remove the given handler for the given type | |
2361 if ( all || namespace.test( handleObj.namespace ) ) { | |
2362 if ( pos == null ) { | |
2363 eventType.splice( j--, 1 ); | |
2364 } | |
2365 | |
2366 if ( special.remove ) { | |
2367 special.remove.call( elem, handleObj ); | |
2368 } | |
2369 } | |
2370 | |
2371 if ( pos != null ) { | |
2372 break; | |
2373 } | |
2374 } | |
2375 } | |
2376 | |
2377 // remove generic event handler if no more handlers exist | |
2378 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { | |
2379 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { | |
2380 jQuery.removeEvent( elem, type, elemData.handle ); | |
2381 } | |
2382 | |
2383 ret = null; | |
2384 delete events[ type ]; | |
2385 } | |
2386 } | |
2387 | |
2388 // Remove the expando if it's no longer used | |
2389 if ( jQuery.isEmptyObject( events ) ) { | |
2390 var handle = elemData.handle; | |
2391 if ( handle ) { | |
2392 handle.elem = null; | |
2393 } | |
2394 | |
2395 delete elemData.events; | |
2396 delete elemData.handle; | |
2397 | |
2398 if ( jQuery.isEmptyObject( elemData ) ) { | |
2399 jQuery.removeData( elem, undefined, true ); | |
2400 } | |
2401 } | |
2402 }, | |
2403 | |
2404 // bubbling is internal | |
2405 trigger: function( event, data, elem /*, bubbling */ ) { | |
2406 // Event object or event type | |
2407 var type = event.type || event, | |
2408 bubbling = arguments[3]; | |
2409 | |
2410 if ( !bubbling ) { | |
2411 event = typeof event === "object" ? | |
2412 // jQuery.Event object | |
2413 event[ jQuery.expando ] ? event : | |
2414 // Object literal | |
2415 jQuery.extend( jQuery.Event(type), event ) : | |
2416 // Just the event type (string) | |
2417 jQuery.Event(type); | |
2418 | |
2419 if ( type.indexOf("!") >= 0 ) { | |
2420 event.type = type = type.slice(0, -1); | |
2421 event.exclusive = true; | |
2422 } | |
2423 | |
2424 // Handle a global trigger | |
2425 if ( !elem ) { | |
2426 // Don't bubble custom events when global (to avoid too much overhead) | |
2427 event.stopPropagation(); | |
2428 | |
2429 // Only trigger if we've ever bound an event for it | |
2430 if ( jQuery.event.global[ type ] ) { | |
2431 // XXX This code smells terrible. event.js should not be directly | |
2432 // inspecting the data cache | |
2433 jQuery.each( jQuery.cache, function() { | |
2434 // internalKey variable is just used to make it easier to find | |
2435 // and potentially change this stuff later; currently it just | |
2436 // points to jQuery.expando | |
2437 var internalKey = jQuery.expando, | |
2438 internalCache = this[ internalKey ]; | |
2439 if ( internalCache && internalCache.events && internalCache.events[ type ] ) { | |
2440 jQuery.event.trigger( event, data, internalCache.handle.elem ); | |
2441 } | |
2442 }); | |
2443 } | |
2444 } | |
2445 | |
2446 // Handle triggering a single element | |
2447 | |
2448 // don't do events on text and comment nodes | |
2449 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { | |
2450 return undefined; | |
2451 } | |
2452 | |
2453 // Clean up in case it is reused | |
2454 event.result = undefined; | |
2455 event.target = elem; | |
2456 | |
2457 // Clone the incoming data, if any | |
2458 data = jQuery.makeArray( data ); | |
2459 data.unshift( event ); | |
2460 } | |
2461 | |
2462 event.currentTarget = elem; | |
2463 | |
2464 // Trigger the event, it is assumed that "handle" is a function | |
2465 var handle = jQuery._data( elem, "handle" ); | |
2466 | |
2467 if ( handle ) { | |
2468 handle.apply( elem, data ); | |
2469 } | |
2470 | |
2471 var parent = elem.parentNode || elem.ownerDocument; | |
2472 | |
2473 // Trigger an inline bound script | |
2474 try { | |
2475 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { | |
2476 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { | |
2477 event.result = false; | |
2478 event.preventDefault(); | |
2479 } | |
2480 } | |
2481 | |
2482 // prevent IE from throwing an error for some elements with some event types, see #3533 | |
2483 } catch (inlineError) {} | |
2484 | |
2485 if ( !event.isPropagationStopped() && parent ) { | |
2486 jQuery.event.trigger( event, data, parent, true ); | |
2487 | |
2488 } else if ( !event.isDefaultPrevented() ) { | |
2489 var old, | |
2490 target = event.target, | |
2491 targetType = type.replace( rnamespaces, "" ), | |
2492 isClick = jQuery.nodeName( target, "a" ) && targetType === "click", | |
2493 special = jQuery.event.special[ targetType ] || {}; | |
2494 | |
2495 if ( (!special._default || special._default.call( elem, event ) === false) && | |
2496 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { | |
2497 | |
2498 try { | |
2499 if ( target[ targetType ] ) { | |
2500 // Make sure that we don't accidentally re-trigger the onFOO events | |
2501 old = target[ "on" + targetType ]; | |
2502 | |
2503 if ( old ) { | |
2504 target[ "on" + targetType ] = null; | |
2505 } | |
2506 | |
2507 jQuery.event.triggered = true; | |
2508 target[ targetType ](); | |
2509 } | |
2510 | |
2511 // prevent IE from throwing an error for some elements with some event types, see #3533 | |
2512 } catch (triggerError) {} | |
2513 | |
2514 if ( old ) { | |
2515 target[ "on" + targetType ] = old; | |
2516 } | |
2517 | |
2518 jQuery.event.triggered = false; | |
2519 } | |
2520 } | |
2521 }, | |
2522 | |
2523 handle: function( event ) { | |
2524 var all, handlers, namespaces, namespace_re, events, | |
2525 namespace_sort = [], | |
2526 args = jQuery.makeArray( arguments ); | |
2527 | |
2528 event = args[0] = jQuery.event.fix( event || window.event ); | |
2529 event.currentTarget = this; | |
2530 | |
2531 // Namespaced event handlers | |
2532 all = event.type.indexOf(".") < 0 && !event.exclusive; | |
2533 | |
2534 if ( !all ) { | |
2535 namespaces = event.type.split("."); | |
2536 event.type = namespaces.shift(); | |
2537 namespace_sort = namespaces.slice(0).sort(); | |
2538 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); | |
2539 } | |
2540 | |
2541 event.namespace = event.namespace || namespace_sort.join("."); | |
2542 | |
2543 events = jQuery._data(this, "events"); | |
2544 | |
2545 handlers = (events || {})[ event.type ]; | |
2546 | |
2547 if ( events && handlers ) { | |
2548 // Clone the handlers to prevent manipulation | |
2549 handlers = handlers.slice(0); | |
2550 | |
2551 for ( var j = 0, l = handlers.length; j < l; j++ ) { | |
2552 var handleObj = handlers[ j ]; | |
2553 | |
2554 // Filter the functions by class | |
2555 if ( all || namespace_re.test( handleObj.namespace ) ) { | |
2556 // Pass in a reference to the handler function itself | |
2557 // So that we can later remove it | |
2558 event.handler = handleObj.handler; | |
2559 event.data = handleObj.data; | |
2560 event.handleObj = handleObj; | |
2561 | |
2562 var ret = handleObj.handler.apply( this, args ); | |
2563 | |
2564 if ( ret !== undefined ) { | |
2565 event.result = ret; | |
2566 if ( ret === false ) { | |
2567 event.preventDefault(); | |
2568 event.stopPropagation(); | |
2569 } | |
2570 } | |
2571 | |
2572 if ( event.isImmediatePropagationStopped() ) { | |
2573 break; | |
2574 } | |
2575 } | |
2576 } | |
2577 } | |
2578 | |
2579 return event.result; | |
2580 }, | |
2581 | |
2582 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(" "), | |
2583 | |
2584 fix: function( event ) { | |
2585 if ( event[ jQuery.expando ] ) { | |
2586 return event; | |
2587 } | |
2588 | |
2589 // store a copy of the original event object | |
2590 // and "clone" to set read-only properties | |
2591 var originalEvent = event; | |
2592 event = jQuery.Event( originalEvent ); | |
2593 | |
2594 for ( var i = this.props.length, prop; i; ) { | |
2595 prop = this.props[ --i ]; | |
2596 event[ prop ] = originalEvent[ prop ]; | |
2597 } | |
2598 | |
2599 // Fix target property, if necessary | |
2600 if ( !event.target ) { | |
2601 // Fixes #1925 where srcElement might not be defined either | |
2602 event.target = event.srcElement || document; | |
2603 } | |
2604 | |
2605 // check if target is a textnode (safari) | |
2606 if ( event.target.nodeType === 3 ) { | |
2607 event.target = event.target.parentNode; | |
2608 } | |
2609 | |
2610 // Add relatedTarget, if necessary | |
2611 if ( !event.relatedTarget && event.fromElement ) { | |
2612 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; | |
2613 } | |
2614 | |
2615 // Calculate pageX/Y if missing and clientX/Y available | |
2616 if ( event.pageX == null && event.clientX != null ) { | |
2617 var doc = document.documentElement, | |
2618 body = document.body; | |
2619 | |
2620 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); | |
2621 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); | |
2622 } | |
2623 | |
2624 // Add which for key events | |
2625 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { | |
2626 event.which = event.charCode != null ? event.charCode : event.keyCode; | |
2627 } | |
2628 | |
2629 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) | |
2630 if ( !event.metaKey && event.ctrlKey ) { | |
2631 event.metaKey = event.ctrlKey; | |
2632 } | |
2633 | |
2634 // Add which for click: 1 === left; 2 === middle; 3 === right | |
2635 // Note: button is not normalized, so don't use it | |
2636 if ( !event.which && event.button !== undefined ) { | |
2637 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); | |
2638 } | |
2639 | |
2640 return event; | |
2641 }, | |
2642 | |
2643 // Deprecated, use jQuery.guid instead | |
2644 guid: 1E8, | |
2645 | |
2646 // Deprecated, use jQuery.proxy instead | |
2647 proxy: jQuery.proxy, | |
2648 | |
2649 special: { | |
2650 ready: { | |
2651 // Make sure the ready event is setup | |
2652 setup: jQuery.bindReady, | |
2653 teardown: jQuery.noop | |
2654 }, | |
2655 | |
2656 live: { | |
2657 add: function( handleObj ) { | |
2658 jQuery.event.add( this, | |
2659 liveConvert( handleObj.origType, handleObj.selector ), | |
2660 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); | |
2661 }, | |
2662 | |
2663 remove: function( handleObj ) { | |
2664 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); | |
2665 } | |
2666 }, | |
2667 | |
2668 beforeunload: { | |
2669 setup: function( data, namespaces, eventHandle ) { | |
2670 // We only want to do this special case on windows | |
2671 if ( jQuery.isWindow( this ) ) { | |
2672 this.onbeforeunload = eventHandle; | |
2673 } | |
2674 }, | |
2675 | |
2676 teardown: function( namespaces, eventHandle ) { | |
2677 if ( this.onbeforeunload === eventHandle ) { | |
2678 this.onbeforeunload = null; | |
2679 } | |
2680 } | |
2681 } | |
2682 } | |
2683 }; | |
2684 | |
2685 jQuery.removeEvent = document.removeEventListener ? | |
2686 function( elem, type, handle ) { | |
2687 if ( elem.removeEventListener ) { | |
2688 elem.removeEventListener( type, handle, false ); | |
2689 } | |
2690 } : | |
2691 function( elem, type, handle ) { | |
2692 if ( elem.detachEvent ) { | |
2693 elem.detachEvent( "on" + type, handle ); | |
2694 } | |
2695 }; | |
2696 | |
2697 jQuery.Event = function( src ) { | |
2698 // Allow instantiation without the 'new' keyword | |
2699 if ( !this.preventDefault ) { | |
2700 return new jQuery.Event( src ); | |
2701 } | |
2702 | |
2703 // Event object | |
2704 if ( src && src.type ) { | |
2705 this.originalEvent = src; | |
2706 this.type = src.type; | |
2707 | |
2708 // Events bubbling up the document may have been marked as prevented | |
2709 // by a handler lower down the tree; reflect the correct value. | |
2710 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || | |
2711 src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; | |
2712 | |
2713 // Event type | |
2714 } else { | |
2715 this.type = src; | |
2716 } | |
2717 | |
2718 // timeStamp is buggy for some events on Firefox(#3843) | |
2719 // So we won't rely on the native value | |
2720 this.timeStamp = jQuery.now(); | |
2721 | |
2722 // Mark it as fixed | |
2723 this[ jQuery.expando ] = true; | |
2724 }; | |
2725 | |
2726 function returnFalse() { | |
2727 return false; | |
2728 } | |
2729 function returnTrue() { | |
2730 return true; | |
2731 } | |
2732 | |
2733 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding | |
2734 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html | |
2735 jQuery.Event.prototype = { | |
2736 preventDefault: function() { | |
2737 this.isDefaultPrevented = returnTrue; | |
2738 | |
2739 var e = this.originalEvent; | |
2740 if ( !e ) { | |
2741 return; | |
2742 } | |
2743 | |
2744 // if preventDefault exists run it on the original event | |
2745 if ( e.preventDefault ) { | |
2746 e.preventDefault(); | |
2747 | |
2748 // otherwise set the returnValue property of the original event to false (IE) | |
2749 } else { | |
2750 e.returnValue = false; | |
2751 } | |
2752 }, | |
2753 stopPropagation: function() { | |
2754 this.isPropagationStopped = returnTrue; | |
2755 | |
2756 var e = this.originalEvent; | |
2757 if ( !e ) { | |
2758 return; | |
2759 } | |
2760 // if stopPropagation exists run it on the original event | |
2761 if ( e.stopPropagation ) { | |
2762 e.stopPropagation(); | |
2763 } | |
2764 // otherwise set the cancelBubble property of the original event to true (IE) | |
2765 e.cancelBubble = true; | |
2766 }, | |
2767 stopImmediatePropagation: function() { | |
2768 this.isImmediatePropagationStopped = returnTrue; | |
2769 this.stopPropagation(); | |
2770 }, | |
2771 isDefaultPrevented: returnFalse, | |
2772 isPropagationStopped: returnFalse, | |
2773 isImmediatePropagationStopped: returnFalse | |
2774 }; | |
2775 | |
2776 // Checks if an event happened on an element within another element | |
2777 // Used in jQuery.event.special.mouseenter and mouseleave handlers | |
2778 var withinElement = function( event ) { | |
2779 // Check if mouse(over|out) are still within the same parent element | |
2780 var parent = event.relatedTarget; | |
2781 | |
2782 // Firefox sometimes assigns relatedTarget a XUL element | |
2783 // which we cannot access the parentNode property of | |
2784 try { | |
2785 | |
2786 // Chrome does something similar, the parentNode property | |
2787 // can be accessed but is null. | |
2788 if ( parent !== document && !parent.parentNode ) { | |
2789 return; | |
2790 } | |
2791 // Traverse up the tree | |
2792 while ( parent && parent !== this ) { | |
2793 parent = parent.parentNode; | |
2794 } | |
2795 | |
2796 if ( parent !== this ) { | |
2797 // set the correct event type | |
2798 event.type = event.data; | |
2799 | |
2800 // handle event if we actually just moused on to a non sub-element | |
2801 jQuery.event.handle.apply( this, arguments ); | |
2802 } | |
2803 | |
2804 // assuming we've left the element since we most likely mousedover a xul element | |
2805 } catch(e) { } | |
2806 }, | |
2807 | |
2808 // In case of event delegation, we only need to rename the event.type, | |
2809 // liveHandler will take care of the rest. | |
2810 delegate = function( event ) { | |
2811 event.type = event.data; | |
2812 jQuery.event.handle.apply( this, arguments ); | |
2813 }; | |
2814 | |
2815 // Create mouseenter and mouseleave events | |
2816 jQuery.each({ | |
2817 mouseenter: "mouseover", | |
2818 mouseleave: "mouseout" | |
2819 }, function( orig, fix ) { | |
2820 jQuery.event.special[ orig ] = { | |
2821 setup: function( data ) { | |
2822 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); | |
2823 }, | |
2824 teardown: function( data ) { | |
2825 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); | |
2826 } | |
2827 }; | |
2828 }); | |
2829 | |
2830 // submit delegation | |
2831 if ( !jQuery.support.submitBubbles ) { | |
2832 | |
2833 jQuery.event.special.submit = { | |
2834 setup: function( data, namespaces ) { | |
2835 if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) { | |
2836 jQuery.event.add(this, "click.specialSubmit", function( e ) { | |
2837 var elem = e.target, | |
2838 type = elem.type; | |
2839 | |
2840 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { | |
2841 trigger( "submit", this, arguments ); | |
2842 } | |
2843 }); | |
2844 | |
2845 jQuery.event.add(this, "keypress.specialSubmit", function( e ) { | |
2846 var elem = e.target, | |
2847 type = elem.type; | |
2848 | |
2849 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { | |
2850 trigger( "submit", this, arguments ); | |
2851 } | |
2852 }); | |
2853 | |
2854 } else { | |
2855 return false; | |
2856 } | |
2857 }, | |
2858 | |
2859 teardown: function( namespaces ) { | |
2860 jQuery.event.remove( this, ".specialSubmit" ); | |
2861 } | |
2862 }; | |
2863 | |
2864 } | |
2865 | |
2866 // change delegation, happens here so we have bind. | |
2867 if ( !jQuery.support.changeBubbles ) { | |
2868 | |
2869 var changeFilters, | |
2870 | |
2871 getVal = function( elem ) { | |
2872 var type = elem.type, val = elem.value; | |
2873 | |
2874 if ( type === "radio" || type === "checkbox" ) { | |
2875 val = elem.checked; | |
2876 | |
2877 } else if ( type === "select-multiple" ) { | |
2878 val = elem.selectedIndex > -1 ? | |
2879 jQuery.map( elem.options, function( elem ) { | |
2880 return elem.selected; | |
2881 }).join("-") : | |
2882 ""; | |
2883 | |
2884 } else if ( elem.nodeName.toLowerCase() === "select" ) { | |
2885 val = elem.selectedIndex; | |
2886 } | |
2887 | |
2888 return val; | |
2889 }, | |
2890 | |
2891 testChange = function testChange( e ) { | |
2892 var elem = e.target, data, val; | |
2893 | |
2894 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { | |
2895 return; | |
2896 } | |
2897 | |
2898 data = jQuery._data( elem, "_change_data" ); | |
2899 val = getVal(elem); | |
2900 | |
2901 // the current data will be also retrieved by beforeactivate | |
2902 if ( e.type !== "focusout" || elem.type !== "radio" ) { | |
2903 jQuery._data( elem, "_change_data", val ); | |
2904 } | |
2905 | |
2906 if ( data === undefined || val === data ) { | |
2907 return; | |
2908 } | |
2909 | |
2910 if ( data != null || val ) { | |
2911 e.type = "change"; | |
2912 e.liveFired = undefined; | |
2913 jQuery.event.trigger( e, arguments[1], elem ); | |
2914 } | |
2915 }; | |
2916 | |
2917 jQuery.event.special.change = { | |
2918 filters: { | |
2919 focusout: testChange, | |
2920 | |
2921 beforedeactivate: testChange, | |
2922 | |
2923 click: function( e ) { | |
2924 var elem = e.target, type = elem.type; | |
2925 | |
2926 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { | |
2927 testChange.call( this, e ); | |
2928 } | |
2929 }, | |
2930 | |
2931 // Change has to be called before submit | |
2932 // Keydown will be called before keypress, which is used in submit-event delegation | |
2933 keydown: function( e ) { | |
2934 var elem = e.target, type = elem.type; | |
2935 | |
2936 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || | |
2937 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || | |
2938 type === "select-multiple" ) { | |
2939 testChange.call( this, e ); | |
2940 } | |
2941 }, | |
2942 | |
2943 // Beforeactivate happens also before the previous element is blurred | |
2944 // with this event you can't trigger a change event, but you can store | |
2945 // information | |
2946 beforeactivate: function( e ) { | |
2947 var elem = e.target; | |
2948 jQuery._data( elem, "_change_data", getVal(elem) ); | |
2949 } | |
2950 }, | |
2951 | |
2952 setup: function( data, namespaces ) { | |
2953 if ( this.type === "file" ) { | |
2954 return false; | |
2955 } | |
2956 | |
2957 for ( var type in changeFilters ) { | |
2958 jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); | |
2959 } | |
2960 | |
2961 return rformElems.test( this.nodeName ); | |
2962 }, | |
2963 | |
2964 teardown: function( namespaces ) { | |
2965 jQuery.event.remove( this, ".specialChange" ); | |
2966 | |
2967 return rformElems.test( this.nodeName ); | |
2968 } | |
2969 }; | |
2970 | |
2971 changeFilters = jQuery.event.special.change.filters; | |
2972 | |
2973 // Handle when the input is .focus()'d | |
2974 changeFilters.focus = changeFilters.beforeactivate; | |
2975 } | |
2976 | |
2977 function trigger( type, elem, args ) { | |
2978 // Piggyback on a donor event to simulate a different one. | |
2979 // Fake originalEvent to avoid donor's stopPropagation, but if the | |
2980 // simulated event prevents default then we do the same on the donor. | |
2981 // Don't pass args or remember liveFired; they apply to the donor event. | |
2982 var event = jQuery.extend( {}, args[ 0 ] ); | |
2983 event.type = type; | |
2984 event.originalEvent = {}; | |
2985 event.liveFired = undefined; | |
2986 jQuery.event.handle.call( elem, event ); | |
2987 if ( event.isDefaultPrevented() ) { | |
2988 args[ 0 ].preventDefault(); | |
2989 } | |
2990 } | |
2991 | |
2992 // Create "bubbling" focus and blur events | |
2993 if ( document.addEventListener ) { | |
2994 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { | |
2995 jQuery.event.special[ fix ] = { | |
2996 setup: function() { | |
2997 this.addEventListener( orig, handler, true ); | |
2998 }, | |
2999 teardown: function() { | |
3000 this.removeEventListener( orig, handler, true ); | |
3001 } | |
3002 }; | |
3003 | |
3004 function handler( e ) { | |
3005 e = jQuery.event.fix( e ); | |
3006 e.type = fix; | |
3007 return jQuery.event.handle.call( this, e ); | |
3008 } | |
3009 }); | |
3010 } | |
3011 | |
3012 jQuery.each(["bind", "one"], function( i, name ) { | |
3013 jQuery.fn[ name ] = function( type, data, fn ) { | |
3014 // Handle object literals | |
3015 if ( typeof type === "object" ) { | |
3016 for ( var key in type ) { | |
3017 this[ name ](key, data, type[key], fn); | |
3018 } | |
3019 return this; | |
3020 } | |
3021 | |
3022 if ( jQuery.isFunction( data ) || data === false ) { | |
3023 fn = data; | |
3024 data = undefined; | |
3025 } | |
3026 | |
3027 var handler = name === "one" ? jQuery.proxy( fn, function( event ) { | |
3028 jQuery( this ).unbind( event, handler ); | |
3029 return fn.apply( this, arguments ); | |
3030 }) : fn; | |
3031 | |
3032 if ( type === "unload" && name !== "one" ) { | |
3033 this.one( type, data, fn ); | |
3034 | |
3035 } else { | |
3036 for ( var i = 0, l = this.length; i < l; i++ ) { | |
3037 jQuery.event.add( this[i], type, handler, data ); | |
3038 } | |
3039 } | |
3040 | |
3041 return this; | |
3042 }; | |
3043 }); | |
3044 | |
3045 jQuery.fn.extend({ | |
3046 unbind: function( type, fn ) { | |
3047 // Handle object literals | |
3048 if ( typeof type === "object" && !type.preventDefault ) { | |
3049 for ( var key in type ) { | |
3050 this.unbind(key, type[key]); | |
3051 } | |
3052 | |
3053 } else { | |
3054 for ( var i = 0, l = this.length; i < l; i++ ) { | |
3055 jQuery.event.remove( this[i], type, fn ); | |
3056 } | |
3057 } | |
3058 | |
3059 return this; | |
3060 }, | |
3061 | |
3062 delegate: function( selector, types, data, fn ) { | |
3063 return this.live( types, data, fn, selector ); | |
3064 }, | |
3065 | |
3066 undelegate: function( selector, types, fn ) { | |
3067 if ( arguments.length === 0 ) { | |
3068 return this.unbind( "live" ); | |
3069 | |
3070 } else { | |
3071 return this.die( types, null, fn, selector ); | |
3072 } | |
3073 }, | |
3074 | |
3075 trigger: function( type, data ) { | |
3076 return this.each(function() { | |
3077 jQuery.event.trigger( type, data, this ); | |
3078 }); | |
3079 }, | |
3080 | |
3081 triggerHandler: function( type, data ) { | |
3082 if ( this[0] ) { | |
3083 var event = jQuery.Event( type ); | |
3084 event.preventDefault(); | |
3085 event.stopPropagation(); | |
3086 jQuery.event.trigger( event, data, this[0] ); | |
3087 return event.result; | |
3088 } | |
3089 }, | |
3090 | |
3091 toggle: function( fn ) { | |
3092 // Save reference to arguments for access in closure | |
3093 var args = arguments, | |
3094 i = 1; | |
3095 | |
3096 // link all the functions, so any of them can unbind this click handler | |
3097 while ( i < args.length ) { | |
3098 jQuery.proxy( fn, args[ i++ ] ); | |
3099 } | |
3100 | |
3101 return this.click( jQuery.proxy( fn, function( event ) { | |
3102 // Figure out which function to execute | |
3103 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; | |
3104 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); | |
3105 | |
3106 // Make sure that clicks stop | |
3107 event.preventDefault(); | |
3108 | |
3109 // and execute the function | |
3110 return args[ lastToggle ].apply( this, arguments ) || false; | |
3111 })); | |
3112 }, | |
3113 | |
3114 hover: function( fnOver, fnOut ) { | |
3115 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); | |
3116 } | |
3117 }); | |
3118 | |
3119 var liveMap = { | |
3120 focus: "focusin", | |
3121 blur: "focusout", | |
3122 mouseenter: "mouseover", | |
3123 mouseleave: "mouseout" | |
3124 }; | |
3125 | |
3126 jQuery.each(["live", "die"], function( i, name ) { | |
3127 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { | |
3128 var type, i = 0, match, namespaces, preType, | |
3129 selector = origSelector || this.selector, | |
3130 context = origSelector ? this : jQuery( this.context ); | |
3131 | |
3132 if ( typeof types === "object" && !types.preventDefault ) { | |
3133 for ( var key in types ) { | |
3134 context[ name ]( key, data, types[key], selector ); | |
3135 } | |
3136 | |
3137 return this; | |
3138 } | |
3139 | |
3140 if ( jQuery.isFunction( data ) ) { | |
3141 fn = data; | |
3142 data = undefined; | |
3143 } | |
3144 | |
3145 types = (types || "").split(" "); | |
3146 | |
3147 while ( (type = types[ i++ ]) != null ) { | |
3148 match = rnamespaces.exec( type ); | |
3149 namespaces = ""; | |
3150 | |
3151 if ( match ) { | |
3152 namespaces = match[0]; | |
3153 type = type.replace( rnamespaces, "" ); | |
3154 } | |
3155 | |
3156 if ( type === "hover" ) { | |
3157 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); | |
3158 continue; | |
3159 } | |
3160 | |
3161 preType = type; | |
3162 | |
3163 if ( type === "focus" || type === "blur" ) { | |
3164 types.push( liveMap[ type ] + namespaces ); | |
3165 type = type + namespaces; | |
3166 | |
3167 } else { | |
3168 type = (liveMap[ type ] || type) + namespaces; | |
3169 } | |
3170 | |
3171 if ( name === "live" ) { | |
3172 // bind live handler | |
3173 for ( var j = 0, l = context.length; j < l; j++ ) { | |
3174 jQuery.event.add( context[j], "live." + liveConvert( type, selector ), | |
3175 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); | |
3176 } | |
3177 | |
3178 } else { | |
3179 // unbind live handler | |
3180 context.unbind( "live." + liveConvert( type, selector ), fn ); | |
3181 } | |
3182 } | |
3183 | |
3184 return this; | |
3185 }; | |
3186 }); | |
3187 | |
3188 function liveHandler( event ) { | |
3189 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, | |
3190 elems = [], | |
3191 selectors = [], | |
3192 events = jQuery._data( this, "events" ); | |
3193 | |
3194 // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) | |
3195 if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { | |
3196 return; | |
3197 } | |
3198 | |
3199 if ( event.namespace ) { | |
3200 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); | |
3201 } | |
3202 | |
3203 event.liveFired = this; | |
3204 | |
3205 var live = events.live.slice(0); | |
3206 | |
3207 for ( j = 0; j < live.length; j++ ) { | |
3208 handleObj = live[j]; | |
3209 | |
3210 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { | |
3211 selectors.push( handleObj.selector ); | |
3212 | |
3213 } else { | |
3214 live.splice( j--, 1 ); | |
3215 } | |
3216 } | |
3217 | |
3218 match = jQuery( event.target ).closest( selectors, event.currentTarget ); | |
3219 | |
3220 for ( i = 0, l = match.length; i < l; i++ ) { | |
3221 close = match[i]; | |
3222 | |
3223 for ( j = 0; j < live.length; j++ ) { | |
3224 handleObj = live[j]; | |
3225 | |
3226 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { | |
3227 elem = close.elem; | |
3228 related = null; | |
3229 | |
3230 // Those two events require additional checking | |
3231 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { | |
3232 event.type = handleObj.preType; | |
3233 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; | |
3234 } | |
3235 | |
3236 if ( !related || related !== elem ) { | |
3237 elems.push({ elem: elem, handleObj: handleObj, level: close.level }); | |
3238 } | |
3239 } | |
3240 } | |
3241 } | |
3242 | |
3243 for ( i = 0, l = elems.length; i < l; i++ ) { | |
3244 match = elems[i]; | |
3245 | |
3246 if ( maxLevel && match.level > maxLevel ) { | |
3247 break; | |
3248 } | |
3249 | |
3250 event.currentTarget = match.elem; | |
3251 event.data = match.handleObj.data; | |
3252 event.handleObj = match.handleObj; | |
3253 | |
3254 ret = match.handleObj.origHandler.apply( match.elem, arguments ); | |
3255 | |
3256 if ( ret === false || event.isPropagationStopped() ) { | |
3257 maxLevel = match.level; | |
3258 | |
3259 if ( ret === false ) { | |
3260 stop = false; | |
3261 } | |
3262 if ( event.isImmediatePropagationStopped() ) { | |
3263 break; | |
3264 } | |
3265 } | |
3266 } | |
3267 | |
3268 return stop; | |
3269 } | |
3270 | |
3271 function liveConvert( type, selector ) { | |
3272 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); | |
3273 } | |
3274 | |
3275 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + | |
3276 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + | |
3277 "change select submit keydown keypress keyup error").split(" "), function( i, name ) { | |
3278 | |
3279 // Handle event binding | |
3280 jQuery.fn[ name ] = function( data, fn ) { | |
3281 if ( fn == null ) { | |
3282 fn = data; | |
3283 data = null; | |
3284 } | |
3285 | |
3286 return arguments.length > 0 ? | |
3287 this.bind( name, data, fn ) : | |
3288 this.trigger( name ); | |
3289 }; | |
3290 | |
3291 if ( jQuery.attrFn ) { | |
3292 jQuery.attrFn[ name ] = true; | |
3293 } | |
3294 }); | |
3295 | |
3296 | |
3297 /*! | |
3298 * Sizzle CSS Selector Engine | |
3299 * Copyright 2011, The Dojo Foundation | |
3300 * Released under the MIT, BSD, and GPL Licenses. | |
3301 * More information: http://sizzlejs.com/ | |
3302 */ | |
3303 (function(){ | |
3304 | |
3305 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, | |
3306 done = 0, | |
3307 toString = Object.prototype.toString, | |
3308 hasDuplicate = false, | |
3309 baseHasDuplicate = true, | |
3310 rBackslash = /\\/g, | |
3311 rNonWord = /\W/; | |
3312 | |
3313 // Here we check if the JavaScript engine is using some sort of | |
3314 // optimization where it does not always call our comparision | |
3315 // function. If that is the case, discard the hasDuplicate value. | |
3316 // Thus far that includes Google Chrome. | |
3317 [0, 0].sort(function() { | |
3318 baseHasDuplicate = false; | |
3319 return 0; | |
3320 }); | |
3321 | |
3322 var Sizzle = function( selector, context, results, seed ) { | |
3323 results = results || []; | |
3324 context = context || document; | |
3325 | |
3326 var origContext = context; | |
3327 | |
3328 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { | |
3329 return []; | |
3330 } | |
3331 | |
3332 if ( !selector || typeof selector !== "string" ) { | |
3333 return results; | |
3334 } | |
3335 | |
3336 var m, set, checkSet, extra, ret, cur, pop, i, | |
3337 prune = true, | |
3338 contextXML = Sizzle.isXML( context ), | |
3339 parts = [], | |
3340 soFar = selector; | |
3341 | |
3342 // Reset the position of the chunker regexp (start from head) | |
3343 do { | |
3344 chunker.exec( "" ); | |
3345 m = chunker.exec( soFar ); | |
3346 | |
3347 if ( m ) { | |
3348 soFar = m[3]; | |
3349 | |
3350 parts.push( m[1] ); | |
3351 | |
3352 if ( m[2] ) { | |
3353 extra = m[3]; | |
3354 break; | |
3355 } | |
3356 } | |
3357 } while ( m ); | |
3358 | |
3359 if ( parts.length > 1 && origPOS.exec( selector ) ) { | |
3360 | |
3361 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { | |
3362 set = posProcess( parts[0] + parts[1], context ); | |
3363 | |
3364 } else { | |
3365 set = Expr.relative[ parts[0] ] ? | |
3366 [ context ] : | |
3367 Sizzle( parts.shift(), context ); | |
3368 | |
3369 while ( parts.length ) { | |
3370 selector = parts.shift(); | |
3371 | |
3372 if ( Expr.relative[ selector ] ) { | |
3373 selector += parts.shift(); | |
3374 } | |
3375 | |
3376 set = posProcess( selector, set ); | |
3377 } | |
3378 } | |
3379 | |
3380 } else { | |
3381 // Take a shortcut and set the context if the root selector is an ID | |
3382 // (but not if it'll be faster if the inner selector is an ID) | |
3383 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && | |
3384 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { | |
3385 | |
3386 ret = Sizzle.find( parts.shift(), context, contextXML ); | |
3387 context = ret.expr ? | |
3388 Sizzle.filter( ret.expr, ret.set )[0] : | |
3389 ret.set[0]; | |
3390 } | |
3391 | |
3392 if ( context ) { | |
3393 ret = seed ? | |
3394 { expr: parts.pop(), set: makeArray(seed) } : | |
3395 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); | |
3396 | |
3397 set = ret.expr ? | |
3398 Sizzle.filter( ret.expr, ret.set ) : | |
3399 ret.set; | |
3400 | |
3401 if ( parts.length > 0 ) { | |
3402 checkSet = makeArray( set ); | |
3403 | |
3404 } else { | |
3405 prune = false; | |
3406 } | |
3407 | |
3408 while ( parts.length ) { | |
3409 cur = parts.pop(); | |
3410 pop = cur; | |
3411 | |
3412 if ( !Expr.relative[ cur ] ) { | |
3413 cur = ""; | |
3414 } else { | |
3415 pop = parts.pop(); | |
3416 } | |
3417 | |
3418 if ( pop == null ) { | |
3419 pop = context; | |
3420 } | |
3421 | |
3422 Expr.relative[ cur ]( checkSet, pop, contextXML ); | |
3423 } | |
3424 | |
3425 } else { | |
3426 checkSet = parts = []; | |
3427 } | |
3428 } | |
3429 | |
3430 if ( !checkSet ) { | |
3431 checkSet = set; | |
3432 } | |
3433 | |
3434 if ( !checkSet ) { | |
3435 Sizzle.error( cur || selector ); | |
3436 } | |
3437 | |
3438 if ( toString.call(checkSet) === "[object Array]" ) { | |
3439 if ( !prune ) { | |
3440 results.push.apply( results, checkSet ); | |
3441 | |
3442 } else if ( context && context.nodeType === 1 ) { | |
3443 for ( i = 0; checkSet[i] != null; i++ ) { | |
3444 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { | |
3445 results.push( set[i] ); | |
3446 } | |
3447 } | |
3448 | |
3449 } else { | |
3450 for ( i = 0; checkSet[i] != null; i++ ) { | |
3451 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { | |
3452 results.push( set[i] ); | |
3453 } | |
3454 } | |
3455 } | |
3456 | |
3457 } else { | |
3458 makeArray( checkSet, results ); | |
3459 } | |
3460 | |
3461 if ( extra ) { | |
3462 Sizzle( extra, origContext, results, seed ); | |
3463 Sizzle.uniqueSort( results ); | |
3464 } | |
3465 | |
3466 return results; | |
3467 }; | |
3468 | |
3469 Sizzle.uniqueSort = function( results ) { | |
3470 if ( sortOrder ) { | |
3471 hasDuplicate = baseHasDuplicate; | |
3472 results.sort( sortOrder ); | |
3473 | |
3474 if ( hasDuplicate ) { | |
3475 for ( var i = 1; i < results.length; i++ ) { | |
3476 if ( results[i] === results[ i - 1 ] ) { | |
3477 results.splice( i--, 1 ); | |
3478 } | |
3479 } | |
3480 } | |
3481 } | |
3482 | |
3483 return results; | |
3484 }; | |
3485 | |
3486 Sizzle.matches = function( expr, set ) { | |
3487 return Sizzle( expr, null, null, set ); | |
3488 }; | |
3489 | |
3490 Sizzle.matchesSelector = function( node, expr ) { | |
3491 return Sizzle( expr, null, null, [node] ).length > 0; | |
3492 }; | |
3493 | |
3494 Sizzle.find = function( expr, context, isXML ) { | |
3495 var set; | |
3496 | |
3497 if ( !expr ) { | |
3498 return []; | |
3499 } | |
3500 | |
3501 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { | |
3502 var match, | |
3503 type = Expr.order[i]; | |
3504 | |
3505 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { | |
3506 var left = match[1]; | |
3507 match.splice( 1, 1 ); | |
3508 | |
3509 if ( left.substr( left.length - 1 ) !== "\\" ) { | |
3510 match[1] = (match[1] || "").replace( rBackslash, "" ); | |
3511 set = Expr.find[ type ]( match, context, isXML ); | |
3512 | |
3513 if ( set != null ) { | |
3514 expr = expr.replace( Expr.match[ type ], "" ); | |
3515 break; | |
3516 } | |
3517 } | |
3518 } | |
3519 } | |
3520 | |
3521 if ( !set ) { | |
3522 set = typeof context.getElementsByTagName !== "undefined" ? | |
3523 context.getElementsByTagName( "*" ) : | |
3524 []; | |
3525 } | |
3526 | |
3527 return { set: set, expr: expr }; | |
3528 }; | |
3529 | |
3530 Sizzle.filter = function( expr, set, inplace, not ) { | |
3531 var match, anyFound, | |
3532 old = expr, | |
3533 result = [], | |
3534 curLoop = set, | |
3535 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); | |
3536 | |
3537 while ( expr && set.length ) { | |
3538 for ( var type in Expr.filter ) { | |
3539 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { | |
3540 var found, item, | |
3541 filter = Expr.filter[ type ], | |
3542 left = match[1]; | |
3543 | |
3544 anyFound = false; | |
3545 | |
3546 match.splice(1,1); | |
3547 | |
3548 if ( left.substr( left.length - 1 ) === "\\" ) { | |
3549 continue; | |
3550 } | |
3551 | |
3552 if ( curLoop === result ) { | |
3553 result = []; | |
3554 } | |
3555 | |
3556 if ( Expr.preFilter[ type ] ) { | |
3557 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); | |
3558 | |
3559 if ( !match ) { | |
3560 anyFound = found = true; | |
3561 | |
3562 } else if ( match === true ) { | |
3563 continue; | |
3564 } | |
3565 } | |
3566 | |
3567 if ( match ) { | |
3568 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { | |
3569 if ( item ) { | |
3570 found = filter( item, match, i, curLoop ); | |
3571 var pass = not ^ !!found; | |
3572 | |
3573 if ( inplace && found != null ) { | |
3574 if ( pass ) { | |
3575 anyFound = true; | |
3576 | |
3577 } else { | |
3578 curLoop[i] = false; | |
3579 } | |
3580 | |
3581 } else if ( pass ) { | |
3582 result.push( item ); | |
3583 anyFound = true; | |
3584 } | |
3585 } | |
3586 } | |
3587 } | |
3588 | |
3589 if ( found !== undefined ) { | |
3590 if ( !inplace ) { | |
3591 curLoop = result; | |
3592 } | |
3593 | |
3594 expr = expr.replace( Expr.match[ type ], "" ); | |
3595 | |
3596 if ( !anyFound ) { | |
3597 return []; | |
3598 } | |
3599 | |
3600 break; | |
3601 } | |
3602 } | |
3603 } | |
3604 | |
3605 // Improper expression | |
3606 if ( expr === old ) { | |
3607 if ( anyFound == null ) { | |
3608 Sizzle.error( expr ); | |
3609 | |
3610 } else { | |
3611 break; | |
3612 } | |
3613 } | |
3614 | |
3615 old = expr; | |
3616 } | |
3617 | |
3618 return curLoop; | |
3619 }; | |
3620 | |
3621 Sizzle.error = function( msg ) { | |
3622 throw "Syntax error, unrecognized expression: " + msg; | |
3623 }; | |
3624 | |
3625 var Expr = Sizzle.selectors = { | |
3626 order: [ "ID", "NAME", "TAG" ], | |
3627 | |
3628 match: { | |
3629 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, | |
3630 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, | |
3631 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, | |
3632 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, | |
3633 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, | |
3634 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, | |
3635 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, | |
3636 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ | |
3637 }, | |
3638 | |
3639 leftMatch: {}, | |
3640 | |
3641 attrMap: { | |
3642 "class": "className", | |
3643 "for": "htmlFor" | |
3644 }, | |
3645 | |
3646 attrHandle: { | |
3647 href: function( elem ) { | |
3648 return elem.getAttribute( "href" ); | |
3649 }, | |
3650 type: function( elem ) { | |
3651 return elem.getAttribute( "type" ); | |
3652 } | |
3653 }, | |
3654 | |
3655 relative: { | |
3656 "+": function(checkSet, part){ | |
3657 var isPartStr = typeof part === "string", | |
3658 isTag = isPartStr && !rNonWord.test( part ), | |
3659 isPartStrNotTag = isPartStr && !isTag; | |
3660 | |
3661 if ( isTag ) { | |
3662 part = part.toLowerCase(); | |
3663 } | |
3664 | |
3665 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { | |
3666 if ( (elem = checkSet[i]) ) { | |
3667 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} | |
3668 | |
3669 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? | |
3670 elem || false : | |
3671 elem === part; | |
3672 } | |
3673 } | |
3674 | |
3675 if ( isPartStrNotTag ) { | |
3676 Sizzle.filter( part, checkSet, true ); | |
3677 } | |
3678 }, | |
3679 | |
3680 ">": function( checkSet, part ) { | |
3681 var elem, | |
3682 isPartStr = typeof part === "string", | |
3683 i = 0, | |
3684 l = checkSet.length; | |
3685 | |
3686 if ( isPartStr && !rNonWord.test( part ) ) { | |
3687 part = part.toLowerCase(); | |
3688 | |
3689 for ( ; i < l; i++ ) { | |
3690 elem = checkSet[i]; | |
3691 | |
3692 if ( elem ) { | |
3693 var parent = elem.parentNode; | |
3694 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; | |
3695 } | |
3696 } | |
3697 | |
3698 } else { | |
3699 for ( ; i < l; i++ ) { | |
3700 elem = checkSet[i]; | |
3701 | |
3702 if ( elem ) { | |
3703 checkSet[i] = isPartStr ? | |
3704 elem.parentNode : | |
3705 elem.parentNode === part; | |
3706 } | |
3707 } | |
3708 | |
3709 if ( isPartStr ) { | |
3710 Sizzle.filter( part, checkSet, true ); | |
3711 } | |
3712 } | |
3713 }, | |
3714 | |
3715 "": function(checkSet, part, isXML){ | |
3716 var nodeCheck, | |
3717 doneName = done++, | |
3718 checkFn = dirCheck; | |
3719 | |
3720 if ( typeof part === "string" && !rNonWord.test( part ) ) { | |
3721 part = part.toLowerCase(); | |
3722 nodeCheck = part; | |
3723 checkFn = dirNodeCheck; | |
3724 } | |
3725 | |
3726 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); | |
3727 }, | |
3728 | |
3729 "~": function( checkSet, part, isXML ) { | |
3730 var nodeCheck, | |
3731 doneName = done++, | |
3732 checkFn = dirCheck; | |
3733 | |
3734 if ( typeof part === "string" && !rNonWord.test( part ) ) { | |
3735 part = part.toLowerCase(); | |
3736 nodeCheck = part; | |
3737 checkFn = dirNodeCheck; | |
3738 } | |
3739 | |
3740 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); | |
3741 } | |
3742 }, | |
3743 | |
3744 find: { | |
3745 ID: function( match, context, isXML ) { | |
3746 if ( typeof context.getElementById !== "undefined" && !isXML ) { | |
3747 var m = context.getElementById(match[1]); | |
3748 // Check parentNode to catch when Blackberry 4.6 returns | |
3749 // nodes that are no longer in the document #6963 | |
3750 return m && m.parentNode ? [m] : []; | |
3751 } | |
3752 }, | |
3753 | |
3754 NAME: function( match, context ) { | |
3755 if ( typeof context.getElementsByName !== "undefined" ) { | |
3756 var ret = [], | |
3757 results = context.getElementsByName( match[1] ); | |
3758 | |
3759 for ( var i = 0, l = results.length; i < l; i++ ) { | |
3760 if ( results[i].getAttribute("name") === match[1] ) { | |
3761 ret.push( results[i] ); | |
3762 } | |
3763 } | |
3764 | |
3765 return ret.length === 0 ? null : ret; | |
3766 } | |
3767 }, | |
3768 | |
3769 TAG: function( match, context ) { | |
3770 if ( typeof context.getElementsByTagName !== "undefined" ) { | |
3771 return context.getElementsByTagName( match[1] ); | |
3772 } | |
3773 } | |
3774 }, | |
3775 preFilter: { | |
3776 CLASS: function( match, curLoop, inplace, result, not, isXML ) { | |
3777 match = " " + match[1].replace( rBackslash, "" ) + " "; | |
3778 | |
3779 if ( isXML ) { | |
3780 return match; | |
3781 } | |
3782 | |
3783 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { | |
3784 if ( elem ) { | |
3785 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { | |
3786 if ( !inplace ) { | |
3787 result.push( elem ); | |
3788 } | |
3789 | |
3790 } else if ( inplace ) { | |
3791 curLoop[i] = false; | |
3792 } | |
3793 } | |
3794 } | |
3795 | |
3796 return false; | |
3797 }, | |
3798 | |
3799 ID: function( match ) { | |
3800 return match[1].replace( rBackslash, "" ); | |
3801 }, | |
3802 | |
3803 TAG: function( match, curLoop ) { | |
3804 return match[1].replace( rBackslash, "" ).toLowerCase(); | |
3805 }, | |
3806 | |
3807 CHILD: function( match ) { | |
3808 if ( match[1] === "nth" ) { | |
3809 if ( !match[2] ) { | |
3810 Sizzle.error( match[0] ); | |
3811 } | |
3812 | |
3813 match[2] = match[2].replace(/^\+|\s*/g, ''); | |
3814 | |
3815 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' | |
3816 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( | |
3817 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || | |
3818 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); | |
3819 | |
3820 // calculate the numbers (first)n+(last) including if they are negative | |
3821 match[2] = (test[1] + (test[2] || 1)) - 0; | |
3822 match[3] = test[3] - 0; | |
3823 } | |
3824 else if ( match[2] ) { | |
3825 Sizzle.error( match[0] ); | |
3826 } | |
3827 | |
3828 // TODO: Move to normal caching system | |
3829 match[0] = done++; | |
3830 | |
3831 return match; | |
3832 }, | |
3833 | |
3834 ATTR: function( match, curLoop, inplace, result, not, isXML ) { | |
3835 var name = match[1] = match[1].replace( rBackslash, "" ); | |
3836 | |
3837 if ( !isXML && Expr.attrMap[name] ) { | |
3838 match[1] = Expr.attrMap[name]; | |
3839 } | |
3840 | |
3841 // Handle if an un-quoted value was used | |
3842 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); | |
3843 | |
3844 if ( match[2] === "~=" ) { | |
3845 match[4] = " " + match[4] + " "; | |
3846 } | |
3847 | |
3848 return match; | |
3849 }, | |
3850 | |
3851 PSEUDO: function( match, curLoop, inplace, result, not ) { | |
3852 if ( match[1] === "not" ) { | |
3853 // If we're dealing with a complex expression, or a simple one | |
3854 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { | |
3855 match[3] = Sizzle(match[3], null, null, curLoop); | |
3856 | |
3857 } else { | |
3858 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); | |
3859 | |
3860 if ( !inplace ) { | |
3861 result.push.apply( result, ret ); | |
3862 } | |
3863 | |
3864 return false; | |
3865 } | |
3866 | |
3867 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { | |
3868 return true; | |
3869 } | |
3870 | |
3871 return match; | |
3872 }, | |
3873 | |
3874 POS: function( match ) { | |
3875 match.unshift( true ); | |
3876 | |
3877 return match; | |
3878 } | |
3879 }, | |
3880 | |
3881 filters: { | |
3882 enabled: function( elem ) { | |
3883 return elem.disabled === false && elem.type !== "hidden"; | |
3884 }, | |
3885 | |
3886 disabled: function( elem ) { | |
3887 return elem.disabled === true; | |
3888 }, | |
3889 | |
3890 checked: function( elem ) { | |
3891 return elem.checked === true; | |
3892 }, | |
3893 | |
3894 selected: function( elem ) { | |
3895 // Accessing this property makes selected-by-default | |
3896 // options in Safari work properly | |
3897 if ( elem.parentNode ) { | |
3898 elem.parentNode.selectedIndex; | |
3899 } | |
3900 | |
3901 return elem.selected === true; | |
3902 }, | |
3903 | |
3904 parent: function( elem ) { | |
3905 return !!elem.firstChild; | |
3906 }, | |
3907 | |
3908 empty: function( elem ) { | |
3909 return !elem.firstChild; | |
3910 }, | |
3911 | |
3912 has: function( elem, i, match ) { | |
3913 return !!Sizzle( match[3], elem ).length; | |
3914 }, | |
3915 | |
3916 header: function( elem ) { | |
3917 return (/h\d/i).test( elem.nodeName ); | |
3918 }, | |
3919 | |
3920 text: function( elem ) { | |
3921 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) | |
3922 // use getAttribute instead to test this case | |
3923 return "text" === elem.getAttribute( 'type' ); | |
3924 }, | |
3925 radio: function( elem ) { | |
3926 return "radio" === elem.type; | |
3927 }, | |
3928 | |
3929 checkbox: function( elem ) { | |
3930 return "checkbox" === elem.type; | |
3931 }, | |
3932 | |
3933 file: function( elem ) { | |
3934 return "file" === elem.type; | |
3935 }, | |
3936 password: function( elem ) { | |
3937 return "password" === elem.type; | |
3938 }, | |
3939 | |
3940 submit: function( elem ) { | |
3941 return "submit" === elem.type; | |
3942 }, | |
3943 | |
3944 image: function( elem ) { | |
3945 return "image" === elem.type; | |
3946 }, | |
3947 | |
3948 reset: function( elem ) { | |
3949 return "reset" === elem.type; | |
3950 }, | |
3951 | |
3952 button: function( elem ) { | |
3953 return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; | |
3954 }, | |
3955 | |
3956 input: function( elem ) { | |
3957 return (/input|select|textarea|button/i).test( elem.nodeName ); | |
3958 } | |
3959 }, | |
3960 setFilters: { | |
3961 first: function( elem, i ) { | |
3962 return i === 0; | |
3963 }, | |
3964 | |
3965 last: function( elem, i, match, array ) { | |
3966 return i === array.length - 1; | |
3967 }, | |
3968 | |
3969 even: function( elem, i ) { | |
3970 return i % 2 === 0; | |
3971 }, | |
3972 | |
3973 odd: function( elem, i ) { | |
3974 return i % 2 === 1; | |
3975 }, | |
3976 | |
3977 lt: function( elem, i, match ) { | |
3978 return i < match[3] - 0; | |
3979 }, | |
3980 | |
3981 gt: function( elem, i, match ) { | |
3982 return i > match[3] - 0; | |
3983 }, | |
3984 | |
3985 nth: function( elem, i, match ) { | |
3986 return match[3] - 0 === i; | |
3987 }, | |
3988 | |
3989 eq: function( elem, i, match ) { | |
3990 return match[3] - 0 === i; | |
3991 } | |
3992 }, | |
3993 filter: { | |
3994 PSEUDO: function( elem, match, i, array ) { | |
3995 var name = match[1], | |
3996 filter = Expr.filters[ name ]; | |
3997 | |
3998 if ( filter ) { | |
3999 return filter( elem, i, match, array ); | |
4000 | |
4001 } else if ( name === "contains" ) { | |
4002 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; | |
4003 | |
4004 } else if ( name === "not" ) { | |
4005 var not = match[3]; | |
4006 | |
4007 for ( var j = 0, l = not.length; j < l; j++ ) { | |
4008 if ( not[j] === elem ) { | |
4009 return false; | |
4010 } | |
4011 } | |
4012 | |
4013 return true; | |
4014 | |
4015 } else { | |
4016 Sizzle.error( name ); | |
4017 } | |
4018 }, | |
4019 | |
4020 CHILD: function( elem, match ) { | |
4021 var type = match[1], | |
4022 node = elem; | |
4023 | |
4024 switch ( type ) { | |
4025 case "only": | |
4026 case "first": | |
4027 while ( (node = node.previousSibling) ) { | |
4028 if ( node.nodeType === 1 ) { | |
4029 return false; | |
4030 } | |
4031 } | |
4032 | |
4033 if ( type === "first" ) { | |
4034 return true; | |
4035 } | |
4036 | |
4037 node = elem; | |
4038 | |
4039 case "last": | |
4040 while ( (node = node.nextSibling) ) { | |
4041 if ( node.nodeType === 1 ) { | |
4042 return false; | |
4043 } | |
4044 } | |
4045 | |
4046 return true; | |
4047 | |
4048 case "nth": | |
4049 var first = match[2], | |
4050 last = match[3]; | |
4051 | |
4052 if ( first === 1 && last === 0 ) { | |
4053 return true; | |
4054 } | |
4055 | |
4056 var doneName = match[0], | |
4057 parent = elem.parentNode; | |
4058 | |
4059 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { | |
4060 var count = 0; | |
4061 | |
4062 for ( node = parent.firstChild; node; node = node.nextSibling ) { | |
4063 if ( node.nodeType === 1 ) { | |
4064 node.nodeIndex = ++count; | |
4065 } | |
4066 } | |
4067 | |
4068 parent.sizcache = doneName; | |
4069 } | |
4070 | |
4071 var diff = elem.nodeIndex - last; | |
4072 | |
4073 if ( first === 0 ) { | |
4074 return diff === 0; | |
4075 | |
4076 } else { | |
4077 return ( diff % first === 0 && diff / first >= 0 ); | |
4078 } | |
4079 } | |
4080 }, | |
4081 | |
4082 ID: function( elem, match ) { | |
4083 return elem.nodeType === 1 && elem.getAttribute("id") === match; | |
4084 }, | |
4085 | |
4086 TAG: function( elem, match ) { | |
4087 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; | |
4088 }, | |
4089 | |
4090 CLASS: function( elem, match ) { | |
4091 return (" " + (elem.className || elem.getAttribute("class")) + " ") | |
4092 .indexOf( match ) > -1; | |
4093 }, | |
4094 | |
4095 ATTR: function( elem, match ) { | |
4096 var name = match[1], | |
4097 result = Expr.attrHandle[ name ] ? | |
4098 Expr.attrHandle[ name ]( elem ) : | |
4099 elem[ name ] != null ? | |
4100 elem[ name ] : | |
4101 elem.getAttribute( name ), | |
4102 value = result + "", | |
4103 type = match[2], | |
4104 check = match[4]; | |
4105 | |
4106 return result == null ? | |
4107 type === "!=" : | |
4108 type === "=" ? | |
4109 value === check : | |
4110 type === "*=" ? | |
4111 value.indexOf(check) >= 0 : | |
4112 type === "~=" ? | |
4113 (" " + value + " ").indexOf(check) >= 0 : | |
4114 !check ? | |
4115 value && result !== false : | |
4116 type === "!=" ? | |
4117 value !== check : | |
4118 type === "^=" ? | |
4119 value.indexOf(check) === 0 : | |
4120 type === "$=" ? | |
4121 value.substr(value.length - check.length) === check : | |
4122 type === "|=" ? | |
4123 value === check || value.substr(0, check.length + 1) === check + "-" : | |
4124 false; | |
4125 }, | |
4126 | |
4127 POS: function( elem, match, i, array ) { | |
4128 var name = match[2], | |
4129 filter = Expr.setFilters[ name ]; | |
4130 | |
4131 if ( filter ) { | |
4132 return filter( elem, i, match, array ); | |
4133 } | |
4134 } | |
4135 } | |
4136 }; | |
4137 | |
4138 var origPOS = Expr.match.POS, | |
4139 fescape = function(all, num){ | |
4140 return "\\" + (num - 0 + 1); | |
4141 }; | |
4142 | |
4143 for ( var type in Expr.match ) { | |
4144 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); | |
4145 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); | |
4146 } | |
4147 | |
4148 var makeArray = function( array, results ) { | |
4149 array = Array.prototype.slice.call( array, 0 ); | |
4150 | |
4151 if ( results ) { | |
4152 results.push.apply( results, array ); | |
4153 return results; | |
4154 } | |
4155 | |
4156 return array; | |
4157 }; | |
4158 | |
4159 // Perform a simple check to determine if the browser is capable of | |
4160 // converting a NodeList to an array using builtin methods. | |
4161 // Also verifies that the returned array holds DOM nodes | |
4162 // (which is not the case in the Blackberry browser) | |
4163 try { | |
4164 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; | |
4165 | |
4166 // Provide a fallback method if it does not work | |
4167 } catch( e ) { | |
4168 makeArray = function( array, results ) { | |
4169 var i = 0, | |
4170 ret = results || []; | |
4171 | |
4172 if ( toString.call(array) === "[object Array]" ) { | |
4173 Array.prototype.push.apply( ret, array ); | |
4174 | |
4175 } else { | |
4176 if ( typeof array.length === "number" ) { | |
4177 for ( var l = array.length; i < l; i++ ) { | |
4178 ret.push( array[i] ); | |
4179 } | |
4180 | |
4181 } else { | |
4182 for ( ; array[i]; i++ ) { | |
4183 ret.push( array[i] ); | |
4184 } | |
4185 } | |
4186 } | |
4187 | |
4188 return ret; | |
4189 }; | |
4190 } | |
4191 | |
4192 var sortOrder, siblingCheck; | |
4193 | |
4194 if ( document.documentElement.compareDocumentPosition ) { | |
4195 sortOrder = function( a, b ) { | |
4196 if ( a === b ) { | |
4197 hasDuplicate = true; | |
4198 return 0; | |
4199 } | |
4200 | |
4201 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { | |
4202 return a.compareDocumentPosition ? -1 : 1; | |
4203 } | |
4204 | |
4205 return a.compareDocumentPosition(b) & 4 ? -1 : 1; | |
4206 }; | |
4207 | |
4208 } else { | |
4209 sortOrder = function( a, b ) { | |
4210 var al, bl, | |
4211 ap = [], | |
4212 bp = [], | |
4213 aup = a.parentNode, | |
4214 bup = b.parentNode, | |
4215 cur = aup; | |
4216 | |
4217 // The nodes are identical, we can exit early | |
4218 if ( a === b ) { | |
4219 hasDuplicate = true; | |
4220 return 0; | |
4221 | |
4222 // If the nodes are siblings (or identical) we can do a quick check | |
4223 } else if ( aup === bup ) { | |
4224 return siblingCheck( a, b ); | |
4225 | |
4226 // If no parents were found then the nodes are disconnected | |
4227 } else if ( !aup ) { | |
4228 return -1; | |
4229 | |
4230 } else if ( !bup ) { | |
4231 return 1; | |
4232 } | |
4233 | |
4234 // Otherwise they're somewhere else in the tree so we need | |
4235 // to build up a full list of the parentNodes for comparison | |
4236 while ( cur ) { | |
4237 ap.unshift( cur ); | |
4238 cur = cur.parentNode; | |
4239 } | |
4240 | |
4241 cur = bup; | |
4242 | |
4243 while ( cur ) { | |
4244 bp.unshift( cur ); | |
4245 cur = cur.parentNode; | |
4246 } | |
4247 | |
4248 al = ap.length; | |
4249 bl = bp.length; | |
4250 | |
4251 // Start walking down the tree looking for a discrepancy | |
4252 for ( var i = 0; i < al && i < bl; i++ ) { | |
4253 if ( ap[i] !== bp[i] ) { | |
4254 return siblingCheck( ap[i], bp[i] ); | |
4255 } | |
4256 } | |
4257 | |
4258 // We ended someplace up the tree so do a sibling check | |
4259 return i === al ? | |
4260 siblingCheck( a, bp[i], -1 ) : | |
4261 siblingCheck( ap[i], b, 1 ); | |
4262 }; | |
4263 | |
4264 siblingCheck = function( a, b, ret ) { | |
4265 if ( a === b ) { | |
4266 return ret; | |
4267 } | |
4268 | |
4269 var cur = a.nextSibling; | |
4270 | |
4271 while ( cur ) { | |
4272 if ( cur === b ) { | |
4273 return -1; | |
4274 } | |
4275 | |
4276 cur = cur.nextSibling; | |
4277 } | |
4278 | |
4279 return 1; | |
4280 }; | |
4281 } | |
4282 | |
4283 // Utility function for retreiving the text value of an array of DOM nodes | |
4284 Sizzle.getText = function( elems ) { | |
4285 var ret = "", elem; | |
4286 | |
4287 for ( var i = 0; elems[i]; i++ ) { | |
4288 elem = elems[i]; | |
4289 | |
4290 // Get the text from text nodes and CDATA nodes | |
4291 if ( elem.nodeType === 3 || elem.nodeType === 4 ) { | |
4292 ret += elem.nodeValue; | |
4293 | |
4294 // Traverse everything else, except comment nodes | |
4295 } else if ( elem.nodeType !== 8 ) { | |
4296 ret += Sizzle.getText( elem.childNodes ); | |
4297 } | |
4298 } | |
4299 | |
4300 return ret; | |
4301 }; | |
4302 | |
4303 // Check to see if the browser returns elements by name when | |
4304 // querying by getElementById (and provide a workaround) | |
4305 (function(){ | |
4306 // We're going to inject a fake input element with a specified name | |
4307 var form = document.createElement("div"), | |
4308 id = "script" + (new Date()).getTime(), | |
4309 root = document.documentElement; | |
4310 | |
4311 form.innerHTML = "<a name='" + id + "'/>"; | |
4312 | |
4313 // Inject it into the root element, check its status, and remove it quickly | |
4314 root.insertBefore( form, root.firstChild ); | |
4315 | |
4316 // The workaround has to do additional checks after a getElementById | |
4317 // Which slows things down for other browsers (hence the branching) | |
4318 if ( document.getElementById( id ) ) { | |
4319 Expr.find.ID = function( match, context, isXML ) { | |
4320 if ( typeof context.getElementById !== "undefined" && !isXML ) { | |
4321 var m = context.getElementById(match[1]); | |
4322 | |
4323 return m ? | |
4324 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? | |
4325 [m] : | |
4326 undefined : | |
4327 []; | |
4328 } | |
4329 }; | |
4330 | |
4331 Expr.filter.ID = function( elem, match ) { | |
4332 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); | |
4333 | |
4334 return elem.nodeType === 1 && node && node.nodeValue === match; | |
4335 }; | |
4336 } | |
4337 | |
4338 root.removeChild( form ); | |
4339 | |
4340 // release memory in IE | |
4341 root = form = null; | |
4342 })(); | |
4343 | |
4344 (function(){ | |
4345 // Check to see if the browser returns only elements | |
4346 // when doing getElementsByTagName("*") | |
4347 | |
4348 // Create a fake element | |
4349 var div = document.createElement("div"); | |
4350 div.appendChild( document.createComment("") ); | |
4351 | |
4352 // Make sure no comments are found | |
4353 if ( div.getElementsByTagName("*").length > 0 ) { | |
4354 Expr.find.TAG = function( match, context ) { | |
4355 var results = context.getElementsByTagName( match[1] ); | |
4356 | |
4357 // Filter out possible comments | |
4358 if ( match[1] === "*" ) { | |
4359 var tmp = []; | |
4360 | |
4361 for ( var i = 0; results[i]; i++ ) { | |
4362 if ( results[i].nodeType === 1 ) { | |
4363 tmp.push( results[i] ); | |
4364 } | |
4365 } | |
4366 | |
4367 results = tmp; | |
4368 } | |
4369 | |
4370 return results; | |
4371 }; | |
4372 } | |
4373 | |
4374 // Check to see if an attribute returns normalized href attributes | |
4375 div.innerHTML = "<a href='#'></a>"; | |
4376 | |
4377 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && | |
4378 div.firstChild.getAttribute("href") !== "#" ) { | |
4379 | |
4380 Expr.attrHandle.href = function( elem ) { | |
4381 return elem.getAttribute( "href", 2 ); | |
4382 }; | |
4383 } | |
4384 | |
4385 // release memory in IE | |
4386 div = null; | |
4387 })(); | |
4388 | |
4389 if ( document.querySelectorAll ) { | |
4390 (function(){ | |
4391 var oldSizzle = Sizzle, | |
4392 div = document.createElement("div"), | |
4393 id = "__sizzle__"; | |
4394 | |
4395 div.innerHTML = "<p class='TEST'></p>"; | |
4396 | |
4397 // Safari can't handle uppercase or unicode characters when | |
4398 // in quirks mode. | |
4399 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { | |
4400 return; | |
4401 } | |
4402 | |
4403 Sizzle = function( query, context, extra, seed ) { | |
4404 context = context || document; | |
4405 | |
4406 // Only use querySelectorAll on non-XML documents | |
4407 // (ID selectors don't work in non-HTML documents) | |
4408 if ( !seed && !Sizzle.isXML(context) ) { | |
4409 // See if we find a selector to speed up | |
4410 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); | |
4411 | |
4412 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { | |
4413 // Speed-up: Sizzle("TAG") | |
4414 if ( match[1] ) { | |
4415 return makeArray( context.getElementsByTagName( query ), extra ); | |
4416 | |
4417 // Speed-up: Sizzle(".CLASS") | |
4418 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { | |
4419 return makeArray( context.getElementsByClassName( match[2] ), extra ); | |
4420 } | |
4421 } | |
4422 | |
4423 if ( context.nodeType === 9 ) { | |
4424 // Speed-up: Sizzle("body") | |
4425 // The body element only exists once, optimize finding it | |
4426 if ( query === "body" && context.body ) { | |
4427 return makeArray( [ context.body ], extra ); | |
4428 | |
4429 // Speed-up: Sizzle("#ID") | |
4430 } else if ( match && match[3] ) { | |
4431 var elem = context.getElementById( match[3] ); | |
4432 | |
4433 // Check parentNode to catch when Blackberry 4.6 returns | |
4434 // nodes that are no longer in the document #6963 | |
4435 if ( elem && elem.parentNode ) { | |
4436 // Handle the case where IE and Opera return items | |
4437 // by name instead of ID | |
4438 if ( elem.id === match[3] ) { | |
4439 return makeArray( [ elem ], extra ); | |
4440 } | |
4441 | |
4442 } else { | |
4443 return makeArray( [], extra ); | |
4444 } | |
4445 } | |
4446 | |
4447 try { | |
4448 return makeArray( context.querySelectorAll(query), extra ); | |
4449 } catch(qsaError) {} | |
4450 | |
4451 // qSA works strangely on Element-rooted queries | |
4452 // We can work around this by specifying an extra ID on the root | |
4453 // and working up from there (Thanks to Andrew Dupont for the technique) | |
4454 // IE 8 doesn't work on object elements | |
4455 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { | |
4456 var oldContext = context, | |
4457 old = context.getAttribute( "id" ), | |
4458 nid = old || id, | |
4459 hasParent = context.parentNode, | |
4460 relativeHierarchySelector = /^\s*[+~]/.test( query ); | |
4461 | |
4462 if ( !old ) { | |
4463 context.setAttribute( "id", nid ); | |
4464 } else { | |
4465 nid = nid.replace( /'/g, "\\$&" ); | |
4466 } | |
4467 if ( relativeHierarchySelector && hasParent ) { | |
4468 context = context.parentNode; | |
4469 } | |
4470 | |
4471 try { | |
4472 if ( !relativeHierarchySelector || hasParent ) { | |
4473 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); | |
4474 } | |
4475 | |
4476 } catch(pseudoError) { | |
4477 } finally { | |
4478 if ( !old ) { | |
4479 oldContext.removeAttribute( "id" ); | |
4480 } | |
4481 } | |
4482 } | |
4483 } | |
4484 | |
4485 return oldSizzle(query, context, extra, seed); | |
4486 }; | |
4487 | |
4488 for ( var prop in oldSizzle ) { | |
4489 Sizzle[ prop ] = oldSizzle[ prop ]; | |
4490 } | |
4491 | |
4492 // release memory in IE | |
4493 div = null; | |
4494 })(); | |
4495 } | |
4496 | |
4497 (function(){ | |
4498 var html = document.documentElement, | |
4499 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector, | |
4500 pseudoWorks = false; | |
4501 | |
4502 try { | |
4503 // This should fail with an exception | |
4504 // Gecko does not error, returns false instead | |
4505 matches.call( document.documentElement, "[test!='']:sizzle" ); | |
4506 | |
4507 } catch( pseudoError ) { | |
4508 pseudoWorks = true; | |
4509 } | |
4510 | |
4511 if ( matches ) { | |
4512 Sizzle.matchesSelector = function( node, expr ) { | |
4513 // Make sure that attribute selectors are quoted | |
4514 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); | |
4515 | |
4516 if ( !Sizzle.isXML( node ) ) { | |
4517 try { | |
4518 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { | |
4519 return matches.call( node, expr ); | |
4520 } | |
4521 } catch(e) {} | |
4522 } | |
4523 | |
4524 return Sizzle(expr, null, null, [node]).length > 0; | |
4525 }; | |
4526 } | |
4527 })(); | |
4528 | |
4529 (function(){ | |
4530 var div = document.createElement("div"); | |
4531 | |
4532 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; | |
4533 | |
4534 // Opera can't find a second classname (in 9.6) | |
4535 // Also, make sure that getElementsByClassName actually exists | |
4536 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { | |
4537 return; | |
4538 } | |
4539 | |
4540 // Safari caches class attributes, doesn't catch changes (in 3.2) | |
4541 div.lastChild.className = "e"; | |
4542 | |
4543 if ( div.getElementsByClassName("e").length === 1 ) { | |
4544 return; | |
4545 } | |
4546 | |
4547 Expr.order.splice(1, 0, "CLASS"); | |
4548 Expr.find.CLASS = function( match, context, isXML ) { | |
4549 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { | |
4550 return context.getElementsByClassName(match[1]); | |
4551 } | |
4552 }; | |
4553 | |
4554 // release memory in IE | |
4555 div = null; | |
4556 })(); | |
4557 | |
4558 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { | |
4559 for ( var i = 0, l = checkSet.length; i < l; i++ ) { | |
4560 var elem = checkSet[i]; | |
4561 | |
4562 if ( elem ) { | |
4563 var match = false; | |
4564 | |
4565 elem = elem[dir]; | |
4566 | |
4567 while ( elem ) { | |
4568 if ( elem.sizcache === doneName ) { | |
4569 match = checkSet[elem.sizset]; | |
4570 break; | |
4571 } | |
4572 | |
4573 if ( elem.nodeType === 1 && !isXML ){ | |
4574 elem.sizcache = doneName; | |
4575 elem.sizset = i; | |
4576 } | |
4577 | |
4578 if ( elem.nodeName.toLowerCase() === cur ) { | |
4579 match = elem; | |
4580 break; | |
4581 } | |
4582 | |
4583 elem = elem[dir]; | |
4584 } | |
4585 | |
4586 checkSet[i] = match; | |
4587 } | |
4588 } | |
4589 } | |
4590 | |
4591 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { | |
4592 for ( var i = 0, l = checkSet.length; i < l; i++ ) { | |
4593 var elem = checkSet[i]; | |
4594 | |
4595 if ( elem ) { | |
4596 var match = false; | |
4597 | |
4598 elem = elem[dir]; | |
4599 | |
4600 while ( elem ) { | |
4601 if ( elem.sizcache === doneName ) { | |
4602 match = checkSet[elem.sizset]; | |
4603 break; | |
4604 } | |
4605 | |
4606 if ( elem.nodeType === 1 ) { | |
4607 if ( !isXML ) { | |
4608 elem.sizcache = doneName; | |
4609 elem.sizset = i; | |
4610 } | |
4611 | |
4612 if ( typeof cur !== "string" ) { | |
4613 if ( elem === cur ) { | |
4614 match = true; | |
4615 break; | |
4616 } | |
4617 | |
4618 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { | |
4619 match = elem; | |
4620 break; | |
4621 } | |
4622 } | |
4623 | |
4624 elem = elem[dir]; | |
4625 } | |
4626 | |
4627 checkSet[i] = match; | |
4628 } | |
4629 } | |
4630 } | |
4631 | |
4632 if ( document.documentElement.contains ) { | |
4633 Sizzle.contains = function( a, b ) { | |
4634 return a !== b && (a.contains ? a.contains(b) : true); | |
4635 }; | |
4636 | |
4637 } else if ( document.documentElement.compareDocumentPosition ) { | |
4638 Sizzle.contains = function( a, b ) { | |
4639 return !!(a.compareDocumentPosition(b) & 16); | |
4640 }; | |
4641 | |
4642 } else { | |
4643 Sizzle.contains = function() { | |
4644 return false; | |
4645 }; | |
4646 } | |
4647 | |
4648 Sizzle.isXML = function( elem ) { | |
4649 // documentElement is verified for cases where it doesn't yet exist | |
4650 // (such as loading iframes in IE - #4833) | |
4651 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; | |
4652 | |
4653 return documentElement ? documentElement.nodeName !== "HTML" : false; | |
4654 }; | |
4655 | |
4656 var posProcess = function( selector, context ) { | |
4657 var match, | |
4658 tmpSet = [], | |
4659 later = "", | |
4660 root = context.nodeType ? [context] : context; | |
4661 | |
4662 // Position selectors must be done after the filter | |
4663 // And so must :not(positional) so we move all PSEUDOs to the end | |
4664 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { | |
4665 later += match[0]; | |
4666 selector = selector.replace( Expr.match.PSEUDO, "" ); | |
4667 } | |
4668 | |
4669 selector = Expr.relative[selector] ? selector + "*" : selector; | |
4670 | |
4671 for ( var i = 0, l = root.length; i < l; i++ ) { | |
4672 Sizzle( selector, root[i], tmpSet ); | |
4673 } | |
4674 | |
4675 return Sizzle.filter( later, tmpSet ); | |
4676 }; | |
4677 | |
4678 // EXPOSE | |
4679 jQuery.find = Sizzle; | |
4680 jQuery.expr = Sizzle.selectors; | |
4681 jQuery.expr[":"] = jQuery.expr.filters; | |
4682 jQuery.unique = Sizzle.uniqueSort; | |
4683 jQuery.text = Sizzle.getText; | |
4684 jQuery.isXMLDoc = Sizzle.isXML; | |
4685 jQuery.contains = Sizzle.contains; | |
4686 | |
4687 | |
4688 })(); | |
4689 | |
4690 | |
4691 var runtil = /Until$/, | |
4692 rparentsprev = /^(?:parents|prevUntil|prevAll)/, | |
4693 // Note: This RegExp should be improved, or likely pulled from Sizzle | |
4694 rmultiselector = /,/, | |
4695 isSimple = /^.[^:#\[\.,]*$/, | |
4696 slice = Array.prototype.slice, | |
4697 POS = jQuery.expr.match.POS, | |
4698 // methods guaranteed to produce a unique set when starting from a unique set | |
4699 guaranteedUnique = { | |
4700 children: true, | |
4701 contents: true, | |
4702 next: true, | |
4703 prev: true | |
4704 }; | |
4705 | |
4706 jQuery.fn.extend({ | |
4707 find: function( selector ) { | |
4708 var ret = this.pushStack( "", "find", selector ), | |
4709 length = 0; | |
4710 | |
4711 for ( var i = 0, l = this.length; i < l; i++ ) { | |
4712 length = ret.length; | |
4713 jQuery.find( selector, this[i], ret ); | |
4714 | |
4715 if ( i > 0 ) { | |
4716 // Make sure that the results are unique | |
4717 for ( var n = length; n < ret.length; n++ ) { | |
4718 for ( var r = 0; r < length; r++ ) { | |
4719 if ( ret[r] === ret[n] ) { | |
4720 ret.splice(n--, 1); | |
4721 break; | |
4722 } | |
4723 } | |
4724 } | |
4725 } | |
4726 } | |
4727 | |
4728 return ret; | |
4729 }, | |
4730 | |
4731 has: function( target ) { | |
4732 var targets = jQuery( target ); | |
4733 return this.filter(function() { | |
4734 for ( var i = 0, l = targets.length; i < l; i++ ) { | |
4735 if ( jQuery.contains( this, targets[i] ) ) { | |
4736 return true; | |
4737 } | |
4738 } | |
4739 }); | |
4740 }, | |
4741 | |
4742 not: function( selector ) { | |
4743 return this.pushStack( winnow(this, selector, false), "not", selector); | |
4744 }, | |
4745 | |
4746 filter: function( selector ) { | |
4747 return this.pushStack( winnow(this, selector, true), "filter", selector ); | |
4748 }, | |
4749 | |
4750 is: function( selector ) { | |
4751 return !!selector && jQuery.filter( selector, this ).length > 0; | |
4752 }, | |
4753 | |
4754 closest: function( selectors, context ) { | |
4755 var ret = [], i, l, cur = this[0]; | |
4756 | |
4757 if ( jQuery.isArray( selectors ) ) { | |
4758 var match, selector, | |
4759 matches = {}, | |
4760 level = 1; | |
4761 | |
4762 if ( cur && selectors.length ) { | |
4763 for ( i = 0, l = selectors.length; i < l; i++ ) { | |
4764 selector = selectors[i]; | |
4765 | |
4766 if ( !matches[selector] ) { | |
4767 matches[selector] = jQuery.expr.match.POS.test( selector ) ? | |
4768 jQuery( selector, context || this.context ) : | |
4769 selector; | |
4770 } | |
4771 } | |
4772 | |
4773 while ( cur && cur.ownerDocument && cur !== context ) { | |
4774 for ( selector in matches ) { | |
4775 match = matches[selector]; | |
4776 | |
4777 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { | |
4778 ret.push({ selector: selector, elem: cur, level: level }); | |
4779 } | |
4780 } | |
4781 | |
4782 cur = cur.parentNode; | |
4783 level++; | |
4784 } | |
4785 } | |
4786 | |
4787 return ret; | |
4788 } | |
4789 | |
4790 var pos = POS.test( selectors ) ? | |
4791 jQuery( selectors, context || this.context ) : null; | |
4792 | |
4793 for ( i = 0, l = this.length; i < l; i++ ) { | |
4794 cur = this[i]; | |
4795 | |
4796 while ( cur ) { | |
4797 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { | |
4798 ret.push( cur ); | |
4799 break; | |
4800 | |
4801 } else { | |
4802 cur = cur.parentNode; | |
4803 if ( !cur || !cur.ownerDocument || cur === context ) { | |
4804 break; | |
4805 } | |
4806 } | |
4807 } | |
4808 } | |
4809 | |
4810 ret = ret.length > 1 ? jQuery.unique(ret) : ret; | |
4811 | |
4812 return this.pushStack( ret, "closest", selectors ); | |
4813 }, | |
4814 | |
4815 // Determine the position of an element within | |
4816 // the matched set of elements | |
4817 index: function( elem ) { | |
4818 if ( !elem || typeof elem === "string" ) { | |
4819 return jQuery.inArray( this[0], | |
4820 // If it receives a string, the selector is used | |
4821 // If it receives nothing, the siblings are used | |
4822 elem ? jQuery( elem ) : this.parent().children() ); | |
4823 } | |
4824 // Locate the position of the desired element | |
4825 return jQuery.inArray( | |
4826 // If it receives a jQuery object, the first element is used | |
4827 elem.jquery ? elem[0] : elem, this ); | |
4828 }, | |
4829 | |
4830 add: function( selector, context ) { | |
4831 var set = typeof selector === "string" ? | |
4832 jQuery( selector, context ) : | |
4833 jQuery.makeArray( selector ), | |
4834 all = jQuery.merge( this.get(), set ); | |
4835 | |
4836 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? | |
4837 all : | |
4838 jQuery.unique( all ) ); | |
4839 }, | |
4840 | |
4841 andSelf: function() { | |
4842 return this.add( this.prevObject ); | |
4843 } | |
4844 }); | |
4845 | |
4846 // A painfully simple check to see if an element is disconnected | |
4847 // from a document (should be improved, where feasible). | |
4848 function isDisconnected( node ) { | |
4849 return !node || !node.parentNode || node.parentNode.nodeType === 11; | |
4850 } | |
4851 | |
4852 jQuery.each({ | |
4853 parent: function( elem ) { | |
4854 var parent = elem.parentNode; | |
4855 return parent && parent.nodeType !== 11 ? parent : null; | |
4856 }, | |
4857 parents: function( elem ) { | |
4858 return jQuery.dir( elem, "parentNode" ); | |
4859 }, | |
4860 parentsUntil: function( elem, i, until ) { | |
4861 return jQuery.dir( elem, "parentNode", until ); | |
4862 }, | |
4863 next: function( elem ) { | |
4864 return jQuery.nth( elem, 2, "nextSibling" ); | |
4865 }, | |
4866 prev: function( elem ) { | |
4867 return jQuery.nth( elem, 2, "previousSibling" ); | |
4868 }, | |
4869 nextAll: function( elem ) { | |
4870 return jQuery.dir( elem, "nextSibling" ); | |
4871 }, | |
4872 prevAll: function( elem ) { | |
4873 return jQuery.dir( elem, "previousSibling" ); | |
4874 }, | |
4875 nextUntil: function( elem, i, until ) { | |
4876 return jQuery.dir( elem, "nextSibling", until ); | |
4877 }, | |
4878 prevUntil: function( elem, i, until ) { | |
4879 return jQuery.dir( elem, "previousSibling", until ); | |
4880 }, | |
4881 siblings: function( elem ) { | |
4882 return jQuery.sibling( elem.parentNode.firstChild, elem ); | |
4883 }, | |
4884 children: function( elem ) { | |
4885 return jQuery.sibling( elem.firstChild ); | |
4886 }, | |
4887 contents: function( elem ) { | |
4888 return jQuery.nodeName( elem, "iframe" ) ? | |
4889 elem.contentDocument || elem.contentWindow.document : | |
4890 jQuery.makeArray( elem.childNodes ); | |
4891 } | |
4892 }, function( name, fn ) { | |
4893 jQuery.fn[ name ] = function( until, selector ) { | |
4894 var ret = jQuery.map( this, fn, until ), | |
4895 // The variable 'args' was introduced in | |
4896 // https://github.com/jquery/jquery/commit/52a0238 | |
4897 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. | |
4898 // http://code.google.com/p/v8/issues/detail?id=1050 | |
4899 args = slice.call(arguments); | |
4900 | |
4901 if ( !runtil.test( name ) ) { | |
4902 selector = until; | |
4903 } | |
4904 | |
4905 if ( selector && typeof selector === "string" ) { | |
4906 ret = jQuery.filter( selector, ret ); | |
4907 } | |
4908 | |
4909 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; | |
4910 | |
4911 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { | |
4912 ret = ret.reverse(); | |
4913 } | |
4914 | |
4915 return this.pushStack( ret, name, args.join(",") ); | |
4916 }; | |
4917 }); | |
4918 | |
4919 jQuery.extend({ | |
4920 filter: function( expr, elems, not ) { | |
4921 if ( not ) { | |
4922 expr = ":not(" + expr + ")"; | |
4923 } | |
4924 | |
4925 return elems.length === 1 ? | |
4926 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : | |
4927 jQuery.find.matches(expr, elems); | |
4928 }, | |
4929 | |
4930 dir: function( elem, dir, until ) { | |
4931 var matched = [], | |
4932 cur = elem[ dir ]; | |
4933 | |
4934 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { | |
4935 if ( cur.nodeType === 1 ) { | |
4936 matched.push( cur ); | |
4937 } | |
4938 cur = cur[dir]; | |
4939 } | |
4940 return matched; | |
4941 }, | |
4942 | |
4943 nth: function( cur, result, dir, elem ) { | |
4944 result = result || 1; | |
4945 var num = 0; | |
4946 | |
4947 for ( ; cur; cur = cur[dir] ) { | |
4948 if ( cur.nodeType === 1 && ++num === result ) { | |
4949 break; | |
4950 } | |
4951 } | |
4952 | |
4953 return cur; | |
4954 }, | |
4955 | |
4956 sibling: function( n, elem ) { | |
4957 var r = []; | |
4958 | |
4959 for ( ; n; n = n.nextSibling ) { | |
4960 if ( n.nodeType === 1 && n !== elem ) { | |
4961 r.push( n ); | |
4962 } | |
4963 } | |
4964 | |
4965 return r; | |
4966 } | |
4967 }); | |
4968 | |
4969 // Implement the identical functionality for filter and not | |
4970 function winnow( elements, qualifier, keep ) { | |
4971 if ( jQuery.isFunction( qualifier ) ) { | |
4972 return jQuery.grep(elements, function( elem, i ) { | |
4973 var retVal = !!qualifier.call( elem, i, elem ); | |
4974 return retVal === keep; | |
4975 }); | |
4976 | |
4977 } else if ( qualifier.nodeType ) { | |
4978 return jQuery.grep(elements, function( elem, i ) { | |
4979 return (elem === qualifier) === keep; | |
4980 }); | |
4981 | |
4982 } else if ( typeof qualifier === "string" ) { | |
4983 var filtered = jQuery.grep(elements, function( elem ) { | |
4984 return elem.nodeType === 1; | |
4985 }); | |
4986 | |
4987 if ( isSimple.test( qualifier ) ) { | |
4988 return jQuery.filter(qualifier, filtered, !keep); | |
4989 } else { | |
4990 qualifier = jQuery.filter( qualifier, filtered ); | |
4991 } | |
4992 } | |
4993 | |
4994 return jQuery.grep(elements, function( elem, i ) { | |
4995 return (jQuery.inArray( elem, qualifier ) >= 0) === keep; | |
4996 }); | |
4997 } | |
4998 | |
4999 | |
5000 | |
5001 | |
5002 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, | |
5003 rleadingWhitespace = /^\s+/, | |
5004 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, | |
5005 rtagName = /<([\w:]+)/, | |
5006 rtbody = /<tbody/i, | |
5007 rhtml = /<|&#?\w+;/, | |
5008 rnocache = /<(?:script|object|embed|option|style)/i, | |
5009 // checked="checked" or checked | |
5010 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, | |
5011 wrapMap = { | |
5012 option: [ 1, "<select multiple='multiple'>", "</select>" ], | |
5013 legend: [ 1, "<fieldset>", "</fieldset>" ], | |
5014 thead: [ 1, "<table>", "</table>" ], | |
5015 tr: [ 2, "<table><tbody>", "</tbody></table>" ], | |
5016 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], | |
5017 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], | |
5018 area: [ 1, "<map>", "</map>" ], | |
5019 _default: [ 0, "", "" ] | |
5020 }; | |
5021 | |
5022 wrapMap.optgroup = wrapMap.option; | |
5023 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; | |
5024 wrapMap.th = wrapMap.td; | |
5025 | |
5026 // IE can't serialize <link> and <script> tags normally | |
5027 if ( !jQuery.support.htmlSerialize ) { | |
5028 wrapMap._default = [ 1, "div<div>", "</div>" ]; | |
5029 } | |
5030 | |
5031 jQuery.fn.extend({ | |
5032 text: function( text ) { | |
5033 if ( jQuery.isFunction(text) ) { | |
5034 return this.each(function(i) { | |
5035 var self = jQuery( this ); | |
5036 | |
5037 self.text( text.call(this, i, self.text()) ); | |
5038 }); | |
5039 } | |
5040 | |
5041 if ( typeof text !== "object" && text !== undefined ) { | |
5042 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); | |
5043 } | |
5044 | |
5045 return jQuery.text( this ); | |
5046 }, | |
5047 | |
5048 wrapAll: function( html ) { | |
5049 if ( jQuery.isFunction( html ) ) { | |
5050 return this.each(function(i) { | |
5051 jQuery(this).wrapAll( html.call(this, i) ); | |
5052 }); | |
5053 } | |
5054 | |
5055 if ( this[0] ) { | |
5056 // The elements to wrap the target around | |
5057 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); | |
5058 | |
5059 if ( this[0].parentNode ) { | |
5060 wrap.insertBefore( this[0] ); | |
5061 } | |
5062 | |
5063 wrap.map(function() { | |
5064 var elem = this; | |
5065 | |
5066 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { | |
5067 elem = elem.firstChild; | |
5068 } | |
5069 | |
5070 return elem; | |
5071 }).append(this); | |
5072 } | |
5073 | |
5074 return this; | |
5075 }, | |
5076 | |
5077 wrapInner: function( html ) { | |
5078 if ( jQuery.isFunction( html ) ) { | |
5079 return this.each(function(i) { | |
5080 jQuery(this).wrapInner( html.call(this, i) ); | |
5081 }); | |
5082 } | |
5083 | |
5084 return this.each(function() { | |
5085 var self = jQuery( this ), | |
5086 contents = self.contents(); | |
5087 | |
5088 if ( contents.length ) { | |
5089 contents.wrapAll( html ); | |
5090 | |
5091 } else { | |
5092 self.append( html ); | |
5093 } | |
5094 }); | |
5095 }, | |
5096 | |
5097 wrap: function( html ) { | |
5098 return this.each(function() { | |
5099 jQuery( this ).wrapAll( html ); | |
5100 }); | |
5101 }, | |
5102 | |
5103 unwrap: function() { | |
5104 return this.parent().each(function() { | |
5105 if ( !jQuery.nodeName( this, "body" ) ) { | |
5106 jQuery( this ).replaceWith( this.childNodes ); | |
5107 } | |
5108 }).end(); | |
5109 }, | |
5110 | |
5111 append: function() { | |
5112 return this.domManip(arguments, true, function( elem ) { | |
5113 if ( this.nodeType === 1 ) { | |
5114 this.appendChild( elem ); | |
5115 } | |
5116 }); | |
5117 }, | |
5118 | |
5119 prepend: function() { | |
5120 return this.domManip(arguments, true, function( elem ) { | |
5121 if ( this.nodeType === 1 ) { | |
5122 this.insertBefore( elem, this.firstChild ); | |
5123 } | |
5124 }); | |
5125 }, | |
5126 | |
5127 before: function() { | |
5128 if ( this[0] && this[0].parentNode ) { | |
5129 return this.domManip(arguments, false, function( elem ) { | |
5130 this.parentNode.insertBefore( elem, this ); | |
5131 }); | |
5132 } else if ( arguments.length ) { | |
5133 var set = jQuery(arguments[0]); | |
5134 set.push.apply( set, this.toArray() ); | |
5135 return this.pushStack( set, "before", arguments ); | |
5136 } | |
5137 }, | |
5138 | |
5139 after: function() { | |
5140 if ( this[0] && this[0].parentNode ) { | |
5141 return this.domManip(arguments, false, function( elem ) { | |
5142 this.parentNode.insertBefore( elem, this.nextSibling ); | |
5143 }); | |
5144 } else if ( arguments.length ) { | |
5145 var set = this.pushStack( this, "after", arguments ); | |
5146 set.push.apply( set, jQuery(arguments[0]).toArray() ); | |
5147 return set; | |
5148 } | |
5149 }, | |
5150 | |
5151 // keepData is for internal use only--do not document | |
5152 remove: function( selector, keepData ) { | |
5153 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { | |
5154 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { | |
5155 if ( !keepData && elem.nodeType === 1 ) { | |
5156 jQuery.cleanData( elem.getElementsByTagName("*") ); | |
5157 jQuery.cleanData( [ elem ] ); | |
5158 } | |
5159 | |
5160 if ( elem.parentNode ) { | |
5161 elem.parentNode.removeChild( elem ); | |
5162 } | |
5163 } | |
5164 } | |
5165 | |
5166 return this; | |
5167 }, | |
5168 | |
5169 empty: function() { | |
5170 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { | |
5171 // Remove element nodes and prevent memory leaks | |
5172 if ( elem.nodeType === 1 ) { | |
5173 jQuery.cleanData( elem.getElementsByTagName("*") ); | |
5174 } | |
5175 | |
5176 // Remove any remaining nodes | |
5177 while ( elem.firstChild ) { | |
5178 elem.removeChild( elem.firstChild ); | |
5179 } | |
5180 } | |
5181 | |
5182 return this; | |
5183 }, | |
5184 | |
5185 clone: function( dataAndEvents, deepDataAndEvents ) { | |
5186 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; | |
5187 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; | |
5188 | |
5189 return this.map( function () { | |
5190 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); | |
5191 }); | |
5192 }, | |
5193 | |
5194 html: function( value ) { | |
5195 if ( value === undefined ) { | |
5196 return this[0] && this[0].nodeType === 1 ? | |
5197 this[0].innerHTML.replace(rinlinejQuery, "") : | |
5198 null; | |
5199 | |
5200 // See if we can take a shortcut and just use innerHTML | |
5201 } else if ( typeof value === "string" && !rnocache.test( value ) && | |
5202 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && | |
5203 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { | |
5204 | |
5205 value = value.replace(rxhtmlTag, "<$1></$2>"); | |
5206 | |
5207 try { | |
5208 for ( var i = 0, l = this.length; i < l; i++ ) { | |
5209 // Remove element nodes and prevent memory leaks | |
5210 if ( this[i].nodeType === 1 ) { | |
5211 jQuery.cleanData( this[i].getElementsByTagName("*") ); | |
5212 this[i].innerHTML = value; | |
5213 } | |
5214 } | |
5215 | |
5216 // If using innerHTML throws an exception, use the fallback method | |
5217 } catch(e) { | |
5218 this.empty().append( value ); | |
5219 } | |
5220 | |
5221 } else if ( jQuery.isFunction( value ) ) { | |
5222 this.each(function(i){ | |
5223 var self = jQuery( this ); | |
5224 | |
5225 self.html( value.call(this, i, self.html()) ); | |
5226 }); | |
5227 | |
5228 } else { | |
5229 this.empty().append( value ); | |
5230 } | |
5231 | |
5232 return this; | |
5233 }, | |
5234 | |
5235 replaceWith: function( value ) { | |
5236 if ( this[0] && this[0].parentNode ) { | |
5237 // Make sure that the elements are removed from the DOM before they are inserted | |
5238 // this can help fix replacing a parent with child elements | |
5239 if ( jQuery.isFunction( value ) ) { | |
5240 return this.each(function(i) { | |
5241 var self = jQuery(this), old = self.html(); | |
5242 self.replaceWith( value.call( this, i, old ) ); | |
5243 }); | |
5244 } | |
5245 | |
5246 if ( typeof value !== "string" ) { | |
5247 value = jQuery( value ).detach(); | |
5248 } | |
5249 | |
5250 return this.each(function() { | |
5251 var next = this.nextSibling, | |
5252 parent = this.parentNode; | |
5253 | |
5254 jQuery( this ).remove(); | |
5255 | |
5256 if ( next ) { | |
5257 jQuery(next).before( value ); | |
5258 } else { | |
5259 jQuery(parent).append( value ); | |
5260 } | |
5261 }); | |
5262 } else { | |
5263 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ); | |
5264 } | |
5265 }, | |
5266 | |
5267 detach: function( selector ) { | |
5268 return this.remove( selector, true ); | |
5269 }, | |
5270 | |
5271 domManip: function( args, table, callback ) { | |
5272 var results, first, fragment, parent, | |
5273 value = args[0], | |
5274 scripts = []; | |
5275 | |
5276 // We can't cloneNode fragments that contain checked, in WebKit | |
5277 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { | |
5278 return this.each(function() { | |
5279 jQuery(this).domManip( args, table, callback, true ); | |
5280 }); | |
5281 } | |
5282 | |
5283 if ( jQuery.isFunction(value) ) { | |
5284 return this.each(function(i) { | |
5285 var self = jQuery(this); | |
5286 args[0] = value.call(this, i, table ? self.html() : undefined); | |
5287 self.domManip( args, table, callback ); | |
5288 }); | |
5289 } | |
5290 | |
5291 if ( this[0] ) { | |
5292 parent = value && value.parentNode; | |
5293 | |
5294 // If we're in a fragment, just use that instead of building a new one | |
5295 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { | |
5296 results = { fragment: parent }; | |
5297 | |
5298 } else { | |
5299 results = jQuery.buildFragment( args, this, scripts ); | |
5300 } | |
5301 | |
5302 fragment = results.fragment; | |
5303 | |
5304 if ( fragment.childNodes.length === 1 ) { | |
5305 first = fragment = fragment.firstChild; | |
5306 } else { | |
5307 first = fragment.firstChild; | |
5308 } | |
5309 | |
5310 if ( first ) { | |
5311 table = table && jQuery.nodeName( first, "tr" ); | |
5312 | |
5313 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { | |
5314 callback.call( | |
5315 table ? | |
5316 root(this[i], first) : | |
5317 this[i], | |
5318 // Make sure that we do not leak memory by inadvertently discarding | |
5319 // the original fragment (which might have attached data) instead of | |
5320 // using it; in addition, use the original fragment object for the last | |
5321 // item instead of first because it can end up being emptied incorrectly | |
5322 // in certain situations (Bug #8070). | |
5323 // Fragments from the fragment cache must always be cloned and never used | |
5324 // in place. | |
5325 results.cacheable || (l > 1 && i < lastIndex) ? | |
5326 jQuery.clone( fragment, true, true ) : | |
5327 fragment | |
5328 ); | |
5329 } | |
5330 } | |
5331 | |
5332 if ( scripts.length ) { | |
5333 jQuery.each( scripts, evalScript ); | |
5334 } | |
5335 } | |
5336 | |
5337 return this; | |
5338 } | |
5339 }); | |
5340 | |
5341 function root( elem, cur ) { | |
5342 return jQuery.nodeName(elem, "table") ? | |
5343 (elem.getElementsByTagName("tbody")[0] || | |
5344 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : | |
5345 elem; | |
5346 } | |
5347 | |
5348 function cloneCopyEvent( src, dest ) { | |
5349 | |
5350 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { | |
5351 return; | |
5352 } | |
5353 | |
5354 var internalKey = jQuery.expando, | |
5355 oldData = jQuery.data( src ), | |
5356 curData = jQuery.data( dest, oldData ); | |
5357 | |
5358 // Switch to use the internal data object, if it exists, for the next | |
5359 // stage of data copying | |
5360 if ( (oldData = oldData[ internalKey ]) ) { | |
5361 var events = oldData.events; | |
5362 curData = curData[ internalKey ] = jQuery.extend({}, oldData); | |
5363 | |
5364 if ( events ) { | |
5365 delete curData.handle; | |
5366 curData.events = {}; | |
5367 | |
5368 for ( var type in events ) { | |
5369 for ( var i = 0, l = events[ type ].length; i < l; i++ ) { | |
5370 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); | |
5371 } | |
5372 } | |
5373 } | |
5374 } | |
5375 } | |
5376 | |
5377 function cloneFixAttributes(src, dest) { | |
5378 // We do not need to do anything for non-Elements | |
5379 if ( dest.nodeType !== 1 ) { | |
5380 return; | |
5381 } | |
5382 | |
5383 var nodeName = dest.nodeName.toLowerCase(); | |
5384 | |
5385 // clearAttributes removes the attributes, which we don't want, | |
5386 // but also removes the attachEvent events, which we *do* want | |
5387 dest.clearAttributes(); | |
5388 | |
5389 // mergeAttributes, in contrast, only merges back on the | |
5390 // original attributes, not the events | |
5391 dest.mergeAttributes(src); | |
5392 | |
5393 // IE6-8 fail to clone children inside object elements that use | |
5394 // the proprietary classid attribute value (rather than the type | |
5395 // attribute) to identify the type of content to display | |
5396 if ( nodeName === "object" ) { | |
5397 dest.outerHTML = src.outerHTML; | |
5398 | |
5399 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { | |
5400 // IE6-8 fails to persist the checked state of a cloned checkbox | |
5401 // or radio button. Worse, IE6-7 fail to give the cloned element | |
5402 // a checked appearance if the defaultChecked value isn't also set | |
5403 if ( src.checked ) { | |
5404 dest.defaultChecked = dest.checked = src.checked; | |
5405 } | |
5406 | |
5407 // IE6-7 get confused and end up setting the value of a cloned | |
5408 // checkbox/radio button to an empty string instead of "on" | |
5409 if ( dest.value !== src.value ) { | |
5410 dest.value = src.value; | |
5411 } | |
5412 | |
5413 // IE6-8 fails to return the selected option to the default selected | |
5414 // state when cloning options | |
5415 } else if ( nodeName === "option" ) { | |
5416 dest.selected = src.defaultSelected; | |
5417 | |
5418 // IE6-8 fails to set the defaultValue to the correct value when | |
5419 // cloning other types of input fields | |
5420 } else if ( nodeName === "input" || nodeName === "textarea" ) { | |
5421 dest.defaultValue = src.defaultValue; | |
5422 } | |
5423 | |
5424 // Event data gets referenced instead of copied if the expando | |
5425 // gets copied too | |
5426 dest.removeAttribute( jQuery.expando ); | |
5427 } | |
5428 | |
5429 jQuery.buildFragment = function( args, nodes, scripts ) { | |
5430 var fragment, cacheable, cacheresults, | |
5431 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); | |
5432 | |
5433 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document | |
5434 // Cloning options loses the selected state, so don't cache them | |
5435 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment | |
5436 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache | |
5437 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document && | |
5438 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { | |
5439 | |
5440 cacheable = true; | |
5441 cacheresults = jQuery.fragments[ args[0] ]; | |
5442 if ( cacheresults ) { | |
5443 if ( cacheresults !== 1 ) { | |
5444 fragment = cacheresults; | |
5445 } | |
5446 } | |
5447 } | |
5448 | |
5449 if ( !fragment ) { | |
5450 fragment = doc.createDocumentFragment(); | |
5451 jQuery.clean( args, doc, fragment, scripts ); | |
5452 } | |
5453 | |
5454 if ( cacheable ) { | |
5455 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1; | |
5456 } | |
5457 | |
5458 return { fragment: fragment, cacheable: cacheable }; | |
5459 }; | |
5460 | |
5461 jQuery.fragments = {}; | |
5462 | |
5463 jQuery.each({ | |
5464 appendTo: "append", | |
5465 prependTo: "prepend", | |
5466 insertBefore: "before", | |
5467 insertAfter: "after", | |
5468 replaceAll: "replaceWith" | |
5469 }, function( name, original ) { | |
5470 jQuery.fn[ name ] = function( selector ) { | |
5471 var ret = [], | |
5472 insert = jQuery( selector ), | |
5473 parent = this.length === 1 && this[0].parentNode; | |
5474 | |
5475 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { | |
5476 insert[ original ]( this[0] ); | |
5477 return this; | |
5478 | |
5479 } else { | |
5480 for ( var i = 0, l = insert.length; i < l; i++ ) { | |
5481 var elems = (i > 0 ? this.clone(true) : this).get(); | |
5482 jQuery( insert[i] )[ original ]( elems ); | |
5483 ret = ret.concat( elems ); | |
5484 } | |
5485 | |
5486 return this.pushStack( ret, name, insert.selector ); | |
5487 } | |
5488 }; | |
5489 }); | |
5490 | |
5491 function getAll( elem ) { | |
5492 if ( "getElementsByTagName" in elem ) { | |
5493 return elem.getElementsByTagName( "*" ); | |
5494 | |
5495 } else if ( "querySelectorAll" in elem ) { | |
5496 return elem.querySelectorAll( "*" ); | |
5497 | |
5498 } else { | |
5499 return []; | |
5500 } | |
5501 } | |
5502 | |
5503 jQuery.extend({ | |
5504 clone: function( elem, dataAndEvents, deepDataAndEvents ) { | |
5505 var clone = elem.cloneNode(true), | |
5506 srcElements, | |
5507 destElements, | |
5508 i; | |
5509 | |
5510 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && | |
5511 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { | |
5512 // IE copies events bound via attachEvent when using cloneNode. | |
5513 // Calling detachEvent on the clone will also remove the events | |
5514 // from the original. In order to get around this, we use some | |
5515 // proprietary methods to clear the events. Thanks to MooTools | |
5516 // guys for this hotness. | |
5517 | |
5518 cloneFixAttributes( elem, clone ); | |
5519 | |
5520 // Using Sizzle here is crazy slow, so we use getElementsByTagName | |
5521 // instead | |
5522 srcElements = getAll( elem ); | |
5523 destElements = getAll( clone ); | |
5524 | |
5525 // Weird iteration because IE will replace the length property | |
5526 // with an element if you are cloning the body and one of the | |
5527 // elements on the page has a name or id of "length" | |
5528 for ( i = 0; srcElements[i]; ++i ) { | |
5529 cloneFixAttributes( srcElements[i], destElements[i] ); | |
5530 } | |
5531 } | |
5532 | |
5533 // Copy the events from the original to the clone | |
5534 if ( dataAndEvents ) { | |
5535 cloneCopyEvent( elem, clone ); | |
5536 | |
5537 if ( deepDataAndEvents ) { | |
5538 srcElements = getAll( elem ); | |
5539 destElements = getAll( clone ); | |
5540 | |
5541 for ( i = 0; srcElements[i]; ++i ) { | |
5542 cloneCopyEvent( srcElements[i], destElements[i] ); | |
5543 } | |
5544 } | |
5545 } | |
5546 | |
5547 // Return the cloned set | |
5548 return clone; | |
5549 }, | |
5550 clean: function( elems, context, fragment, scripts ) { | |
5551 context = context || document; | |
5552 | |
5553 // !context.createElement fails in IE with an error but returns typeof 'object' | |
5554 if ( typeof context.createElement === "undefined" ) { | |
5555 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; | |
5556 } | |
5557 | |
5558 var ret = []; | |
5559 | |
5560 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
5561 if ( typeof elem === "number" ) { | |
5562 elem += ""; | |
5563 } | |
5564 | |
5565 if ( !elem ) { | |
5566 continue; | |
5567 } | |
5568 | |
5569 // Convert html string into DOM nodes | |
5570 if ( typeof elem === "string" && !rhtml.test( elem ) ) { | |
5571 elem = context.createTextNode( elem ); | |
5572 | |
5573 } else if ( typeof elem === "string" ) { | |
5574 // Fix "XHTML"-style tags in all browsers | |
5575 elem = elem.replace(rxhtmlTag, "<$1></$2>"); | |
5576 | |
5577 // Trim whitespace, otherwise indexOf won't work as expected | |
5578 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), | |
5579 wrap = wrapMap[ tag ] || wrapMap._default, | |
5580 depth = wrap[0], | |
5581 div = context.createElement("div"); | |
5582 | |
5583 // Go to html and back, then peel off extra wrappers | |
5584 div.innerHTML = wrap[1] + elem + wrap[2]; | |
5585 | |
5586 // Move to the right depth | |
5587 while ( depth-- ) { | |
5588 div = div.lastChild; | |
5589 } | |
5590 | |
5591 // Remove IE's autoinserted <tbody> from table fragments | |
5592 if ( !jQuery.support.tbody ) { | |
5593 | |
5594 // String was a <table>, *may* have spurious <tbody> | |
5595 var hasBody = rtbody.test(elem), | |
5596 tbody = tag === "table" && !hasBody ? | |
5597 div.firstChild && div.firstChild.childNodes : | |
5598 | |
5599 // String was a bare <thead> or <tfoot> | |
5600 wrap[1] === "<table>" && !hasBody ? | |
5601 div.childNodes : | |
5602 []; | |
5603 | |
5604 for ( var j = tbody.length - 1; j >= 0 ; --j ) { | |
5605 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { | |
5606 tbody[ j ].parentNode.removeChild( tbody[ j ] ); | |
5607 } | |
5608 } | |
5609 | |
5610 } | |
5611 | |
5612 // IE completely kills leading whitespace when innerHTML is used | |
5613 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { | |
5614 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); | |
5615 } | |
5616 | |
5617 elem = div.childNodes; | |
5618 } | |
5619 | |
5620 if ( elem.nodeType ) { | |
5621 ret.push( elem ); | |
5622 } else { | |
5623 ret = jQuery.merge( ret, elem ); | |
5624 } | |
5625 } | |
5626 | |
5627 if ( fragment ) { | |
5628 for ( i = 0; ret[i]; i++ ) { | |
5629 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { | |
5630 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); | |
5631 | |
5632 } else { | |
5633 if ( ret[i].nodeType === 1 ) { | |
5634 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); | |
5635 } | |
5636 fragment.appendChild( ret[i] ); | |
5637 } | |
5638 } | |
5639 } | |
5640 | |
5641 return ret; | |
5642 }, | |
5643 | |
5644 cleanData: function( elems ) { | |
5645 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special, | |
5646 deleteExpando = jQuery.support.deleteExpando; | |
5647 | |
5648 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
5649 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { | |
5650 continue; | |
5651 } | |
5652 | |
5653 id = elem[ jQuery.expando ]; | |
5654 | |
5655 if ( id ) { | |
5656 data = cache[ id ] && cache[ id ][ internalKey ]; | |
5657 | |
5658 if ( data && data.events ) { | |
5659 for ( var type in data.events ) { | |
5660 if ( special[ type ] ) { | |
5661 jQuery.event.remove( elem, type ); | |
5662 | |
5663 // This is a shortcut to avoid jQuery.event.remove's overhead | |
5664 } else { | |
5665 jQuery.removeEvent( elem, type, data.handle ); | |
5666 } | |
5667 } | |
5668 | |
5669 // Null the DOM reference to avoid IE6/7/8 leak (#7054) | |
5670 if ( data.handle ) { | |
5671 data.handle.elem = null; | |
5672 } | |
5673 } | |
5674 | |
5675 if ( deleteExpando ) { | |
5676 delete elem[ jQuery.expando ]; | |
5677 | |
5678 } else if ( elem.removeAttribute ) { | |
5679 elem.removeAttribute( jQuery.expando ); | |
5680 } | |
5681 | |
5682 delete cache[ id ]; | |
5683 } | |
5684 } | |
5685 } | |
5686 }); | |
5687 | |
5688 function evalScript( i, elem ) { | |
5689 if ( elem.src ) { | |
5690 jQuery.ajax({ | |
5691 url: elem.src, | |
5692 async: false, | |
5693 dataType: "script" | |
5694 }); | |
5695 } else { | |
5696 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); | |
5697 } | |
5698 | |
5699 if ( elem.parentNode ) { | |
5700 elem.parentNode.removeChild( elem ); | |
5701 } | |
5702 } | |
5703 | |
5704 | |
5705 | |
5706 | |
5707 var ralpha = /alpha\([^)]*\)/i, | |
5708 ropacity = /opacity=([^)]*)/, | |
5709 rdashAlpha = /-([a-z])/ig, | |
5710 rupper = /([A-Z])/g, | |
5711 rnumpx = /^-?\d+(?:px)?$/i, | |
5712 rnum = /^-?\d/, | |
5713 | |
5714 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, | |
5715 cssWidth = [ "Left", "Right" ], | |
5716 cssHeight = [ "Top", "Bottom" ], | |
5717 curCSS, | |
5718 | |
5719 getComputedStyle, | |
5720 currentStyle, | |
5721 | |
5722 fcamelCase = function( all, letter ) { | |
5723 return letter.toUpperCase(); | |
5724 }; | |
5725 | |
5726 jQuery.fn.css = function( name, value ) { | |
5727 // Setting 'undefined' is a no-op | |
5728 if ( arguments.length === 2 && value === undefined ) { | |
5729 return this; | |
5730 } | |
5731 | |
5732 return jQuery.access( this, name, value, true, function( elem, name, value ) { | |
5733 return value !== undefined ? | |
5734 jQuery.style( elem, name, value ) : | |
5735 jQuery.css( elem, name ); | |
5736 }); | |
5737 }; | |
5738 | |
5739 jQuery.extend({ | |
5740 // Add in style property hooks for overriding the default | |
5741 // behavior of getting and setting a style property | |
5742 cssHooks: { | |
5743 opacity: { | |
5744 get: function( elem, computed ) { | |
5745 if ( computed ) { | |
5746 // We should always get a number back from opacity | |
5747 var ret = curCSS( elem, "opacity", "opacity" ); | |
5748 return ret === "" ? "1" : ret; | |
5749 | |
5750 } else { | |
5751 return elem.style.opacity; | |
5752 } | |
5753 } | |
5754 } | |
5755 }, | |
5756 | |
5757 // Exclude the following css properties to add px | |
5758 cssNumber: { | |
5759 "zIndex": true, | |
5760 "fontWeight": true, | |
5761 "opacity": true, | |
5762 "zoom": true, | |
5763 "lineHeight": true | |
5764 }, | |
5765 | |
5766 // Add in properties whose names you wish to fix before | |
5767 // setting or getting the value | |
5768 cssProps: { | |
5769 // normalize float css property | |
5770 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" | |
5771 }, | |
5772 | |
5773 // Get and set the style property on a DOM Node | |
5774 style: function( elem, name, value, extra ) { | |
5775 // Don't set styles on text and comment nodes | |
5776 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { | |
5777 return; | |
5778 } | |
5779 | |
5780 // Make sure that we're working with the right name | |
5781 var ret, origName = jQuery.camelCase( name ), | |
5782 style = elem.style, hooks = jQuery.cssHooks[ origName ]; | |
5783 | |
5784 name = jQuery.cssProps[ origName ] || origName; | |
5785 | |
5786 // Check if we're setting a value | |
5787 if ( value !== undefined ) { | |
5788 // Make sure that NaN and null values aren't set. See: #7116 | |
5789 if ( typeof value === "number" && isNaN( value ) || value == null ) { | |
5790 return; | |
5791 } | |
5792 | |
5793 // If a number was passed in, add 'px' to the (except for certain CSS properties) | |
5794 if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) { | |
5795 value += "px"; | |
5796 } | |
5797 | |
5798 // If a hook was provided, use that value, otherwise just set the specified value | |
5799 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { | |
5800 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided | |
5801 // Fixes bug #5509 | |
5802 try { | |
5803 style[ name ] = value; | |
5804 } catch(e) {} | |
5805 } | |
5806 | |
5807 } else { | |
5808 // If a hook was provided get the non-computed value from there | |
5809 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { | |
5810 return ret; | |
5811 } | |
5812 | |
5813 // Otherwise just get the value from the style object | |
5814 return style[ name ]; | |
5815 } | |
5816 }, | |
5817 | |
5818 css: function( elem, name, extra ) { | |
5819 // Make sure that we're working with the right name | |
5820 var ret, origName = jQuery.camelCase( name ), | |
5821 hooks = jQuery.cssHooks[ origName ]; | |
5822 | |
5823 name = jQuery.cssProps[ origName ] || origName; | |
5824 | |
5825 // If a hook was provided get the computed value from there | |
5826 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { | |
5827 return ret; | |
5828 | |
5829 // Otherwise, if a way to get the computed value exists, use that | |
5830 } else if ( curCSS ) { | |
5831 return curCSS( elem, name, origName ); | |
5832 } | |
5833 }, | |
5834 | |
5835 // A method for quickly swapping in/out CSS properties to get correct calculations | |
5836 swap: function( elem, options, callback ) { | |
5837 var old = {}; | |
5838 | |
5839 // Remember the old values, and insert the new ones | |
5840 for ( var name in options ) { | |
5841 old[ name ] = elem.style[ name ]; | |
5842 elem.style[ name ] = options[ name ]; | |
5843 } | |
5844 | |
5845 callback.call( elem ); | |
5846 | |
5847 // Revert the old values | |
5848 for ( name in options ) { | |
5849 elem.style[ name ] = old[ name ]; | |
5850 } | |
5851 }, | |
5852 | |
5853 camelCase: function( string ) { | |
5854 return string.replace( rdashAlpha, fcamelCase ); | |
5855 } | |
5856 }); | |
5857 | |
5858 // DEPRECATED, Use jQuery.css() instead | |
5859 jQuery.curCSS = jQuery.css; | |
5860 | |
5861 jQuery.each(["height", "width"], function( i, name ) { | |
5862 jQuery.cssHooks[ name ] = { | |
5863 get: function( elem, computed, extra ) { | |
5864 var val; | |
5865 | |
5866 if ( computed ) { | |
5867 if ( elem.offsetWidth !== 0 ) { | |
5868 val = getWH( elem, name, extra ); | |
5869 | |
5870 } else { | |
5871 jQuery.swap( elem, cssShow, function() { | |
5872 val = getWH( elem, name, extra ); | |
5873 }); | |
5874 } | |
5875 | |
5876 if ( val <= 0 ) { | |
5877 val = curCSS( elem, name, name ); | |
5878 | |
5879 if ( val === "0px" && currentStyle ) { | |
5880 val = currentStyle( elem, name, name ); | |
5881 } | |
5882 | |
5883 if ( val != null ) { | |
5884 // Should return "auto" instead of 0, use 0 for | |
5885 // temporary backwards-compat | |
5886 return val === "" || val === "auto" ? "0px" : val; | |
5887 } | |
5888 } | |
5889 | |
5890 if ( val < 0 || val == null ) { | |
5891 val = elem.style[ name ]; | |
5892 | |
5893 // Should return "auto" instead of 0, use 0 for | |
5894 // temporary backwards-compat | |
5895 return val === "" || val === "auto" ? "0px" : val; | |
5896 } | |
5897 | |
5898 return typeof val === "string" ? val : val + "px"; | |
5899 } | |
5900 }, | |
5901 | |
5902 set: function( elem, value ) { | |
5903 if ( rnumpx.test( value ) ) { | |
5904 // ignore negative width and height values #1599 | |
5905 value = parseFloat(value); | |
5906 | |
5907 if ( value >= 0 ) { | |
5908 return value + "px"; | |
5909 } | |
5910 | |
5911 } else { | |
5912 return value; | |
5913 } | |
5914 } | |
5915 }; | |
5916 }); | |
5917 | |
5918 if ( !jQuery.support.opacity ) { | |
5919 jQuery.cssHooks.opacity = { | |
5920 get: function( elem, computed ) { | |
5921 // IE uses filters for opacity | |
5922 return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ? | |
5923 (parseFloat(RegExp.$1) / 100) + "" : | |
5924 computed ? "1" : ""; | |
5925 }, | |
5926 | |
5927 set: function( elem, value ) { | |
5928 var style = elem.style; | |
5929 | |
5930 // IE has trouble with opacity if it does not have layout | |
5931 // Force it by setting the zoom level | |
5932 style.zoom = 1; | |
5933 | |
5934 // Set the alpha filter to set the opacity | |
5935 var opacity = jQuery.isNaN(value) ? | |
5936 "" : | |
5937 "alpha(opacity=" + value * 100 + ")", | |
5938 filter = style.filter || ""; | |
5939 | |
5940 style.filter = ralpha.test(filter) ? | |
5941 filter.replace(ralpha, opacity) : | |
5942 style.filter + ' ' + opacity; | |
5943 } | |
5944 }; | |
5945 } | |
5946 | |
5947 if ( document.defaultView && document.defaultView.getComputedStyle ) { | |
5948 getComputedStyle = function( elem, newName, name ) { | |
5949 var ret, defaultView, computedStyle; | |
5950 | |
5951 name = name.replace( rupper, "-$1" ).toLowerCase(); | |
5952 | |
5953 if ( !(defaultView = elem.ownerDocument.defaultView) ) { | |
5954 return undefined; | |
5955 } | |
5956 | |
5957 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) { | |
5958 ret = computedStyle.getPropertyValue( name ); | |
5959 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { | |
5960 ret = jQuery.style( elem, name ); | |
5961 } | |
5962 } | |
5963 | |
5964 return ret; | |
5965 }; | |
5966 } | |
5967 | |
5968 if ( document.documentElement.currentStyle ) { | |
5969 currentStyle = function( elem, name ) { | |
5970 var left, | |
5971 ret = elem.currentStyle && elem.currentStyle[ name ], | |
5972 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ], | |
5973 style = elem.style; | |
5974 | |
5975 // From the awesome hack by Dean Edwards | |
5976 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 | |
5977 | |
5978 // If we're not dealing with a regular pixel number | |
5979 // but a number that has a weird ending, we need to convert it to pixels | |
5980 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { | |
5981 // Remember the original values | |
5982 left = style.left; | |
5983 | |
5984 // Put in the new values to get a computed value out | |
5985 if ( rsLeft ) { | |
5986 elem.runtimeStyle.left = elem.currentStyle.left; | |
5987 } | |
5988 style.left = name === "fontSize" ? "1em" : (ret || 0); | |
5989 ret = style.pixelLeft + "px"; | |
5990 | |
5991 // Revert the changed values | |
5992 style.left = left; | |
5993 if ( rsLeft ) { | |
5994 elem.runtimeStyle.left = rsLeft; | |
5995 } | |
5996 } | |
5997 | |
5998 return ret === "" ? "auto" : ret; | |
5999 }; | |
6000 } | |
6001 | |
6002 curCSS = getComputedStyle || currentStyle; | |
6003 | |
6004 function getWH( elem, name, extra ) { | |
6005 var which = name === "width" ? cssWidth : cssHeight, | |
6006 val = name === "width" ? elem.offsetWidth : elem.offsetHeight; | |
6007 | |
6008 if ( extra === "border" ) { | |
6009 return val; | |
6010 } | |
6011 | |
6012 jQuery.each( which, function() { | |
6013 if ( !extra ) { | |
6014 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0; | |
6015 } | |
6016 | |
6017 if ( extra === "margin" ) { | |
6018 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0; | |
6019 | |
6020 } else { | |
6021 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0; | |
6022 } | |
6023 }); | |
6024 | |
6025 return val; | |
6026 } | |
6027 | |
6028 if ( jQuery.expr && jQuery.expr.filters ) { | |
6029 jQuery.expr.filters.hidden = function( elem ) { | |
6030 var width = elem.offsetWidth, | |
6031 height = elem.offsetHeight; | |
6032 | |
6033 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none"); | |
6034 }; | |
6035 | |
6036 jQuery.expr.filters.visible = function( elem ) { | |
6037 return !jQuery.expr.filters.hidden( elem ); | |
6038 }; | |
6039 } | |
6040 | |
6041 | |
6042 | |
6043 | |
6044 var r20 = /%20/g, | |
6045 rbracket = /\[\]$/, | |
6046 rCRLF = /\r?\n/g, | |
6047 rhash = /#.*$/, | |
6048 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL | |
6049 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, | |
6050 // #7653, #8125, #8152: local protocol detection | |
6051 rlocalProtocol = /(?:^file|^widget|\-extension):$/, | |
6052 rnoContent = /^(?:GET|HEAD)$/, | |
6053 rprotocol = /^\/\//, | |
6054 rquery = /\?/, | |
6055 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, | |
6056 rselectTextarea = /^(?:select|textarea)/i, | |
6057 rspacesAjax = /\s+/, | |
6058 rts = /([?&])_=[^&]*/, | |
6059 rucHeaders = /(^|\-)([a-z])/g, | |
6060 rucHeadersFunc = function( _, $1, $2 ) { | |
6061 return $1 + $2.toUpperCase(); | |
6062 }, | |
6063 rurl = /^([\w\+\.\-]+:)\/\/([^\/?#:]*)(?::(\d+))?/, | |
6064 | |
6065 // Keep a copy of the old load method | |
6066 _load = jQuery.fn.load, | |
6067 | |
6068 /* Prefilters | |
6069 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) | |
6070 * 2) These are called: | |
6071 * - BEFORE asking for a transport | |
6072 * - AFTER param serialization (s.data is a string if s.processData is true) | |
6073 * 3) key is the dataType | |
6074 * 4) the catchall symbol "*" can be used | |
6075 * 5) execution will start with transport dataType and THEN continue down to "*" if needed | |
6076 */ | |
6077 prefilters = {}, | |
6078 | |
6079 /* Transports bindings | |
6080 * 1) key is the dataType | |
6081 * 2) the catchall symbol "*" can be used | |
6082 * 3) selection will start with transport dataType and THEN go to "*" if needed | |
6083 */ | |
6084 transports = {}, | |
6085 | |
6086 // Document location | |
6087 ajaxLocation, | |
6088 | |
6089 // Document location segments | |
6090 ajaxLocParts; | |
6091 | |
6092 // #8138, IE may throw an exception when accessing | |
6093 // a field from document.location if document.domain has been set | |
6094 try { | |
6095 ajaxLocation = document.location.href; | |
6096 } catch( e ) { | |
6097 // Use the href attribute of an A element | |
6098 // since IE will modify it given document.location | |
6099 ajaxLocation = document.createElement( "a" ); | |
6100 ajaxLocation.href = ""; | |
6101 ajaxLocation = ajaxLocation.href; | |
6102 } | |
6103 | |
6104 // Segment location into parts | |
6105 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ); | |
6106 | |
6107 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport | |
6108 function addToPrefiltersOrTransports( structure ) { | |
6109 | |
6110 // dataTypeExpression is optional and defaults to "*" | |
6111 return function( dataTypeExpression, func ) { | |
6112 | |
6113 if ( typeof dataTypeExpression !== "string" ) { | |
6114 func = dataTypeExpression; | |
6115 dataTypeExpression = "*"; | |
6116 } | |
6117 | |
6118 if ( jQuery.isFunction( func ) ) { | |
6119 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), | |
6120 i = 0, | |
6121 length = dataTypes.length, | |
6122 dataType, | |
6123 list, | |
6124 placeBefore; | |
6125 | |
6126 // For each dataType in the dataTypeExpression | |
6127 for(; i < length; i++ ) { | |
6128 dataType = dataTypes[ i ]; | |
6129 // We control if we're asked to add before | |
6130 // any existing element | |
6131 placeBefore = /^\+/.test( dataType ); | |
6132 if ( placeBefore ) { | |
6133 dataType = dataType.substr( 1 ) || "*"; | |
6134 } | |
6135 list = structure[ dataType ] = structure[ dataType ] || []; | |
6136 // then we add to the structure accordingly | |
6137 list[ placeBefore ? "unshift" : "push" ]( func ); | |
6138 } | |
6139 } | |
6140 }; | |
6141 } | |
6142 | |
6143 //Base inspection function for prefilters and transports | |
6144 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, | |
6145 dataType /* internal */, inspected /* internal */ ) { | |
6146 | |
6147 dataType = dataType || options.dataTypes[ 0 ]; | |
6148 inspected = inspected || {}; | |
6149 | |
6150 inspected[ dataType ] = true; | |
6151 | |
6152 var list = structure[ dataType ], | |
6153 i = 0, | |
6154 length = list ? list.length : 0, | |
6155 executeOnly = ( structure === prefilters ), | |
6156 selection; | |
6157 | |
6158 for(; i < length && ( executeOnly || !selection ); i++ ) { | |
6159 selection = list[ i ]( options, originalOptions, jqXHR ); | |
6160 // If we got redirected to another dataType | |
6161 // we try there if executing only and not done already | |
6162 if ( typeof selection === "string" ) { | |
6163 if ( !executeOnly || inspected[ selection ] ) { | |
6164 selection = undefined; | |
6165 } else { | |
6166 options.dataTypes.unshift( selection ); | |
6167 selection = inspectPrefiltersOrTransports( | |
6168 structure, options, originalOptions, jqXHR, selection, inspected ); | |
6169 } | |
6170 } | |
6171 } | |
6172 // If we're only executing or nothing was selected | |
6173 // we try the catchall dataType if not done already | |
6174 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { | |
6175 selection = inspectPrefiltersOrTransports( | |
6176 structure, options, originalOptions, jqXHR, "*", inspected ); | |
6177 } | |
6178 // unnecessary when only executing (prefilters) | |
6179 // but it'll be ignored by the caller in that case | |
6180 return selection; | |
6181 } | |
6182 | |
6183 jQuery.fn.extend({ | |
6184 load: function( url, params, callback ) { | |
6185 if ( typeof url !== "string" && _load ) { | |
6186 return _load.apply( this, arguments ); | |
6187 | |
6188 // Don't do a request if no elements are being requested | |
6189 } else if ( !this.length ) { | |
6190 return this; | |
6191 } | |
6192 | |
6193 var off = url.indexOf( " " ); | |
6194 if ( off >= 0 ) { | |
6195 var selector = url.slice( off, url.length ); | |
6196 url = url.slice( 0, off ); | |
6197 } | |
6198 | |
6199 // Default to a GET request | |
6200 var type = "GET"; | |
6201 | |
6202 // If the second parameter was provided | |
6203 if ( params ) { | |
6204 // If it's a function | |
6205 if ( jQuery.isFunction( params ) ) { | |
6206 // We assume that it's the callback | |
6207 callback = params; | |
6208 params = undefined; | |
6209 | |
6210 // Otherwise, build a param string | |
6211 } else if ( typeof params === "object" ) { | |
6212 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); | |
6213 type = "POST"; | |
6214 } | |
6215 } | |
6216 | |
6217 var self = this; | |
6218 | |
6219 // Request the remote document | |
6220 jQuery.ajax({ | |
6221 url: url, | |
6222 type: type, | |
6223 dataType: "html", | |
6224 data: params, | |
6225 // Complete callback (responseText is used internally) | |
6226 complete: function( jqXHR, status, responseText ) { | |
6227 // Store the response as specified by the jqXHR object | |
6228 responseText = jqXHR.responseText; | |
6229 // If successful, inject the HTML into all the matched elements | |
6230 if ( jqXHR.isResolved() ) { | |
6231 // #4825: Get the actual response in case | |
6232 // a dataFilter is present in ajaxSettings | |
6233 jqXHR.done(function( r ) { | |
6234 responseText = r; | |
6235 }); | |
6236 // See if a selector was specified | |
6237 self.html( selector ? | |
6238 // Create a dummy div to hold the results | |
6239 jQuery("<div>") | |
6240 // inject the contents of the document in, removing the scripts | |
6241 // to avoid any 'Permission Denied' errors in IE | |
6242 .append(responseText.replace(rscript, "")) | |
6243 | |
6244 // Locate the specified elements | |
6245 .find(selector) : | |
6246 | |
6247 // If not, just inject the full result | |
6248 responseText ); | |
6249 } | |
6250 | |
6251 if ( callback ) { | |
6252 self.each( callback, [ responseText, status, jqXHR ] ); | |
6253 } | |
6254 } | |
6255 }); | |
6256 | |
6257 return this; | |
6258 }, | |
6259 | |
6260 serialize: function() { | |
6261 return jQuery.param( this.serializeArray() ); | |
6262 }, | |
6263 | |
6264 serializeArray: function() { | |
6265 return this.map(function(){ | |
6266 return this.elements ? jQuery.makeArray( this.elements ) : this; | |
6267 }) | |
6268 .filter(function(){ | |
6269 return this.name && !this.disabled && | |
6270 ( this.checked || rselectTextarea.test( this.nodeName ) || | |
6271 rinput.test( this.type ) ); | |
6272 }) | |
6273 .map(function( i, elem ){ | |
6274 var val = jQuery( this ).val(); | |
6275 | |
6276 return val == null ? | |
6277 null : | |
6278 jQuery.isArray( val ) ? | |
6279 jQuery.map( val, function( val, i ){ | |
6280 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
6281 }) : | |
6282 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
6283 }).get(); | |
6284 } | |
6285 }); | |
6286 | |
6287 // Attach a bunch of functions for handling common AJAX events | |
6288 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ | |
6289 jQuery.fn[ o ] = function( f ){ | |
6290 return this.bind( o, f ); | |
6291 }; | |
6292 } ); | |
6293 | |
6294 jQuery.each( [ "get", "post" ], function( i, method ) { | |
6295 jQuery[ method ] = function( url, data, callback, type ) { | |
6296 // shift arguments if data argument was omitted | |
6297 if ( jQuery.isFunction( data ) ) { | |
6298 type = type || callback; | |
6299 callback = data; | |
6300 data = undefined; | |
6301 } | |
6302 | |
6303 return jQuery.ajax({ | |
6304 type: method, | |
6305 url: url, | |
6306 data: data, | |
6307 success: callback, | |
6308 dataType: type | |
6309 }); | |
6310 }; | |
6311 } ); | |
6312 | |
6313 jQuery.extend({ | |
6314 | |
6315 getScript: function( url, callback ) { | |
6316 return jQuery.get( url, undefined, callback, "script" ); | |
6317 }, | |
6318 | |
6319 getJSON: function( url, data, callback ) { | |
6320 return jQuery.get( url, data, callback, "json" ); | |
6321 }, | |
6322 | |
6323 // Creates a full fledged settings object into target | |
6324 // with both ajaxSettings and settings fields. | |
6325 // If target is omitted, writes into ajaxSettings. | |
6326 ajaxSetup: function ( target, settings ) { | |
6327 if ( !settings ) { | |
6328 // Only one parameter, we extend ajaxSettings | |
6329 settings = target; | |
6330 target = jQuery.extend( true, jQuery.ajaxSettings, settings ); | |
6331 } else { | |
6332 // target was provided, we extend into it | |
6333 jQuery.extend( true, target, jQuery.ajaxSettings, settings ); | |
6334 } | |
6335 // Flatten fields we don't want deep extended | |
6336 for( var field in { context: 1, url: 1 } ) { | |
6337 if ( field in settings ) { | |
6338 target[ field ] = settings[ field ]; | |
6339 } else if( field in jQuery.ajaxSettings ) { | |
6340 target[ field ] = jQuery.ajaxSettings[ field ]; | |
6341 } | |
6342 } | |
6343 return target; | |
6344 }, | |
6345 | |
6346 ajaxSettings: { | |
6347 url: ajaxLocation, | |
6348 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), | |
6349 global: true, | |
6350 type: "GET", | |
6351 contentType: "application/x-www-form-urlencoded", | |
6352 processData: true, | |
6353 async: true, | |
6354 /* | |
6355 timeout: 0, | |
6356 data: null, | |
6357 dataType: null, | |
6358 username: null, | |
6359 password: null, | |
6360 cache: null, | |
6361 traditional: false, | |
6362 headers: {}, | |
6363 crossDomain: null, | |
6364 */ | |
6365 | |
6366 accepts: { | |
6367 xml: "application/xml, text/xml", | |
6368 html: "text/html", | |
6369 text: "text/plain", | |
6370 json: "application/json, text/javascript", | |
6371 "*": "*/*" | |
6372 }, | |
6373 | |
6374 contents: { | |
6375 xml: /xml/, | |
6376 html: /html/, | |
6377 json: /json/ | |
6378 }, | |
6379 | |
6380 responseFields: { | |
6381 xml: "responseXML", | |
6382 text: "responseText" | |
6383 }, | |
6384 | |
6385 // List of data converters | |
6386 // 1) key format is "source_type destination_type" (a single space in-between) | |
6387 // 2) the catchall symbol "*" can be used for source_type | |
6388 converters: { | |
6389 | |
6390 // Convert anything to text | |
6391 "* text": window.String, | |
6392 | |
6393 // Text to html (true = no transformation) | |
6394 "text html": true, | |
6395 | |
6396 // Evaluate text as a json expression | |
6397 "text json": jQuery.parseJSON, | |
6398 | |
6399 // Parse text as xml | |
6400 "text xml": jQuery.parseXML | |
6401 } | |
6402 }, | |
6403 | |
6404 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), | |
6405 ajaxTransport: addToPrefiltersOrTransports( transports ), | |
6406 | |
6407 // Main method | |
6408 ajax: function( url, options ) { | |
6409 | |
6410 // If url is an object, simulate pre-1.5 signature | |
6411 if ( typeof url === "object" ) { | |
6412 options = url; | |
6413 url = undefined; | |
6414 } | |
6415 | |
6416 // Force options to be an object | |
6417 options = options || {}; | |
6418 | |
6419 var // Create the final options object | |
6420 s = jQuery.ajaxSetup( {}, options ), | |
6421 // Callbacks context | |
6422 callbackContext = s.context || s, | |
6423 // Context for global events | |
6424 // It's the callbackContext if one was provided in the options | |
6425 // and if it's a DOM node or a jQuery collection | |
6426 globalEventContext = callbackContext !== s && | |
6427 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? | |
6428 jQuery( callbackContext ) : jQuery.event, | |
6429 // Deferreds | |
6430 deferred = jQuery.Deferred(), | |
6431 completeDeferred = jQuery._Deferred(), | |
6432 // Status-dependent callbacks | |
6433 statusCode = s.statusCode || {}, | |
6434 // ifModified key | |
6435 ifModifiedKey, | |
6436 // Headers (they are sent all at once) | |
6437 requestHeaders = {}, | |
6438 // Response headers | |
6439 responseHeadersString, | |
6440 responseHeaders, | |
6441 // transport | |
6442 transport, | |
6443 // timeout handle | |
6444 timeoutTimer, | |
6445 // Cross-domain detection vars | |
6446 parts, | |
6447 // The jqXHR state | |
6448 state = 0, | |
6449 // To know if global events are to be dispatched | |
6450 fireGlobals, | |
6451 // Loop variable | |
6452 i, | |
6453 // Fake xhr | |
6454 jqXHR = { | |
6455 | |
6456 readyState: 0, | |
6457 | |
6458 // Caches the header | |
6459 setRequestHeader: function( name, value ) { | |
6460 if ( !state ) { | |
6461 requestHeaders[ name.toLowerCase().replace( rucHeaders, rucHeadersFunc ) ] = value; | |
6462 } | |
6463 return this; | |
6464 }, | |
6465 | |
6466 // Raw string | |
6467 getAllResponseHeaders: function() { | |
6468 return state === 2 ? responseHeadersString : null; | |
6469 }, | |
6470 | |
6471 // Builds headers hashtable if needed | |
6472 getResponseHeader: function( key ) { | |
6473 var match; | |
6474 if ( state === 2 ) { | |
6475 if ( !responseHeaders ) { | |
6476 responseHeaders = {}; | |
6477 while( ( match = rheaders.exec( responseHeadersString ) ) ) { | |
6478 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; | |
6479 } | |
6480 } | |
6481 match = responseHeaders[ key.toLowerCase() ]; | |
6482 } | |
6483 return match === undefined ? null : match; | |
6484 }, | |
6485 | |
6486 // Overrides response content-type header | |
6487 overrideMimeType: function( type ) { | |
6488 if ( !state ) { | |
6489 s.mimeType = type; | |
6490 } | |
6491 return this; | |
6492 }, | |
6493 | |
6494 // Cancel the request | |
6495 abort: function( statusText ) { | |
6496 statusText = statusText || "abort"; | |
6497 if ( transport ) { | |
6498 transport.abort( statusText ); | |
6499 } | |
6500 done( 0, statusText ); | |
6501 return this; | |
6502 } | |
6503 }; | |
6504 | |
6505 // Callback for when everything is done | |
6506 // It is defined here because jslint complains if it is declared | |
6507 // at the end of the function (which would be more logical and readable) | |
6508 function done( status, statusText, responses, headers ) { | |
6509 | |
6510 // Called once | |
6511 if ( state === 2 ) { | |
6512 return; | |
6513 } | |
6514 | |
6515 // State is "done" now | |
6516 state = 2; | |
6517 | |
6518 // Clear timeout if it exists | |
6519 if ( timeoutTimer ) { | |
6520 clearTimeout( timeoutTimer ); | |
6521 } | |
6522 | |
6523 // Dereference transport for early garbage collection | |
6524 // (no matter how long the jqXHR object will be used) | |
6525 transport = undefined; | |
6526 | |
6527 // Cache response headers | |
6528 responseHeadersString = headers || ""; | |
6529 | |
6530 // Set readyState | |
6531 jqXHR.readyState = status ? 4 : 0; | |
6532 | |
6533 var isSuccess, | |
6534 success, | |
6535 error, | |
6536 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, | |
6537 lastModified, | |
6538 etag; | |
6539 | |
6540 // If successful, handle type chaining | |
6541 if ( status >= 200 && status < 300 || status === 304 ) { | |
6542 | |
6543 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. | |
6544 if ( s.ifModified ) { | |
6545 | |
6546 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { | |
6547 jQuery.lastModified[ ifModifiedKey ] = lastModified; | |
6548 } | |
6549 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { | |
6550 jQuery.etag[ ifModifiedKey ] = etag; | |
6551 } | |
6552 } | |
6553 | |
6554 // If not modified | |
6555 if ( status === 304 ) { | |
6556 | |
6557 statusText = "notmodified"; | |
6558 isSuccess = true; | |
6559 | |
6560 // If we have data | |
6561 } else { | |
6562 | |
6563 try { | |
6564 success = ajaxConvert( s, response ); | |
6565 statusText = "success"; | |
6566 isSuccess = true; | |
6567 } catch(e) { | |
6568 // We have a parsererror | |
6569 statusText = "parsererror"; | |
6570 error = e; | |
6571 } | |
6572 } | |
6573 } else { | |
6574 // We extract error from statusText | |
6575 // then normalize statusText and status for non-aborts | |
6576 error = statusText; | |
6577 if( !statusText || status ) { | |
6578 statusText = "error"; | |
6579 if ( status < 0 ) { | |
6580 status = 0; | |
6581 } | |
6582 } | |
6583 } | |
6584 | |
6585 // Set data for the fake xhr object | |
6586 jqXHR.status = status; | |
6587 jqXHR.statusText = statusText; | |
6588 | |
6589 // Success/Error | |
6590 if ( isSuccess ) { | |
6591 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); | |
6592 } else { | |
6593 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); | |
6594 } | |
6595 | |
6596 // Status-dependent callbacks | |
6597 jqXHR.statusCode( statusCode ); | |
6598 statusCode = undefined; | |
6599 | |
6600 if ( fireGlobals ) { | |
6601 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), | |
6602 [ jqXHR, s, isSuccess ? success : error ] ); | |
6603 } | |
6604 | |
6605 // Complete | |
6606 completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] ); | |
6607 | |
6608 if ( fireGlobals ) { | |
6609 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] ); | |
6610 // Handle the global AJAX counter | |
6611 if ( !( --jQuery.active ) ) { | |
6612 jQuery.event.trigger( "ajaxStop" ); | |
6613 } | |
6614 } | |
6615 } | |
6616 | |
6617 // Attach deferreds | |
6618 deferred.promise( jqXHR ); | |
6619 jqXHR.success = jqXHR.done; | |
6620 jqXHR.error = jqXHR.fail; | |
6621 jqXHR.complete = completeDeferred.done; | |
6622 | |
6623 // Status-dependent callbacks | |
6624 jqXHR.statusCode = function( map ) { | |
6625 if ( map ) { | |
6626 var tmp; | |
6627 if ( state < 2 ) { | |
6628 for( tmp in map ) { | |
6629 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; | |
6630 } | |
6631 } else { | |
6632 tmp = map[ jqXHR.status ]; | |
6633 jqXHR.then( tmp, tmp ); | |
6634 } | |
6635 } | |
6636 return this; | |
6637 }; | |
6638 | |
6639 // Remove hash character (#7531: and string promotion) | |
6640 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) | |
6641 // We also use the url parameter if available | |
6642 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); | |
6643 | |
6644 // Extract dataTypes list | |
6645 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); | |
6646 | |
6647 // Determine if a cross-domain request is in order | |
6648 if ( !s.crossDomain ) { | |
6649 parts = rurl.exec( s.url.toLowerCase() ); | |
6650 s.crossDomain = !!( parts && | |
6651 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || | |
6652 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != | |
6653 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) | |
6654 ); | |
6655 } | |
6656 | |
6657 // Convert data if not already a string | |
6658 if ( s.data && s.processData && typeof s.data !== "string" ) { | |
6659 s.data = jQuery.param( s.data, s.traditional ); | |
6660 } | |
6661 | |
6662 // Apply prefilters | |
6663 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); | |
6664 | |
6665 // If request was aborted inside a prefiler, stop there | |
6666 if ( state === 2 ) { | |
6667 return false; | |
6668 } | |
6669 | |
6670 // We can fire global events as of now if asked to | |
6671 fireGlobals = s.global; | |
6672 | |
6673 // Uppercase the type | |
6674 s.type = s.type.toUpperCase(); | |
6675 | |
6676 // Determine if request has content | |
6677 s.hasContent = !rnoContent.test( s.type ); | |
6678 | |
6679 // Watch for a new set of requests | |
6680 if ( fireGlobals && jQuery.active++ === 0 ) { | |
6681 jQuery.event.trigger( "ajaxStart" ); | |
6682 } | |
6683 | |
6684 // More options handling for requests with no content | |
6685 if ( !s.hasContent ) { | |
6686 | |
6687 // If data is available, append data to url | |
6688 if ( s.data ) { | |
6689 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; | |
6690 } | |
6691 | |
6692 // Get ifModifiedKey before adding the anti-cache parameter | |
6693 ifModifiedKey = s.url; | |
6694 | |
6695 // Add anti-cache in url if needed | |
6696 if ( s.cache === false ) { | |
6697 | |
6698 var ts = jQuery.now(), | |
6699 // try replacing _= if it is there | |
6700 ret = s.url.replace( rts, "$1_=" + ts ); | |
6701 | |
6702 // if nothing was replaced, add timestamp to the end | |
6703 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); | |
6704 } | |
6705 } | |
6706 | |
6707 // Set the correct header, if data is being sent | |
6708 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { | |
6709 requestHeaders[ "Content-Type" ] = s.contentType; | |
6710 } | |
6711 | |
6712 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. | |
6713 if ( s.ifModified ) { | |
6714 ifModifiedKey = ifModifiedKey || s.url; | |
6715 if ( jQuery.lastModified[ ifModifiedKey ] ) { | |
6716 requestHeaders[ "If-Modified-Since" ] = jQuery.lastModified[ ifModifiedKey ]; | |
6717 } | |
6718 if ( jQuery.etag[ ifModifiedKey ] ) { | |
6719 requestHeaders[ "If-None-Match" ] = jQuery.etag[ ifModifiedKey ]; | |
6720 } | |
6721 } | |
6722 | |
6723 // Set the Accepts header for the server, depending on the dataType | |
6724 requestHeaders.Accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? | |
6725 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : | |
6726 s.accepts[ "*" ]; | |
6727 | |
6728 // Check for headers option | |
6729 for ( i in s.headers ) { | |
6730 jqXHR.setRequestHeader( i, s.headers[ i ] ); | |
6731 } | |
6732 | |
6733 // Allow custom headers/mimetypes and early abort | |
6734 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { | |
6735 // Abort if not done already | |
6736 jqXHR.abort(); | |
6737 return false; | |
6738 | |
6739 } | |
6740 | |
6741 // Install callbacks on deferreds | |
6742 for ( i in { success: 1, error: 1, complete: 1 } ) { | |
6743 jqXHR[ i ]( s[ i ] ); | |
6744 } | |
6745 | |
6746 // Get transport | |
6747 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); | |
6748 | |
6749 // If no transport, we auto-abort | |
6750 if ( !transport ) { | |
6751 done( -1, "No Transport" ); | |
6752 } else { | |
6753 jqXHR.readyState = 1; | |
6754 // Send global event | |
6755 if ( fireGlobals ) { | |
6756 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); | |
6757 } | |
6758 // Timeout | |
6759 if ( s.async && s.timeout > 0 ) { | |
6760 timeoutTimer = setTimeout( function(){ | |
6761 jqXHR.abort( "timeout" ); | |
6762 }, s.timeout ); | |
6763 } | |
6764 | |
6765 try { | |
6766 state = 1; | |
6767 transport.send( requestHeaders, done ); | |
6768 } catch (e) { | |
6769 // Propagate exception as error if not done | |
6770 if ( status < 2 ) { | |
6771 done( -1, e ); | |
6772 // Simply rethrow otherwise | |
6773 } else { | |
6774 jQuery.error( e ); | |
6775 } | |
6776 } | |
6777 } | |
6778 | |
6779 return jqXHR; | |
6780 }, | |
6781 | |
6782 // Serialize an array of form elements or a set of | |
6783 // key/values into a query string | |
6784 param: function( a, traditional ) { | |
6785 var s = [], | |
6786 add = function( key, value ) { | |
6787 // If value is a function, invoke it and return its value | |
6788 value = jQuery.isFunction( value ) ? value() : value; | |
6789 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); | |
6790 }; | |
6791 | |
6792 // Set traditional to true for jQuery <= 1.3.2 behavior. | |
6793 if ( traditional === undefined ) { | |
6794 traditional = jQuery.ajaxSettings.traditional; | |
6795 } | |
6796 | |
6797 // If an array was passed in, assume that it is an array of form elements. | |
6798 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { | |
6799 // Serialize the form elements | |
6800 jQuery.each( a, function() { | |
6801 add( this.name, this.value ); | |
6802 } ); | |
6803 | |
6804 } else { | |
6805 // If traditional, encode the "old" way (the way 1.3.2 or older | |
6806 // did it), otherwise encode params recursively. | |
6807 for ( var prefix in a ) { | |
6808 buildParams( prefix, a[ prefix ], traditional, add ); | |
6809 } | |
6810 } | |
6811 | |
6812 // Return the resulting serialization | |
6813 return s.join( "&" ).replace( r20, "+" ); | |
6814 } | |
6815 }); | |
6816 | |
6817 function buildParams( prefix, obj, traditional, add ) { | |
6818 if ( jQuery.isArray( obj ) && obj.length ) { | |
6819 // Serialize array item. | |
6820 jQuery.each( obj, function( i, v ) { | |
6821 if ( traditional || rbracket.test( prefix ) ) { | |
6822 // Treat each array item as a scalar. | |
6823 add( prefix, v ); | |
6824 | |
6825 } else { | |
6826 // If array item is non-scalar (array or object), encode its | |
6827 // numeric index to resolve deserialization ambiguity issues. | |
6828 // Note that rack (as of 1.0.0) can't currently deserialize | |
6829 // nested arrays properly, and attempting to do so may cause | |
6830 // a server error. Possible fixes are to modify rack's | |
6831 // deserialization algorithm or to provide an option or flag | |
6832 // to force array serialization to be shallow. | |
6833 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add ); | |
6834 } | |
6835 }); | |
6836 | |
6837 } else if ( !traditional && obj != null && typeof obj === "object" ) { | |
6838 // If we see an array here, it is empty and should be treated as an empty | |
6839 // object | |
6840 if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) { | |
6841 add( prefix, "" ); | |
6842 | |
6843 // Serialize object item. | |
6844 } else { | |
6845 for ( var name in obj ) { | |
6846 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); | |
6847 } | |
6848 } | |
6849 | |
6850 } else { | |
6851 // Serialize scalar item. | |
6852 add( prefix, obj ); | |
6853 } | |
6854 } | |
6855 | |
6856 // This is still on the jQuery object... for now | |
6857 // Want to move this to jQuery.ajax some day | |
6858 jQuery.extend({ | |
6859 | |
6860 // Counter for holding the number of active queries | |
6861 active: 0, | |
6862 | |
6863 // Last-Modified header cache for next request | |
6864 lastModified: {}, | |
6865 etag: {} | |
6866 | |
6867 }); | |
6868 | |
6869 /* Handles responses to an ajax request: | |
6870 * - sets all responseXXX fields accordingly | |
6871 * - finds the right dataType (mediates between content-type and expected dataType) | |
6872 * - returns the corresponding response | |
6873 */ | |
6874 function ajaxHandleResponses( s, jqXHR, responses ) { | |
6875 | |
6876 var contents = s.contents, | |
6877 dataTypes = s.dataTypes, | |
6878 responseFields = s.responseFields, | |
6879 ct, | |
6880 type, | |
6881 finalDataType, | |
6882 firstDataType; | |
6883 | |
6884 // Fill responseXXX fields | |
6885 for( type in responseFields ) { | |
6886 if ( type in responses ) { | |
6887 jqXHR[ responseFields[type] ] = responses[ type ]; | |
6888 } | |
6889 } | |
6890 | |
6891 // Remove auto dataType and get content-type in the process | |
6892 while( dataTypes[ 0 ] === "*" ) { | |
6893 dataTypes.shift(); | |
6894 if ( ct === undefined ) { | |
6895 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); | |
6896 } | |
6897 } | |
6898 | |
6899 // Check if we're dealing with a known content-type | |
6900 if ( ct ) { | |
6901 for ( type in contents ) { | |
6902 if ( contents[ type ] && contents[ type ].test( ct ) ) { | |
6903 dataTypes.unshift( type ); | |
6904 break; | |
6905 } | |
6906 } | |
6907 } | |
6908 | |
6909 // Check to see if we have a response for the expected dataType | |
6910 if ( dataTypes[ 0 ] in responses ) { | |
6911 finalDataType = dataTypes[ 0 ]; | |
6912 } else { | |
6913 // Try convertible dataTypes | |
6914 for ( type in responses ) { | |
6915 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { | |
6916 finalDataType = type; | |
6917 break; | |
6918 } | |
6919 if ( !firstDataType ) { | |
6920 firstDataType = type; | |
6921 } | |
6922 } | |
6923 // Or just use first one | |
6924 finalDataType = finalDataType || firstDataType; | |
6925 } | |
6926 | |
6927 // If we found a dataType | |
6928 // We add the dataType to the list if needed | |
6929 // and return the corresponding response | |
6930 if ( finalDataType ) { | |
6931 if ( finalDataType !== dataTypes[ 0 ] ) { | |
6932 dataTypes.unshift( finalDataType ); | |
6933 } | |
6934 return responses[ finalDataType ]; | |
6935 } | |
6936 } | |
6937 | |
6938 // Chain conversions given the request and the original response | |
6939 function ajaxConvert( s, response ) { | |
6940 | |
6941 // Apply the dataFilter if provided | |
6942 if ( s.dataFilter ) { | |
6943 response = s.dataFilter( response, s.dataType ); | |
6944 } | |
6945 | |
6946 var dataTypes = s.dataTypes, | |
6947 converters = {}, | |
6948 i, | |
6949 key, | |
6950 length = dataTypes.length, | |
6951 tmp, | |
6952 // Current and previous dataTypes | |
6953 current = dataTypes[ 0 ], | |
6954 prev, | |
6955 // Conversion expression | |
6956 conversion, | |
6957 // Conversion function | |
6958 conv, | |
6959 // Conversion functions (transitive conversion) | |
6960 conv1, | |
6961 conv2; | |
6962 | |
6963 // For each dataType in the chain | |
6964 for( i = 1; i < length; i++ ) { | |
6965 | |
6966 // Create converters map | |
6967 // with lowercased keys | |
6968 if ( i === 1 ) { | |
6969 for( key in s.converters ) { | |
6970 if( typeof key === "string" ) { | |
6971 converters[ key.toLowerCase() ] = s.converters[ key ]; | |
6972 } | |
6973 } | |
6974 } | |
6975 | |
6976 // Get the dataTypes | |
6977 prev = current; | |
6978 current = dataTypes[ i ]; | |
6979 | |
6980 // If current is auto dataType, update it to prev | |
6981 if( current === "*" ) { | |
6982 current = prev; | |
6983 // If no auto and dataTypes are actually different | |
6984 } else if ( prev !== "*" && prev !== current ) { | |
6985 | |
6986 // Get the converter | |
6987 conversion = prev + " " + current; | |
6988 conv = converters[ conversion ] || converters[ "* " + current ]; | |
6989 | |
6990 // If there is no direct converter, search transitively | |
6991 if ( !conv ) { | |
6992 conv2 = undefined; | |
6993 for( conv1 in converters ) { | |
6994 tmp = conv1.split( " " ); | |
6995 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { | |
6996 conv2 = converters[ tmp[1] + " " + current ]; | |
6997 if ( conv2 ) { | |
6998 conv1 = converters[ conv1 ]; | |
6999 if ( conv1 === true ) { | |
7000 conv = conv2; | |
7001 } else if ( conv2 === true ) { | |
7002 conv = conv1; | |
7003 } | |
7004 break; | |
7005 } | |
7006 } | |
7007 } | |
7008 } | |
7009 // If we found no converter, dispatch an error | |
7010 if ( !( conv || conv2 ) ) { | |
7011 jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); | |
7012 } | |
7013 // If found converter is not an equivalence | |
7014 if ( conv !== true ) { | |
7015 // Convert with 1 or 2 converters accordingly | |
7016 response = conv ? conv( response ) : conv2( conv1(response) ); | |
7017 } | |
7018 } | |
7019 } | |
7020 return response; | |
7021 } | |
7022 | |
7023 | |
7024 | |
7025 | |
7026 var jsc = jQuery.now(), | |
7027 jsre = /(\=)\?(&|$)|()\?\?()/i; | |
7028 | |
7029 // Default jsonp settings | |
7030 jQuery.ajaxSetup({ | |
7031 jsonp: "callback", | |
7032 jsonpCallback: function() { | |
7033 return jQuery.expando + "_" + ( jsc++ ); | |
7034 } | |
7035 }); | |
7036 | |
7037 // Detect, normalize options and install callbacks for jsonp requests | |
7038 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { | |
7039 | |
7040 var dataIsString = ( typeof s.data === "string" ); | |
7041 | |
7042 if ( s.dataTypes[ 0 ] === "jsonp" || | |
7043 originalSettings.jsonpCallback || | |
7044 originalSettings.jsonp != null || | |
7045 s.jsonp !== false && ( jsre.test( s.url ) || | |
7046 dataIsString && jsre.test( s.data ) ) ) { | |
7047 | |
7048 var responseContainer, | |
7049 jsonpCallback = s.jsonpCallback = | |
7050 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, | |
7051 previous = window[ jsonpCallback ], | |
7052 url = s.url, | |
7053 data = s.data, | |
7054 replace = "$1" + jsonpCallback + "$2", | |
7055 cleanUp = function() { | |
7056 // Set callback back to previous value | |
7057 window[ jsonpCallback ] = previous; | |
7058 // Call if it was a function and we have a response | |
7059 if ( responseContainer && jQuery.isFunction( previous ) ) { | |
7060 window[ jsonpCallback ]( responseContainer[ 0 ] ); | |
7061 } | |
7062 }; | |
7063 | |
7064 if ( s.jsonp !== false ) { | |
7065 url = url.replace( jsre, replace ); | |
7066 if ( s.url === url ) { | |
7067 if ( dataIsString ) { | |
7068 data = data.replace( jsre, replace ); | |
7069 } | |
7070 if ( s.data === data ) { | |
7071 // Add callback manually | |
7072 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback; | |
7073 } | |
7074 } | |
7075 } | |
7076 | |
7077 s.url = url; | |
7078 s.data = data; | |
7079 | |
7080 // Install callback | |
7081 window[ jsonpCallback ] = function( response ) { | |
7082 responseContainer = [ response ]; | |
7083 }; | |
7084 | |
7085 // Install cleanUp function | |
7086 jqXHR.then( cleanUp, cleanUp ); | |
7087 | |
7088 // Use data converter to retrieve json after script execution | |
7089 s.converters["script json"] = function() { | |
7090 if ( !responseContainer ) { | |
7091 jQuery.error( jsonpCallback + " was not called" ); | |
7092 } | |
7093 return responseContainer[ 0 ]; | |
7094 }; | |
7095 | |
7096 // force json dataType | |
7097 s.dataTypes[ 0 ] = "json"; | |
7098 | |
7099 // Delegate to script | |
7100 return "script"; | |
7101 } | |
7102 } ); | |
7103 | |
7104 | |
7105 | |
7106 | |
7107 // Install script dataType | |
7108 jQuery.ajaxSetup({ | |
7109 accepts: { | |
7110 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" | |
7111 }, | |
7112 contents: { | |
7113 script: /javascript|ecmascript/ | |
7114 }, | |
7115 converters: { | |
7116 "text script": function( text ) { | |
7117 jQuery.globalEval( text ); | |
7118 return text; | |
7119 } | |
7120 } | |
7121 }); | |
7122 | |
7123 // Handle cache's special case and global | |
7124 jQuery.ajaxPrefilter( "script", function( s ) { | |
7125 if ( s.cache === undefined ) { | |
7126 s.cache = false; | |
7127 } | |
7128 if ( s.crossDomain ) { | |
7129 s.type = "GET"; | |
7130 s.global = false; | |
7131 } | |
7132 } ); | |
7133 | |
7134 // Bind script tag hack transport | |
7135 jQuery.ajaxTransport( "script", function(s) { | |
7136 | |
7137 // This transport only deals with cross domain requests | |
7138 if ( s.crossDomain ) { | |
7139 | |
7140 var script, | |
7141 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; | |
7142 | |
7143 return { | |
7144 | |
7145 send: function( _, callback ) { | |
7146 | |
7147 script = document.createElement( "script" ); | |
7148 | |
7149 script.async = "async"; | |
7150 | |
7151 if ( s.scriptCharset ) { | |
7152 script.charset = s.scriptCharset; | |
7153 } | |
7154 | |
7155 script.src = s.url; | |
7156 | |
7157 // Attach handlers for all browsers | |
7158 script.onload = script.onreadystatechange = function( _, isAbort ) { | |
7159 | |
7160 if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) { | |
7161 | |
7162 // Handle memory leak in IE | |
7163 script.onload = script.onreadystatechange = null; | |
7164 | |
7165 // Remove the script | |
7166 if ( head && script.parentNode ) { | |
7167 head.removeChild( script ); | |
7168 } | |
7169 | |
7170 // Dereference the script | |
7171 script = undefined; | |
7172 | |
7173 // Callback if not abort | |
7174 if ( !isAbort ) { | |
7175 callback( 200, "success" ); | |
7176 } | |
7177 } | |
7178 }; | |
7179 // Use insertBefore instead of appendChild to circumvent an IE6 bug. | |
7180 // This arises when a base node is used (#2709 and #4378). | |
7181 head.insertBefore( script, head.firstChild ); | |
7182 }, | |
7183 | |
7184 abort: function() { | |
7185 if ( script ) { | |
7186 script.onload( 0, 1 ); | |
7187 } | |
7188 } | |
7189 }; | |
7190 } | |
7191 } ); | |
7192 | |
7193 | |
7194 | |
7195 | |
7196 var // #5280: next active xhr id and list of active xhrs' callbacks | |
7197 xhrId = jQuery.now(), | |
7198 xhrCallbacks, | |
7199 | |
7200 // XHR used to determine supports properties | |
7201 testXHR; | |
7202 | |
7203 // #5280: Internet Explorer will keep connections alive if we don't abort on unload | |
7204 function xhrOnUnloadAbort() { | |
7205 jQuery( window ).unload(function() { | |
7206 // Abort all pending requests | |
7207 for ( var key in xhrCallbacks ) { | |
7208 xhrCallbacks[ key ]( 0, 1 ); | |
7209 } | |
7210 }); | |
7211 } | |
7212 | |
7213 // Functions to create xhrs | |
7214 function createStandardXHR() { | |
7215 try { | |
7216 return new window.XMLHttpRequest(); | |
7217 } catch( e ) {} | |
7218 } | |
7219 | |
7220 function createActiveXHR() { | |
7221 try { | |
7222 return new window.ActiveXObject( "Microsoft.XMLHTTP" ); | |
7223 } catch( e ) {} | |
7224 } | |
7225 | |
7226 // Create the request object | |
7227 // (This is still attached to ajaxSettings for backward compatibility) | |
7228 jQuery.ajaxSettings.xhr = window.ActiveXObject ? | |
7229 /* Microsoft failed to properly | |
7230 * implement the XMLHttpRequest in IE7 (can't request local files), | |
7231 * so we use the ActiveXObject when it is available | |
7232 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so | |
7233 * we need a fallback. | |
7234 */ | |
7235 function() { | |
7236 return !this.isLocal && createStandardXHR() || createActiveXHR(); | |
7237 } : | |
7238 // For all other browsers, use the standard XMLHttpRequest object | |
7239 createStandardXHR; | |
7240 | |
7241 // Test if we can create an xhr object | |
7242 testXHR = jQuery.ajaxSettings.xhr(); | |
7243 jQuery.support.ajax = !!testXHR; | |
7244 | |
7245 // Does this browser support crossDomain XHR requests | |
7246 jQuery.support.cors = testXHR && ( "withCredentials" in testXHR ); | |
7247 | |
7248 // No need for the temporary xhr anymore | |
7249 testXHR = undefined; | |
7250 | |
7251 // Create transport if the browser can provide an xhr | |
7252 if ( jQuery.support.ajax ) { | |
7253 | |
7254 jQuery.ajaxTransport(function( s ) { | |
7255 // Cross domain only allowed if supported through XMLHttpRequest | |
7256 if ( !s.crossDomain || jQuery.support.cors ) { | |
7257 | |
7258 var callback; | |
7259 | |
7260 return { | |
7261 send: function( headers, complete ) { | |
7262 | |
7263 // Get a new xhr | |
7264 var xhr = s.xhr(), | |
7265 handle, | |
7266 i; | |
7267 | |
7268 // Open the socket | |
7269 // Passing null username, generates a login popup on Opera (#2865) | |
7270 if ( s.username ) { | |
7271 xhr.open( s.type, s.url, s.async, s.username, s.password ); | |
7272 } else { | |
7273 xhr.open( s.type, s.url, s.async ); | |
7274 } | |
7275 | |
7276 // Apply custom fields if provided | |
7277 if ( s.xhrFields ) { | |
7278 for ( i in s.xhrFields ) { | |
7279 xhr[ i ] = s.xhrFields[ i ]; | |
7280 } | |
7281 } | |
7282 | |
7283 // Override mime type if needed | |
7284 if ( s.mimeType && xhr.overrideMimeType ) { | |
7285 xhr.overrideMimeType( s.mimeType ); | |
7286 } | |
7287 | |
7288 // Requested-With header | |
7289 // Not set for crossDomain requests with no content | |
7290 // (see why at http://trac.dojotoolkit.org/ticket/9486) | |
7291 // Won't change header if already provided | |
7292 if ( !( s.crossDomain && !s.hasContent ) && !headers["X-Requested-With"] ) { | |
7293 headers[ "X-Requested-With" ] = "XMLHttpRequest"; | |
7294 } | |
7295 | |
7296 // Need an extra try/catch for cross domain requests in Firefox 3 | |
7297 try { | |
7298 for ( i in headers ) { | |
7299 xhr.setRequestHeader( i, headers[ i ] ); | |
7300 } | |
7301 } catch( _ ) {} | |
7302 | |
7303 // Do send the request | |
7304 // This may raise an exception which is actually | |
7305 // handled in jQuery.ajax (so no try/catch here) | |
7306 xhr.send( ( s.hasContent && s.data ) || null ); | |
7307 | |
7308 // Listener | |
7309 callback = function( _, isAbort ) { | |
7310 | |
7311 var status, | |
7312 statusText, | |
7313 responseHeaders, | |
7314 responses, | |
7315 xml; | |
7316 | |
7317 // Firefox throws exceptions when accessing properties | |
7318 // of an xhr when a network error occured | |
7319 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) | |
7320 try { | |
7321 | |
7322 // Was never called and is aborted or complete | |
7323 if ( callback && ( isAbort || xhr.readyState === 4 ) ) { | |
7324 | |
7325 // Only called once | |
7326 callback = undefined; | |
7327 | |
7328 // Do not keep as active anymore | |
7329 if ( handle ) { | |
7330 xhr.onreadystatechange = jQuery.noop; | |
7331 delete xhrCallbacks[ handle ]; | |
7332 } | |
7333 | |
7334 // If it's an abort | |
7335 if ( isAbort ) { | |
7336 // Abort it manually if needed | |
7337 if ( xhr.readyState !== 4 ) { | |
7338 xhr.abort(); | |
7339 } | |
7340 } else { | |
7341 status = xhr.status; | |
7342 responseHeaders = xhr.getAllResponseHeaders(); | |
7343 responses = {}; | |
7344 xml = xhr.responseXML; | |
7345 | |
7346 // Construct response list | |
7347 if ( xml && xml.documentElement /* #4958 */ ) { | |
7348 responses.xml = xml; | |
7349 } | |
7350 responses.text = xhr.responseText; | |
7351 | |
7352 // Firefox throws an exception when accessing | |
7353 // statusText for faulty cross-domain requests | |
7354 try { | |
7355 statusText = xhr.statusText; | |
7356 } catch( e ) { | |
7357 // We normalize with Webkit giving an empty statusText | |
7358 statusText = ""; | |
7359 } | |
7360 | |
7361 // Filter status for non standard behaviors | |
7362 | |
7363 // If the request is local and we have data: assume a success | |
7364 // (success with no data won't get notified, that's the best we | |
7365 // can do given current implementations) | |
7366 if ( !status && s.isLocal && !s.crossDomain ) { | |
7367 status = responses.text ? 200 : 404; | |
7368 // IE - #1450: sometimes returns 1223 when it should be 204 | |
7369 } else if ( status === 1223 ) { | |
7370 status = 204; | |
7371 } | |
7372 } | |
7373 } | |
7374 } catch( firefoxAccessException ) { | |
7375 if ( !isAbort ) { | |
7376 complete( -1, firefoxAccessException ); | |
7377 } | |
7378 } | |
7379 | |
7380 // Call complete if needed | |
7381 if ( responses ) { | |
7382 complete( status, statusText, responses, responseHeaders ); | |
7383 } | |
7384 }; | |
7385 | |
7386 // if we're in sync mode or it's in cache | |
7387 // and has been retrieved directly (IE6 & IE7) | |
7388 // we need to manually fire the callback | |
7389 if ( !s.async || xhr.readyState === 4 ) { | |
7390 callback(); | |
7391 } else { | |
7392 // Create the active xhrs callbacks list if needed | |
7393 // and attach the unload handler | |
7394 if ( !xhrCallbacks ) { | |
7395 xhrCallbacks = {}; | |
7396 xhrOnUnloadAbort(); | |
7397 } | |
7398 // Add to list of active xhrs callbacks | |
7399 handle = xhrId++; | |
7400 xhr.onreadystatechange = xhrCallbacks[ handle ] = callback; | |
7401 } | |
7402 }, | |
7403 | |
7404 abort: function() { | |
7405 if ( callback ) { | |
7406 callback(0,1); | |
7407 } | |
7408 } | |
7409 }; | |
7410 } | |
7411 }); | |
7412 } | |
7413 | |
7414 | |
7415 | |
7416 | |
7417 var elemdisplay = {}, | |
7418 rfxtypes = /^(?:toggle|show|hide)$/, | |
7419 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, | |
7420 timerId, | |
7421 fxAttrs = [ | |
7422 // height animations | |
7423 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], | |
7424 // width animations | |
7425 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], | |
7426 // opacity animations | |
7427 [ "opacity" ] | |
7428 ]; | |
7429 | |
7430 jQuery.fn.extend({ | |
7431 show: function( speed, easing, callback ) { | |
7432 var elem, display; | |
7433 | |
7434 if ( speed || speed === 0 ) { | |
7435 return this.animate( genFx("show", 3), speed, easing, callback); | |
7436 | |
7437 } else { | |
7438 for ( var i = 0, j = this.length; i < j; i++ ) { | |
7439 elem = this[i]; | |
7440 display = elem.style.display; | |
7441 | |
7442 // Reset the inline display of this element to learn if it is | |
7443 // being hidden by cascaded rules or not | |
7444 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { | |
7445 display = elem.style.display = ""; | |
7446 } | |
7447 | |
7448 // Set elements which have been overridden with display: none | |
7449 // in a stylesheet to whatever the default browser style is | |
7450 // for such an element | |
7451 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { | |
7452 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); | |
7453 } | |
7454 } | |
7455 | |
7456 // Set the display of most of the elements in a second loop | |
7457 // to avoid the constant reflow | |
7458 for ( i = 0; i < j; i++ ) { | |
7459 elem = this[i]; | |
7460 display = elem.style.display; | |
7461 | |
7462 if ( display === "" || display === "none" ) { | |
7463 elem.style.display = jQuery._data(elem, "olddisplay") || ""; | |
7464 } | |
7465 } | |
7466 | |
7467 return this; | |
7468 } | |
7469 }, | |
7470 | |
7471 hide: function( speed, easing, callback ) { | |
7472 if ( speed || speed === 0 ) { | |
7473 return this.animate( genFx("hide", 3), speed, easing, callback); | |
7474 | |
7475 } else { | |
7476 for ( var i = 0, j = this.length; i < j; i++ ) { | |
7477 var display = jQuery.css( this[i], "display" ); | |
7478 | |
7479 if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { | |
7480 jQuery._data( this[i], "olddisplay", display ); | |
7481 } | |
7482 } | |
7483 | |
7484 // Set the display of the elements in a second loop | |
7485 // to avoid the constant reflow | |
7486 for ( i = 0; i < j; i++ ) { | |
7487 this[i].style.display = "none"; | |
7488 } | |
7489 | |
7490 return this; | |
7491 } | |
7492 }, | |
7493 | |
7494 // Save the old toggle function | |
7495 _toggle: jQuery.fn.toggle, | |
7496 | |
7497 toggle: function( fn, fn2, callback ) { | |
7498 var bool = typeof fn === "boolean"; | |
7499 | |
7500 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { | |
7501 this._toggle.apply( this, arguments ); | |
7502 | |
7503 } else if ( fn == null || bool ) { | |
7504 this.each(function() { | |
7505 var state = bool ? fn : jQuery(this).is(":hidden"); | |
7506 jQuery(this)[ state ? "show" : "hide" ](); | |
7507 }); | |
7508 | |
7509 } else { | |
7510 this.animate(genFx("toggle", 3), fn, fn2, callback); | |
7511 } | |
7512 | |
7513 return this; | |
7514 }, | |
7515 | |
7516 fadeTo: function( speed, to, easing, callback ) { | |
7517 return this.filter(":hidden").css("opacity", 0).show().end() | |
7518 .animate({opacity: to}, speed, easing, callback); | |
7519 }, | |
7520 | |
7521 animate: function( prop, speed, easing, callback ) { | |
7522 var optall = jQuery.speed(speed, easing, callback); | |
7523 | |
7524 if ( jQuery.isEmptyObject( prop ) ) { | |
7525 return this.each( optall.complete ); | |
7526 } | |
7527 | |
7528 return this[ optall.queue === false ? "each" : "queue" ](function() { | |
7529 // XXX 'this' does not always have a nodeName when running the | |
7530 // test suite | |
7531 | |
7532 var opt = jQuery.extend({}, optall), p, | |
7533 isElement = this.nodeType === 1, | |
7534 hidden = isElement && jQuery(this).is(":hidden"), | |
7535 self = this; | |
7536 | |
7537 for ( p in prop ) { | |
7538 var name = jQuery.camelCase( p ); | |
7539 | |
7540 if ( p !== name ) { | |
7541 prop[ name ] = prop[ p ]; | |
7542 delete prop[ p ]; | |
7543 p = name; | |
7544 } | |
7545 | |
7546 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { | |
7547 return opt.complete.call(this); | |
7548 } | |
7549 | |
7550 if ( isElement && ( p === "height" || p === "width" ) ) { | |
7551 // Make sure that nothing sneaks out | |
7552 // Record all 3 overflow attributes because IE does not | |
7553 // change the overflow attribute when overflowX and | |
7554 // overflowY are set to the same value | |
7555 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; | |
7556 | |
7557 // Set display property to inline-block for height/width | |
7558 // animations on inline elements that are having width/height | |
7559 // animated | |
7560 if ( jQuery.css( this, "display" ) === "inline" && | |
7561 jQuery.css( this, "float" ) === "none" ) { | |
7562 if ( !jQuery.support.inlineBlockNeedsLayout ) { | |
7563 this.style.display = "inline-block"; | |
7564 | |
7565 } else { | |
7566 var display = defaultDisplay(this.nodeName); | |
7567 | |
7568 // inline-level elements accept inline-block; | |
7569 // block-level elements need to be inline with layout | |
7570 if ( display === "inline" ) { | |
7571 this.style.display = "inline-block"; | |
7572 | |
7573 } else { | |
7574 this.style.display = "inline"; | |
7575 this.style.zoom = 1; | |
7576 } | |
7577 } | |
7578 } | |
7579 } | |
7580 | |
7581 if ( jQuery.isArray( prop[p] ) ) { | |
7582 // Create (if needed) and add to specialEasing | |
7583 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; | |
7584 prop[p] = prop[p][0]; | |
7585 } | |
7586 } | |
7587 | |
7588 if ( opt.overflow != null ) { | |
7589 this.style.overflow = "hidden"; | |
7590 } | |
7591 | |
7592 opt.curAnim = jQuery.extend({}, prop); | |
7593 | |
7594 jQuery.each( prop, function( name, val ) { | |
7595 var e = new jQuery.fx( self, opt, name ); | |
7596 | |
7597 if ( rfxtypes.test(val) ) { | |
7598 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); | |
7599 | |
7600 } else { | |
7601 var parts = rfxnum.exec(val), | |
7602 start = e.cur(); | |
7603 | |
7604 if ( parts ) { | |
7605 var end = parseFloat( parts[2] ), | |
7606 unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" ); | |
7607 | |
7608 // We need to compute starting value | |
7609 if ( unit !== "px" ) { | |
7610 jQuery.style( self, name, (end || 1) + unit); | |
7611 start = ((end || 1) / e.cur()) * start; | |
7612 jQuery.style( self, name, start + unit); | |
7613 } | |
7614 | |
7615 // If a +=/-= token was provided, we're doing a relative animation | |
7616 if ( parts[1] ) { | |
7617 end = ((parts[1] === "-=" ? -1 : 1) * end) + start; | |
7618 } | |
7619 | |
7620 e.custom( start, end, unit ); | |
7621 | |
7622 } else { | |
7623 e.custom( start, val, "" ); | |
7624 } | |
7625 } | |
7626 }); | |
7627 | |
7628 // For JS strict compliance | |
7629 return true; | |
7630 }); | |
7631 }, | |
7632 | |
7633 stop: function( clearQueue, gotoEnd ) { | |
7634 var timers = jQuery.timers; | |
7635 | |
7636 if ( clearQueue ) { | |
7637 this.queue([]); | |
7638 } | |
7639 | |
7640 this.each(function() { | |
7641 // go in reverse order so anything added to the queue during the loop is ignored | |
7642 for ( var i = timers.length - 1; i >= 0; i-- ) { | |
7643 if ( timers[i].elem === this ) { | |
7644 if (gotoEnd) { | |
7645 // force the next step to be the last | |
7646 timers[i](true); | |
7647 } | |
7648 | |
7649 timers.splice(i, 1); | |
7650 } | |
7651 } | |
7652 }); | |
7653 | |
7654 // start the next in the queue if the last step wasn't forced | |
7655 if ( !gotoEnd ) { | |
7656 this.dequeue(); | |
7657 } | |
7658 | |
7659 return this; | |
7660 } | |
7661 | |
7662 }); | |
7663 | |
7664 function genFx( type, num ) { | |
7665 var obj = {}; | |
7666 | |
7667 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() { | |
7668 obj[ this ] = type; | |
7669 }); | |
7670 | |
7671 return obj; | |
7672 } | |
7673 | |
7674 // Generate shortcuts for custom animations | |
7675 jQuery.each({ | |
7676 slideDown: genFx("show", 1), | |
7677 slideUp: genFx("hide", 1), | |
7678 slideToggle: genFx("toggle", 1), | |
7679 fadeIn: { opacity: "show" }, | |
7680 fadeOut: { opacity: "hide" }, | |
7681 fadeToggle: { opacity: "toggle" } | |
7682 }, function( name, props ) { | |
7683 jQuery.fn[ name ] = function( speed, easing, callback ) { | |
7684 return this.animate( props, speed, easing, callback ); | |
7685 }; | |
7686 }); | |
7687 | |
7688 jQuery.extend({ | |
7689 speed: function( speed, easing, fn ) { | |
7690 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { | |
7691 complete: fn || !fn && easing || | |
7692 jQuery.isFunction( speed ) && speed, | |
7693 duration: speed, | |
7694 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing | |
7695 }; | |
7696 | |
7697 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : | |
7698 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; | |
7699 | |
7700 // Queueing | |
7701 opt.old = opt.complete; | |
7702 opt.complete = function() { | |
7703 if ( opt.queue !== false ) { | |
7704 jQuery(this).dequeue(); | |
7705 } | |
7706 if ( jQuery.isFunction( opt.old ) ) { | |
7707 opt.old.call( this ); | |
7708 } | |
7709 }; | |
7710 | |
7711 return opt; | |
7712 }, | |
7713 | |
7714 easing: { | |
7715 linear: function( p, n, firstNum, diff ) { | |
7716 return firstNum + diff * p; | |
7717 }, | |
7718 swing: function( p, n, firstNum, diff ) { | |
7719 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; | |
7720 } | |
7721 }, | |
7722 | |
7723 timers: [], | |
7724 | |
7725 fx: function( elem, options, prop ) { | |
7726 this.options = options; | |
7727 this.elem = elem; | |
7728 this.prop = prop; | |
7729 | |
7730 if ( !options.orig ) { | |
7731 options.orig = {}; | |
7732 } | |
7733 } | |
7734 | |
7735 }); | |
7736 | |
7737 jQuery.fx.prototype = { | |
7738 // Simple function for setting a style value | |
7739 update: function() { | |
7740 if ( this.options.step ) { | |
7741 this.options.step.call( this.elem, this.now, this ); | |
7742 } | |
7743 | |
7744 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); | |
7745 }, | |
7746 | |
7747 // Get the current size | |
7748 cur: function() { | |
7749 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) { | |
7750 return this.elem[ this.prop ]; | |
7751 } | |
7752 | |
7753 var parsed, | |
7754 r = jQuery.css( this.elem, this.prop ); | |
7755 // Empty strings, null, undefined and "auto" are converted to 0, | |
7756 // complex values such as "rotate(1rad)" are returned as is, | |
7757 // simple values such as "10px" are parsed to Float. | |
7758 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; | |
7759 }, | |
7760 | |
7761 // Start an animation from one number to another | |
7762 custom: function( from, to, unit ) { | |
7763 var self = this, | |
7764 fx = jQuery.fx; | |
7765 | |
7766 this.startTime = jQuery.now(); | |
7767 this.start = from; | |
7768 this.end = to; | |
7769 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); | |
7770 this.now = this.start; | |
7771 this.pos = this.state = 0; | |
7772 | |
7773 function t( gotoEnd ) { | |
7774 return self.step(gotoEnd); | |
7775 } | |
7776 | |
7777 t.elem = this.elem; | |
7778 | |
7779 if ( t() && jQuery.timers.push(t) && !timerId ) { | |
7780 timerId = setInterval(fx.tick, fx.interval); | |
7781 } | |
7782 }, | |
7783 | |
7784 // Simple 'show' function | |
7785 show: function() { | |
7786 // Remember where we started, so that we can go back to it later | |
7787 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); | |
7788 this.options.show = true; | |
7789 | |
7790 // Begin the animation | |
7791 // Make sure that we start at a small width/height to avoid any | |
7792 // flash of content | |
7793 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur()); | |
7794 | |
7795 // Start by showing the element | |
7796 jQuery( this.elem ).show(); | |
7797 }, | |
7798 | |
7799 // Simple 'hide' function | |
7800 hide: function() { | |
7801 // Remember where we started, so that we can go back to it later | |
7802 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop ); | |
7803 this.options.hide = true; | |
7804 | |
7805 // Begin the animation | |
7806 this.custom(this.cur(), 0); | |
7807 }, | |
7808 | |
7809 // Each step of an animation | |
7810 step: function( gotoEnd ) { | |
7811 var t = jQuery.now(), done = true; | |
7812 | |
7813 if ( gotoEnd || t >= this.options.duration + this.startTime ) { | |
7814 this.now = this.end; | |
7815 this.pos = this.state = 1; | |
7816 this.update(); | |
7817 | |
7818 this.options.curAnim[ this.prop ] = true; | |
7819 | |
7820 for ( var i in this.options.curAnim ) { | |
7821 if ( this.options.curAnim[i] !== true ) { | |
7822 done = false; | |
7823 } | |
7824 } | |
7825 | |
7826 if ( done ) { | |
7827 // Reset the overflow | |
7828 if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { | |
7829 var elem = this.elem, | |
7830 options = this.options; | |
7831 | |
7832 jQuery.each( [ "", "X", "Y" ], function (index, value) { | |
7833 elem.style[ "overflow" + value ] = options.overflow[index]; | |
7834 } ); | |
7835 } | |
7836 | |
7837 // Hide the element if the "hide" operation was done | |
7838 if ( this.options.hide ) { | |
7839 jQuery(this.elem).hide(); | |
7840 } | |
7841 | |
7842 // Reset the properties, if the item has been hidden or shown | |
7843 if ( this.options.hide || this.options.show ) { | |
7844 for ( var p in this.options.curAnim ) { | |
7845 jQuery.style( this.elem, p, this.options.orig[p] ); | |
7846 } | |
7847 } | |
7848 | |
7849 // Execute the complete function | |
7850 this.options.complete.call( this.elem ); | |
7851 } | |
7852 | |
7853 return false; | |
7854 | |
7855 } else { | |
7856 var n = t - this.startTime; | |
7857 this.state = n / this.options.duration; | |
7858 | |
7859 // Perform the easing function, defaults to swing | |
7860 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop]; | |
7861 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear"); | |
7862 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration); | |
7863 this.now = this.start + ((this.end - this.start) * this.pos); | |
7864 | |
7865 // Perform the next step of the animation | |
7866 this.update(); | |
7867 } | |
7868 | |
7869 return true; | |
7870 } | |
7871 }; | |
7872 | |
7873 jQuery.extend( jQuery.fx, { | |
7874 tick: function() { | |
7875 var timers = jQuery.timers; | |
7876 | |
7877 for ( var i = 0; i < timers.length; i++ ) { | |
7878 if ( !timers[i]() ) { | |
7879 timers.splice(i--, 1); | |
7880 } | |
7881 } | |
7882 | |
7883 if ( !timers.length ) { | |
7884 jQuery.fx.stop(); | |
7885 } | |
7886 }, | |
7887 | |
7888 interval: 13, | |
7889 | |
7890 stop: function() { | |
7891 clearInterval( timerId ); | |
7892 timerId = null; | |
7893 }, | |
7894 | |
7895 speeds: { | |
7896 slow: 600, | |
7897 fast: 200, | |
7898 // Default speed | |
7899 _default: 400 | |
7900 }, | |
7901 | |
7902 step: { | |
7903 opacity: function( fx ) { | |
7904 jQuery.style( fx.elem, "opacity", fx.now ); | |
7905 }, | |
7906 | |
7907 _default: function( fx ) { | |
7908 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { | |
7909 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit; | |
7910 } else { | |
7911 fx.elem[ fx.prop ] = fx.now; | |
7912 } | |
7913 } | |
7914 } | |
7915 }); | |
7916 | |
7917 if ( jQuery.expr && jQuery.expr.filters ) { | |
7918 jQuery.expr.filters.animated = function( elem ) { | |
7919 return jQuery.grep(jQuery.timers, function( fn ) { | |
7920 return elem === fn.elem; | |
7921 }).length; | |
7922 }; | |
7923 } | |
7924 | |
7925 function defaultDisplay( nodeName ) { | |
7926 if ( !elemdisplay[ nodeName ] ) { | |
7927 var elem = jQuery("<" + nodeName + ">").appendTo("body"), | |
7928 display = elem.css("display"); | |
7929 | |
7930 elem.remove(); | |
7931 | |
7932 if ( display === "none" || display === "" ) { | |
7933 display = "block"; | |
7934 } | |
7935 | |
7936 elemdisplay[ nodeName ] = display; | |
7937 } | |
7938 | |
7939 return elemdisplay[ nodeName ]; | |
7940 } | |
7941 | |
7942 | |
7943 | |
7944 | |
7945 var rtable = /^t(?:able|d|h)$/i, | |
7946 rroot = /^(?:body|html)$/i; | |
7947 | |
7948 if ( "getBoundingClientRect" in document.documentElement ) { | |
7949 jQuery.fn.offset = function( options ) { | |
7950 var elem = this[0], box; | |
7951 | |
7952 if ( options ) { | |
7953 return this.each(function( i ) { | |
7954 jQuery.offset.setOffset( this, options, i ); | |
7955 }); | |
7956 } | |
7957 | |
7958 if ( !elem || !elem.ownerDocument ) { | |
7959 return null; | |
7960 } | |
7961 | |
7962 if ( elem === elem.ownerDocument.body ) { | |
7963 return jQuery.offset.bodyOffset( elem ); | |
7964 } | |
7965 | |
7966 try { | |
7967 box = elem.getBoundingClientRect(); | |
7968 } catch(e) {} | |
7969 | |
7970 var doc = elem.ownerDocument, | |
7971 docElem = doc.documentElement; | |
7972 | |
7973 // Make sure we're not dealing with a disconnected DOM node | |
7974 if ( !box || !jQuery.contains( docElem, elem ) ) { | |
7975 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; | |
7976 } | |
7977 | |
7978 var body = doc.body, | |
7979 win = getWindow(doc), | |
7980 clientTop = docElem.clientTop || body.clientTop || 0, | |
7981 clientLeft = docElem.clientLeft || body.clientLeft || 0, | |
7982 scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ), | |
7983 scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft), | |
7984 top = box.top + scrollTop - clientTop, | |
7985 left = box.left + scrollLeft - clientLeft; | |
7986 | |
7987 return { top: top, left: left }; | |
7988 }; | |
7989 | |
7990 } else { | |
7991 jQuery.fn.offset = function( options ) { | |
7992 var elem = this[0]; | |
7993 | |
7994 if ( options ) { | |
7995 return this.each(function( i ) { | |
7996 jQuery.offset.setOffset( this, options, i ); | |
7997 }); | |
7998 } | |
7999 | |
8000 if ( !elem || !elem.ownerDocument ) { | |
8001 return null; | |
8002 } | |
8003 | |
8004 if ( elem === elem.ownerDocument.body ) { | |
8005 return jQuery.offset.bodyOffset( elem ); | |
8006 } | |
8007 | |
8008 jQuery.offset.initialize(); | |
8009 | |
8010 var computedStyle, | |
8011 offsetParent = elem.offsetParent, | |
8012 prevOffsetParent = elem, | |
8013 doc = elem.ownerDocument, | |
8014 docElem = doc.documentElement, | |
8015 body = doc.body, | |
8016 defaultView = doc.defaultView, | |
8017 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, | |
8018 top = elem.offsetTop, | |
8019 left = elem.offsetLeft; | |
8020 | |
8021 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { | |
8022 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { | |
8023 break; | |
8024 } | |
8025 | |
8026 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; | |
8027 top -= elem.scrollTop; | |
8028 left -= elem.scrollLeft; | |
8029 | |
8030 if ( elem === offsetParent ) { | |
8031 top += elem.offsetTop; | |
8032 left += elem.offsetLeft; | |
8033 | |
8034 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { | |
8035 top += parseFloat( computedStyle.borderTopWidth ) || 0; | |
8036 left += parseFloat( computedStyle.borderLeftWidth ) || 0; | |
8037 } | |
8038 | |
8039 prevOffsetParent = offsetParent; | |
8040 offsetParent = elem.offsetParent; | |
8041 } | |
8042 | |
8043 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { | |
8044 top += parseFloat( computedStyle.borderTopWidth ) || 0; | |
8045 left += parseFloat( computedStyle.borderLeftWidth ) || 0; | |
8046 } | |
8047 | |
8048 prevComputedStyle = computedStyle; | |
8049 } | |
8050 | |
8051 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { | |
8052 top += body.offsetTop; | |
8053 left += body.offsetLeft; | |
8054 } | |
8055 | |
8056 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { | |
8057 top += Math.max( docElem.scrollTop, body.scrollTop ); | |
8058 left += Math.max( docElem.scrollLeft, body.scrollLeft ); | |
8059 } | |
8060 | |
8061 return { top: top, left: left }; | |
8062 }; | |
8063 } | |
8064 | |
8065 jQuery.offset = { | |
8066 initialize: function() { | |
8067 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0, | |
8068 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>"; | |
8069 | |
8070 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } ); | |
8071 | |
8072 container.innerHTML = html; | |
8073 body.insertBefore( container, body.firstChild ); | |
8074 innerDiv = container.firstChild; | |
8075 checkDiv = innerDiv.firstChild; | |
8076 td = innerDiv.nextSibling.firstChild.firstChild; | |
8077 | |
8078 this.doesNotAddBorder = (checkDiv.offsetTop !== 5); | |
8079 this.doesAddBorderForTableAndCells = (td.offsetTop === 5); | |
8080 | |
8081 checkDiv.style.position = "fixed"; | |
8082 checkDiv.style.top = "20px"; | |
8083 | |
8084 // safari subtracts parent border width here which is 5px | |
8085 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); | |
8086 checkDiv.style.position = checkDiv.style.top = ""; | |
8087 | |
8088 innerDiv.style.overflow = "hidden"; | |
8089 innerDiv.style.position = "relative"; | |
8090 | |
8091 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); | |
8092 | |
8093 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); | |
8094 | |
8095 body.removeChild( container ); | |
8096 body = container = innerDiv = checkDiv = table = td = null; | |
8097 jQuery.offset.initialize = jQuery.noop; | |
8098 }, | |
8099 | |
8100 bodyOffset: function( body ) { | |
8101 var top = body.offsetTop, | |
8102 left = body.offsetLeft; | |
8103 | |
8104 jQuery.offset.initialize(); | |
8105 | |
8106 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) { | |
8107 top += parseFloat( jQuery.css(body, "marginTop") ) || 0; | |
8108 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; | |
8109 } | |
8110 | |
8111 return { top: top, left: left }; | |
8112 }, | |
8113 | |
8114 setOffset: function( elem, options, i ) { | |
8115 var position = jQuery.css( elem, "position" ); | |
8116 | |
8117 // set position first, in-case top/left are set even on static elem | |
8118 if ( position === "static" ) { | |
8119 elem.style.position = "relative"; | |
8120 } | |
8121 | |
8122 var curElem = jQuery( elem ), | |
8123 curOffset = curElem.offset(), | |
8124 curCSSTop = jQuery.css( elem, "top" ), | |
8125 curCSSLeft = jQuery.css( elem, "left" ), | |
8126 calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1), | |
8127 props = {}, curPosition = {}, curTop, curLeft; | |
8128 | |
8129 // need to be able to calculate position if either top or left is auto and position is absolute | |
8130 if ( calculatePosition ) { | |
8131 curPosition = curElem.position(); | |
8132 } | |
8133 | |
8134 curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0; | |
8135 curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0; | |
8136 | |
8137 if ( jQuery.isFunction( options ) ) { | |
8138 options = options.call( elem, i, curOffset ); | |
8139 } | |
8140 | |
8141 if (options.top != null) { | |
8142 props.top = (options.top - curOffset.top) + curTop; | |
8143 } | |
8144 if (options.left != null) { | |
8145 props.left = (options.left - curOffset.left) + curLeft; | |
8146 } | |
8147 | |
8148 if ( "using" in options ) { | |
8149 options.using.call( elem, props ); | |
8150 } else { | |
8151 curElem.css( props ); | |
8152 } | |
8153 } | |
8154 }; | |
8155 | |
8156 | |
8157 jQuery.fn.extend({ | |
8158 position: function() { | |
8159 if ( !this[0] ) { | |
8160 return null; | |
8161 } | |
8162 | |
8163 var elem = this[0], | |
8164 | |
8165 // Get *real* offsetParent | |
8166 offsetParent = this.offsetParent(), | |
8167 | |
8168 // Get correct offsets | |
8169 offset = this.offset(), | |
8170 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); | |
8171 | |
8172 // Subtract element margins | |
8173 // note: when an element has margin: auto the offsetLeft and marginLeft | |
8174 // are the same in Safari causing offset.left to incorrectly be 0 | |
8175 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; | |
8176 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; | |
8177 | |
8178 // Add offsetParent borders | |
8179 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; | |
8180 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; | |
8181 | |
8182 // Subtract the two offsets | |
8183 return { | |
8184 top: offset.top - parentOffset.top, | |
8185 left: offset.left - parentOffset.left | |
8186 }; | |
8187 }, | |
8188 | |
8189 offsetParent: function() { | |
8190 return this.map(function() { | |
8191 var offsetParent = this.offsetParent || document.body; | |
8192 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { | |
8193 offsetParent = offsetParent.offsetParent; | |
8194 } | |
8195 return offsetParent; | |
8196 }); | |
8197 } | |
8198 }); | |
8199 | |
8200 | |
8201 // Create scrollLeft and scrollTop methods | |
8202 jQuery.each( ["Left", "Top"], function( i, name ) { | |
8203 var method = "scroll" + name; | |
8204 | |
8205 jQuery.fn[ method ] = function(val) { | |
8206 var elem = this[0], win; | |
8207 | |
8208 if ( !elem ) { | |
8209 return null; | |
8210 } | |
8211 | |
8212 if ( val !== undefined ) { | |
8213 // Set the scroll offset | |
8214 return this.each(function() { | |
8215 win = getWindow( this ); | |
8216 | |
8217 if ( win ) { | |
8218 win.scrollTo( | |
8219 !i ? val : jQuery(win).scrollLeft(), | |
8220 i ? val : jQuery(win).scrollTop() | |
8221 ); | |
8222 | |
8223 } else { | |
8224 this[ method ] = val; | |
8225 } | |
8226 }); | |
8227 } else { | |
8228 win = getWindow( elem ); | |
8229 | |
8230 // Return the scroll offset | |
8231 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : | |
8232 jQuery.support.boxModel && win.document.documentElement[ method ] || | |
8233 win.document.body[ method ] : | |
8234 elem[ method ]; | |
8235 } | |
8236 }; | |
8237 }); | |
8238 | |
8239 function getWindow( elem ) { | |
8240 return jQuery.isWindow( elem ) ? | |
8241 elem : | |
8242 elem.nodeType === 9 ? | |
8243 elem.defaultView || elem.parentWindow : | |
8244 false; | |
8245 } | |
8246 | |
8247 | |
8248 | |
8249 | |
8250 // Create innerHeight, innerWidth, outerHeight and outerWidth methods | |
8251 jQuery.each([ "Height", "Width" ], function( i, name ) { | |
8252 | |
8253 var type = name.toLowerCase(); | |
8254 | |
8255 // innerHeight and innerWidth | |
8256 jQuery.fn["inner" + name] = function() { | |
8257 return this[0] ? | |
8258 parseFloat( jQuery.css( this[0], type, "padding" ) ) : | |
8259 null; | |
8260 }; | |
8261 | |
8262 // outerHeight and outerWidth | |
8263 jQuery.fn["outer" + name] = function( margin ) { | |
8264 return this[0] ? | |
8265 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) : | |
8266 null; | |
8267 }; | |
8268 | |
8269 jQuery.fn[ type ] = function( size ) { | |
8270 // Get window width or height | |
8271 var elem = this[0]; | |
8272 if ( !elem ) { | |
8273 return size == null ? null : this; | |
8274 } | |
8275 | |
8276 if ( jQuery.isFunction( size ) ) { | |
8277 return this.each(function( i ) { | |
8278 var self = jQuery( this ); | |
8279 self[ type ]( size.call( this, i, self[ type ]() ) ); | |
8280 }); | |
8281 } | |
8282 | |
8283 if ( jQuery.isWindow( elem ) ) { | |
8284 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode | |
8285 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat | |
8286 var docElemProp = elem.document.documentElement[ "client" + name ]; | |
8287 return elem.document.compatMode === "CSS1Compat" && docElemProp || | |
8288 elem.document.body[ "client" + name ] || docElemProp; | |
8289 | |
8290 // Get document width or height | |
8291 } else if ( elem.nodeType === 9 ) { | |
8292 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater | |
8293 return Math.max( | |
8294 elem.documentElement["client" + name], | |
8295 elem.body["scroll" + name], elem.documentElement["scroll" + name], | |
8296 elem.body["offset" + name], elem.documentElement["offset" + name] | |
8297 ); | |
8298 | |
8299 // Get or set width or height on the element | |
8300 } else if ( size === undefined ) { | |
8301 var orig = jQuery.css( elem, type ), | |
8302 ret = parseFloat( orig ); | |
8303 | |
8304 return jQuery.isNaN( ret ) ? orig : ret; | |
8305 | |
8306 // Set the width or height on the element (default to pixels if value is unitless) | |
8307 } else { | |
8308 return this.css( type, typeof size === "string" ? size : size + "px" ); | |
8309 } | |
8310 }; | |
8311 | |
8312 }); | |
8313 | |
8314 | |
8315 window.jQuery = window.$ = jQuery; | |
8316 })(window); |