|
1 /* prevent execution of jQuery if included more than once */ |
|
2 if(typeof window.jQuery == "undefined") { |
|
3 /* |
|
4 * jQuery 1.1.2 - New Wave Javascript |
|
5 * |
|
6 * Copyright (c) 2007 John Resig (jquery.com) |
|
7 * Dual licensed under the MIT (MIT-LICENSE.txt) |
|
8 * and GPL (GPL-LICENSE.txt) licenses. |
|
9 * |
|
10 * $Date: 2007-02-28 12:03:00 -0500 (Wed, 28 Feb 2007) $ |
|
11 * $Rev: 1465 $ |
|
12 */ |
|
13 |
|
14 // Global undefined variable |
|
15 window.undefined = window.undefined; |
|
16 var jQuery = function(a,c) { |
|
17 // If the context is global, return a new object |
|
18 if ( window == this ) |
|
19 return new jQuery(a,c); |
|
20 |
|
21 // Make sure that a selection was provided |
|
22 a = a || document; |
|
23 |
|
24 // HANDLE: $(function) |
|
25 // Shortcut for document ready |
|
26 if ( jQuery.isFunction(a) ) |
|
27 return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a ); |
|
28 |
|
29 // Handle HTML strings |
|
30 if ( typeof a == "string" ) { |
|
31 // HANDLE: $(html) -> $(array) |
|
32 var m = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(a); |
|
33 if ( m ) |
|
34 a = jQuery.clean( [ m[1] ] ); |
|
35 |
|
36 // HANDLE: $(expr) |
|
37 else |
|
38 return new jQuery( c ).find( a ); |
|
39 } |
|
40 |
|
41 return this.setArray( |
|
42 // HANDLE: $(array) |
|
43 a.constructor == Array && a || |
|
44 |
|
45 // HANDLE: $(arraylike) |
|
46 // Watch for when an array-like object is passed as the selector |
|
47 (a.jquery || a.length && a != window && !a.nodeType && a[0] != undefined && a[0].nodeType) && jQuery.makeArray( a ) || |
|
48 |
|
49 // HANDLE: $(*) |
|
50 [ a ] ); |
|
51 }; |
|
52 |
|
53 // Map over the $ in case of overwrite |
|
54 if ( typeof $ != "undefined" ) |
|
55 jQuery._$ = $; |
|
56 |
|
57 // Map the jQuery namespace to the '$' one |
|
58 var $jq = jQuery; |
|
59 |
|
60 jQuery.fn = jQuery.prototype = { |
|
61 jquery: "1.1.2", |
|
62 |
|
63 size: function() { |
|
64 return this.length; |
|
65 }, |
|
66 |
|
67 length: 0, |
|
68 |
|
69 get: function( num ) { |
|
70 return num == undefined ? |
|
71 |
|
72 // Return a 'clean' array |
|
73 jQuery.makeArray( this ) : |
|
74 |
|
75 // Return just the object |
|
76 this[num]; |
|
77 }, |
|
78 pushStack: function( a ) { |
|
79 var ret = jQuery(a); |
|
80 ret.prevObject = this; |
|
81 return ret; |
|
82 }, |
|
83 setArray: function( a ) { |
|
84 this.length = 0; |
|
85 [].push.apply( this, a ); |
|
86 return this; |
|
87 }, |
|
88 each: function( fn, args ) { |
|
89 return jQuery.each( this, fn, args ); |
|
90 }, |
|
91 index: function( obj ) { |
|
92 var pos = -1; |
|
93 this.each(function(i){ |
|
94 if ( this == obj ) pos = i; |
|
95 }); |
|
96 return pos; |
|
97 }, |
|
98 |
|
99 attr: function( key, value, type ) { |
|
100 var obj = key; |
|
101 |
|
102 // Look for the case where we're accessing a style value |
|
103 if ( key.constructor == String ) |
|
104 if ( value == undefined ) |
|
105 return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined; |
|
106 else { |
|
107 obj = {}; |
|
108 obj[ key ] = value; |
|
109 } |
|
110 |
|
111 // Check to see if we're setting style values |
|
112 return this.each(function(index){ |
|
113 // Set all the styles |
|
114 for ( var prop in obj ) |
|
115 jQuery.attr( |
|
116 type ? this.style : this, |
|
117 prop, jQuery.prop(this, obj[prop], type, index, prop) |
|
118 ); |
|
119 }); |
|
120 }, |
|
121 |
|
122 css: function( key, value ) { |
|
123 return this.attr( key, value, "curCSS" ); |
|
124 }, |
|
125 |
|
126 text: function(e) { |
|
127 if ( typeof e == "string" ) |
|
128 return this.empty().append( document.createTextNode( e ) ); |
|
129 |
|
130 var t = ""; |
|
131 jQuery.each( e || this, function(){ |
|
132 jQuery.each( this.childNodes, function(){ |
|
133 if ( this.nodeType != 8 ) |
|
134 t += this.nodeType != 1 ? |
|
135 this.nodeValue : jQuery.fn.text([ this ]); |
|
136 }); |
|
137 }); |
|
138 return t; |
|
139 }, |
|
140 |
|
141 wrap: function() { |
|
142 // The elements to wrap the target around |
|
143 var a = jQuery.clean(arguments); |
|
144 |
|
145 // Wrap each of the matched elements individually |
|
146 return this.each(function(){ |
|
147 // Clone the structure that we're using to wrap |
|
148 var b = a[0].cloneNode(true); |
|
149 |
|
150 // Insert it before the element to be wrapped |
|
151 this.parentNode.insertBefore( b, this ); |
|
152 |
|
153 // Find the deepest point in the wrap structure |
|
154 while ( b.firstChild ) |
|
155 b = b.firstChild; |
|
156 |
|
157 // Move the matched element to within the wrap structure |
|
158 b.appendChild( this ); |
|
159 }); |
|
160 }, |
|
161 append: function() { |
|
162 return this.domManip(arguments, true, 1, function(a){ |
|
163 this.appendChild( a ); |
|
164 }); |
|
165 }, |
|
166 prepend: function() { |
|
167 return this.domManip(arguments, true, -1, function(a){ |
|
168 this.insertBefore( a, this.firstChild ); |
|
169 }); |
|
170 }, |
|
171 before: function() { |
|
172 return this.domManip(arguments, false, 1, function(a){ |
|
173 this.parentNode.insertBefore( a, this ); |
|
174 }); |
|
175 }, |
|
176 after: function() { |
|
177 return this.domManip(arguments, false, -1, function(a){ |
|
178 this.parentNode.insertBefore( a, this.nextSibling ); |
|
179 }); |
|
180 }, |
|
181 end: function() { |
|
182 return this.prevObject || jQuery([]); |
|
183 }, |
|
184 find: function(t) { |
|
185 return this.pushStack( jQuery.map( this, function(a){ |
|
186 return jQuery.find(t,a); |
|
187 }), t ); |
|
188 }, |
|
189 clone: function(deep) { |
|
190 return this.pushStack( jQuery.map( this, function(a){ |
|
191 var a = a.cloneNode( deep != undefined ? deep : true ); |
|
192 a.$events = null; // drop $events expando to avoid firing incorrect events |
|
193 return a; |
|
194 }) ); |
|
195 }, |
|
196 |
|
197 filter: function(t) { |
|
198 return this.pushStack( |
|
199 jQuery.isFunction( t ) && |
|
200 jQuery.grep(this, function(el, index){ |
|
201 return t.apply(el, [index]) |
|
202 }) || |
|
203 |
|
204 jQuery.multiFilter(t,this) ); |
|
205 }, |
|
206 |
|
207 not: function(t) { |
|
208 return this.pushStack( |
|
209 t.constructor == String && |
|
210 jQuery.multiFilter(t, this, true) || |
|
211 |
|
212 jQuery.grep(this, function(a) { |
|
213 return ( t.constructor == Array || t.jquery ) |
|
214 ? jQuery.inArray( a, t ) < 0 |
|
215 : a != t; |
|
216 }) |
|
217 ); |
|
218 }, |
|
219 |
|
220 add: function(t) { |
|
221 return this.pushStack( jQuery.merge( |
|
222 this.get(), |
|
223 t.constructor == String ? |
|
224 jQuery(t).get() : |
|
225 t.length != undefined && (!t.nodeName || t.nodeName == "FORM") ? |
|
226 t : [t] ) |
|
227 ); |
|
228 }, |
|
229 is: function(expr) { |
|
230 return expr ? jQuery.filter(expr,this).r.length > 0 : false; |
|
231 }, |
|
232 |
|
233 val: function( val ) { |
|
234 return val == undefined ? |
|
235 ( this.length ? this[0].value : null ) : |
|
236 this.attr( "value", val ); |
|
237 }, |
|
238 |
|
239 html: function( val ) { |
|
240 return val == undefined ? |
|
241 ( this.length ? this[0].innerHTML : null ) : |
|
242 this.empty().append( val ); |
|
243 }, |
|
244 domManip: function(args, table, dir, fn){ |
|
245 var clone = this.length > 1; |
|
246 var a = jQuery.clean(args); |
|
247 if ( dir < 0 ) |
|
248 a.reverse(); |
|
249 |
|
250 return this.each(function(){ |
|
251 var obj = this; |
|
252 |
|
253 if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") ) |
|
254 obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody")); |
|
255 |
|
256 jQuery.each( a, function(){ |
|
257 fn.apply( obj, [ clone ? this.cloneNode(true) : this ] ); |
|
258 }); |
|
259 |
|
260 }); |
|
261 } |
|
262 }; |
|
263 |
|
264 jQuery.extend = jQuery.fn.extend = function() { |
|
265 // copy reference to target object |
|
266 var target = arguments[0], |
|
267 a = 1; |
|
268 |
|
269 // extend jQuery itself if only one argument is passed |
|
270 if ( arguments.length == 1 ) { |
|
271 target = this; |
|
272 a = 0; |
|
273 } |
|
274 var prop; |
|
275 while (prop = arguments[a++]) |
|
276 // Extend the base object |
|
277 for ( var i in prop ) target[i] = prop[i]; |
|
278 |
|
279 // Return the modified object |
|
280 return target; |
|
281 }; |
|
282 |
|
283 jQuery.extend({ |
|
284 noConflict: function() { |
|
285 if ( jQuery._$ ) |
|
286 $ = jQuery._$; |
|
287 return jQuery; |
|
288 }, |
|
289 |
|
290 // This may seem like some crazy code, but trust me when I say that this |
|
291 // is the only cross-browser way to do this. --John |
|
292 isFunction: function( fn ) { |
|
293 return !!fn && typeof fn != "string" && !fn.nodeName && |
|
294 typeof fn[0] == "undefined" && /function/i.test( fn + "" ); |
|
295 }, |
|
296 |
|
297 // check if an element is in a XML document |
|
298 isXMLDoc: function(elem) { |
|
299 return elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; |
|
300 }, |
|
301 |
|
302 nodeName: function( elem, name ) { |
|
303 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); |
|
304 }, |
|
305 // args is for internal usage only |
|
306 each: function( obj, fn, args ) { |
|
307 if ( obj.length == undefined ) |
|
308 for ( var i in obj ) |
|
309 fn.apply( obj[i], args || [i, obj[i]] ); |
|
310 else |
|
311 for ( var i = 0, ol = obj.length; i < ol; i++ ) |
|
312 if ( fn.apply( obj[i], args || [i, obj[i]] ) === false ) break; |
|
313 return obj; |
|
314 }, |
|
315 |
|
316 prop: function(elem, value, type, index, prop){ |
|
317 // Handle executable functions |
|
318 if ( jQuery.isFunction( value ) ) |
|
319 value = value.call( elem, [index] ); |
|
320 |
|
321 // exclude the following css properties to add px |
|
322 var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; |
|
323 |
|
324 // Handle passing in a number to a CSS property |
|
325 return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ? |
|
326 value + "px" : |
|
327 value; |
|
328 }, |
|
329 |
|
330 className: { |
|
331 // internal only, use addClass("class") |
|
332 add: function( elem, c ){ |
|
333 jQuery.each( c.split(/\s+/), function(i, cur){ |
|
334 if ( !jQuery.className.has( elem.className, cur ) ) |
|
335 elem.className += ( elem.className ? " " : "" ) + cur; |
|
336 }); |
|
337 }, |
|
338 |
|
339 // internal only, use removeClass("class") |
|
340 remove: function( elem, c ){ |
|
341 elem.className = c ? |
|
342 jQuery.grep( elem.className.split(/\s+/), function(cur){ |
|
343 return !jQuery.className.has( c, cur ); |
|
344 }).join(" ") : ""; |
|
345 }, |
|
346 |
|
347 // internal only, use is(".class") |
|
348 has: function( t, c ) { |
|
349 t = t.className || t; |
|
350 // escape regex characters |
|
351 c = c.replace(/([\.\\\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"); |
|
352 return t && new RegExp("(^|\\s)" + c + "(\\s|$)").test( t ); |
|
353 } |
|
354 }, |
|
355 swap: function(e,o,f) { |
|
356 for ( var i in o ) { |
|
357 e.style["old"+i] = e.style[i]; |
|
358 e.style[i] = o[i]; |
|
359 } |
|
360 f.apply( e, [] ); |
|
361 for ( var i in o ) |
|
362 e.style[i] = e.style["old"+i]; |
|
363 }, |
|
364 |
|
365 css: function(e,p) { |
|
366 if ( p == "height" || p == "width" ) { |
|
367 var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"]; |
|
368 |
|
369 jQuery.each( d, function(){ |
|
370 old["padding" + this] = 0; |
|
371 old["border" + this + "Width"] = 0; |
|
372 }); |
|
373 |
|
374 jQuery.swap( e, old, function() { |
|
375 if (jQuery.css(e,"display") != "none") { |
|
376 oHeight = e.offsetHeight; |
|
377 oWidth = e.offsetWidth; |
|
378 } else { |
|
379 e = jQuery(e.cloneNode(true)) |
|
380 .find(":radio").removeAttr("checked").end() |
|
381 .css({ |
|
382 visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0" |
|
383 }).appendTo(e.parentNode)[0]; |
|
384 |
|
385 var parPos = jQuery.css(e.parentNode,"position"); |
|
386 if ( parPos == "" || parPos == "static" ) |
|
387 e.parentNode.style.position = "relative"; |
|
388 |
|
389 oHeight = e.clientHeight; |
|
390 oWidth = e.clientWidth; |
|
391 |
|
392 if ( parPos == "" || parPos == "static" ) |
|
393 e.parentNode.style.position = "static"; |
|
394 |
|
395 e.parentNode.removeChild(e); |
|
396 } |
|
397 }); |
|
398 |
|
399 return p == "height" ? oHeight : oWidth; |
|
400 } |
|
401 |
|
402 return jQuery.curCSS( e, p ); |
|
403 }, |
|
404 |
|
405 curCSS: function(elem, prop, force) { |
|
406 var ret; |
|
407 |
|
408 if (prop == "opacity" && jQuery.browser.msie) |
|
409 return jQuery.attr(elem.style, "opacity"); |
|
410 |
|
411 if (prop == "float" || prop == "cssFloat") |
|
412 prop = jQuery.browser.msie ? "styleFloat" : "cssFloat"; |
|
413 |
|
414 if (!force && elem.style[prop]) |
|
415 ret = elem.style[prop]; |
|
416 |
|
417 else if (document.defaultView && document.defaultView.getComputedStyle) { |
|
418 |
|
419 if (prop == "cssFloat" || prop == "styleFloat") |
|
420 prop = "float"; |
|
421 |
|
422 prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase(); |
|
423 var cur = document.defaultView.getComputedStyle(elem, null); |
|
424 |
|
425 if ( cur ) |
|
426 ret = cur.getPropertyValue(prop); |
|
427 else if ( prop == "display" ) |
|
428 ret = "none"; |
|
429 else |
|
430 jQuery.swap(elem, { display: "block" }, function() { |
|
431 var c = document.defaultView.getComputedStyle(this, ""); |
|
432 ret = c && c.getPropertyValue(prop) || ""; |
|
433 }); |
|
434 |
|
435 } else if (elem.currentStyle) { |
|
436 |
|
437 var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();}); |
|
438 ret = elem.currentStyle[prop] || elem.currentStyle[newProp]; |
|
439 |
|
440 } |
|
441 |
|
442 return ret; |
|
443 }, |
|
444 |
|
445 clean: function(a) { |
|
446 var r = []; |
|
447 |
|
448 jQuery.each( a, function(i,arg){ |
|
449 if ( !arg ) return; |
|
450 |
|
451 if ( arg.constructor == Number ) |
|
452 arg = arg.toString(); |
|
453 |
|
454 // Convert html string into DOM nodes |
|
455 if ( typeof arg == "string" ) { |
|
456 // Trim whitespace, otherwise indexOf won't work as expected |
|
457 var s = jQuery.trim(arg), div = document.createElement("div"), tb = []; |
|
458 |
|
459 var wrap = |
|
460 // option or optgroup |
|
461 !s.indexOf("<opt") && |
|
462 [1, "<select>", "</select>"] || |
|
463 |
|
464 (!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot")) && |
|
465 [1, "<table>", "</table>"] || |
|
466 |
|
467 !s.indexOf("<tr") && |
|
468 [2, "<table><tbody>", "</tbody></table>"] || |
|
469 |
|
470 // <thead> matched above |
|
471 (!s.indexOf("<td") || !s.indexOf("<th")) && |
|
472 [3, "<table><tbody><tr>", "</tr></tbody></table>"] || |
|
473 |
|
474 [0,"",""]; |
|
475 |
|
476 // Go to html and back, then peel off extra wrappers |
|
477 div.innerHTML = wrap[1] + s + wrap[2]; |
|
478 |
|
479 // Move to the right depth |
|
480 while ( wrap[0]-- ) |
|
481 div = div.firstChild; |
|
482 |
|
483 // Remove IE's autoinserted <tbody> from table fragments |
|
484 if ( jQuery.browser.msie ) { |
|
485 |
|
486 // String was a <table>, *may* have spurious <tbody> |
|
487 if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) |
|
488 tb = div.firstChild && div.firstChild.childNodes; |
|
489 |
|
490 // String was a bare <thead> or <tfoot> |
|
491 else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 ) |
|
492 tb = div.childNodes; |
|
493 |
|
494 for ( var n = tb.length-1; n >= 0 ; --n ) |
|
495 if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length ) |
|
496 tb[n].parentNode.removeChild(tb[n]); |
|
497 |
|
498 } |
|
499 |
|
500 arg = []; |
|
501 for (var i=0, l=div.childNodes.length; i<l; i++) |
|
502 arg.push(div.childNodes[i]); |
|
503 } |
|
504 |
|
505 if ( arg.length === 0 && !jQuery.nodeName(arg, "form") ) |
|
506 return; |
|
507 |
|
508 if ( arg[0] == undefined || jQuery.nodeName(arg, "form") ) |
|
509 r.push( arg ); |
|
510 else |
|
511 r = jQuery.merge( r, arg ); |
|
512 |
|
513 }); |
|
514 |
|
515 return r; |
|
516 }, |
|
517 |
|
518 attr: function(elem, name, value){ |
|
519 var fix = jQuery.isXMLDoc(elem) ? {} : { |
|
520 "for": "htmlFor", |
|
521 "class": "className", |
|
522 "float": jQuery.browser.msie ? "styleFloat" : "cssFloat", |
|
523 cssFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat", |
|
524 innerHTML: "innerHTML", |
|
525 className: "className", |
|
526 value: "value", |
|
527 disabled: "disabled", |
|
528 checked: "checked", |
|
529 readonly: "readOnly", |
|
530 selected: "selected" |
|
531 }; |
|
532 |
|
533 // IE actually uses filters for opacity ... elem is actually elem.style |
|
534 if ( name == "opacity" && jQuery.browser.msie && value != undefined ) { |
|
535 // IE has trouble with opacity if it does not have layout |
|
536 // Force it by setting the zoom level |
|
537 elem.zoom = 1; |
|
538 |
|
539 // Set the alpha filter to set the opacity |
|
540 return elem.filter = elem.filter.replace(/alpha\([^\)]*\)/gi,"") + |
|
541 ( value == 1 ? "" : "alpha(opacity=" + value * 100 + ")" ); |
|
542 |
|
543 } else if ( name == "opacity" && jQuery.browser.msie ) |
|
544 return elem.filter ? |
|
545 parseFloat( elem.filter.match(/alpha\(opacity=(.*)\)/)[1] ) / 100 : 1; |
|
546 |
|
547 // Mozilla doesn't play well with opacity 1 |
|
548 if ( name == "opacity" && jQuery.browser.mozilla && value == 1 ) |
|
549 value = 0.9999; |
|
550 |
|
551 |
|
552 // Certain attributes only work when accessed via the old DOM 0 way |
|
553 if ( fix[name] ) { |
|
554 if ( value != undefined ) elem[fix[name]] = value; |
|
555 return elem[fix[name]]; |
|
556 |
|
557 } else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") ) |
|
558 return elem.getAttributeNode(name).nodeValue; |
|
559 |
|
560 // IE elem.getAttribute passes even for style |
|
561 else if ( elem.tagName ) { |
|
562 if ( value != undefined ) elem.setAttribute( name, value ); |
|
563 if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) ) |
|
564 return elem.getAttribute( name, 2 ); |
|
565 return elem.getAttribute( name ); |
|
566 |
|
567 // elem is actually elem.style ... set the style |
|
568 } else { |
|
569 name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();}); |
|
570 if ( value != undefined ) elem[name] = value; |
|
571 return elem[name]; |
|
572 } |
|
573 }, |
|
574 trim: function(t){ |
|
575 return t.replace(/^\s+|\s+$/g, ""); |
|
576 }, |
|
577 |
|
578 makeArray: function( a ) { |
|
579 var r = []; |
|
580 |
|
581 if ( a.constructor != Array ) |
|
582 for ( var i = 0, al = a.length; i < al; i++ ) |
|
583 r.push( a[i] ); |
|
584 else |
|
585 r = a.slice( 0 ); |
|
586 |
|
587 return r; |
|
588 }, |
|
589 |
|
590 inArray: function( b, a ) { |
|
591 for ( var i = 0, al = a.length; i < al; i++ ) |
|
592 if ( a[i] == b ) |
|
593 return i; |
|
594 return -1; |
|
595 }, |
|
596 merge: function(first, second) { |
|
597 var r = [].slice.call( first, 0 ); |
|
598 |
|
599 // Now check for duplicates between the two arrays |
|
600 // and only add the unique items |
|
601 for ( var i = 0, sl = second.length; i < sl; i++ ) |
|
602 // Check for duplicates |
|
603 if ( jQuery.inArray( second[i], r ) == -1 ) |
|
604 // The item is unique, add it |
|
605 first.push( second[i] ); |
|
606 |
|
607 return first; |
|
608 }, |
|
609 grep: function(elems, fn, inv) { |
|
610 // If a string is passed in for the function, make a function |
|
611 // for it (a handy shortcut) |
|
612 if ( typeof fn == "string" ) |
|
613 fn = new Function("a","i","return " + fn); |
|
614 |
|
615 var result = []; |
|
616 |
|
617 // Go through the array, only saving the items |
|
618 // that pass the validator function |
|
619 for ( var i = 0, el = elems.length; i < el; i++ ) |
|
620 if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) ) |
|
621 result.push( elems[i] ); |
|
622 |
|
623 return result; |
|
624 }, |
|
625 map: function(elems, fn) { |
|
626 // If a string is passed in for the function, make a function |
|
627 // for it (a handy shortcut) |
|
628 if ( typeof fn == "string" ) |
|
629 fn = new Function("a","return " + fn); |
|
630 |
|
631 var result = [], r = []; |
|
632 |
|
633 // Go through the array, translating each of the items to their |
|
634 // new value (or values). |
|
635 for ( var i = 0, el = elems.length; i < el; i++ ) { |
|
636 var val = fn(elems[i],i); |
|
637 |
|
638 if ( val !== null && val != undefined ) { |
|
639 if ( val.constructor != Array ) val = [val]; |
|
640 result = result.concat( val ); |
|
641 } |
|
642 } |
|
643 |
|
644 var r = result.length ? [ result[0] ] : []; |
|
645 |
|
646 check: for ( var i = 1, rl = result.length; i < rl; i++ ) { |
|
647 for ( var j = 0; j < i; j++ ) |
|
648 if ( result[i] == r[j] ) |
|
649 continue check; |
|
650 |
|
651 r.push( result[i] ); |
|
652 } |
|
653 |
|
654 return r; |
|
655 } |
|
656 }); |
|
657 |
|
658 /* |
|
659 * Whether the W3C compliant box model is being used. |
|
660 * |
|
661 * @property |
|
662 * @name $.boxModel |
|
663 * @type Boolean |
|
664 * @cat JavaScript |
|
665 */ |
|
666 new function() { |
|
667 var b = navigator.userAgent.toLowerCase(); |
|
668 |
|
669 // Figure out what browser is being used |
|
670 jQuery.browser = { |
|
671 safari: /webkit/.test(b), |
|
672 opera: /opera/.test(b), |
|
673 msie: /msie/.test(b) && !/opera/.test(b), |
|
674 mozilla: /mozilla/.test(b) && !/(compatible|webkit)/.test(b) |
|
675 }; |
|
676 |
|
677 // Check to see if the W3C box model is being used |
|
678 jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat"; |
|
679 }; |
|
680 |
|
681 jQuery.each({ |
|
682 parent: "a.parentNode", |
|
683 parents: "jQuery.parents(a)", |
|
684 next: "jQuery.nth(a,2,'nextSibling')", |
|
685 prev: "jQuery.nth(a,2,'previousSibling')", |
|
686 siblings: "jQuery.sibling(a.parentNode.firstChild,a)", |
|
687 children: "jQuery.sibling(a.firstChild)" |
|
688 }, function(i,n){ |
|
689 jQuery.fn[ i ] = function(a) { |
|
690 var ret = jQuery.map(this,n); |
|
691 if ( a && typeof a == "string" ) |
|
692 ret = jQuery.multiFilter(a,ret); |
|
693 return this.pushStack( ret ); |
|
694 }; |
|
695 }); |
|
696 |
|
697 jQuery.each({ |
|
698 appendTo: "append", |
|
699 prependTo: "prepend", |
|
700 insertBefore: "before", |
|
701 insertAfter: "after" |
|
702 }, function(i,n){ |
|
703 jQuery.fn[ i ] = function(){ |
|
704 var a = arguments; |
|
705 return this.each(function(){ |
|
706 for ( var j = 0, al = a.length; j < al; j++ ) |
|
707 jQuery(a[j])[n]( this ); |
|
708 }); |
|
709 }; |
|
710 }); |
|
711 |
|
712 jQuery.each( { |
|
713 removeAttr: function( key ) { |
|
714 jQuery.attr( this, key, "" ); |
|
715 this.removeAttribute( key ); |
|
716 }, |
|
717 addClass: function(c){ |
|
718 jQuery.className.add(this,c); |
|
719 }, |
|
720 removeClass: function(c){ |
|
721 jQuery.className.remove(this,c); |
|
722 }, |
|
723 toggleClass: function( c ){ |
|
724 jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c); |
|
725 }, |
|
726 remove: function(a){ |
|
727 if ( !a || jQuery.filter( a, [this] ).r.length ) |
|
728 this.parentNode.removeChild( this ); |
|
729 }, |
|
730 empty: function() { |
|
731 while ( this.firstChild ) |
|
732 this.removeChild( this.firstChild ); |
|
733 } |
|
734 }, function(i,n){ |
|
735 jQuery.fn[ i ] = function() { |
|
736 return this.each( n, arguments ); |
|
737 }; |
|
738 }); |
|
739 |
|
740 jQuery.each( [ "eq", "lt", "gt", "contains" ], function(i,n){ |
|
741 jQuery.fn[ n ] = function(num,fn) { |
|
742 return this.filter( ":" + n + "(" + num + ")", fn ); |
|
743 }; |
|
744 }); |
|
745 |
|
746 jQuery.each( [ "height", "width" ], function(i,n){ |
|
747 jQuery.fn[ n ] = function(h) { |
|
748 return h == undefined ? |
|
749 ( this.length ? jQuery.css( this[0], n ) : null ) : |
|
750 this.css( n, h.constructor == String ? h : h + "px" ); |
|
751 }; |
|
752 }); |
|
753 jQuery.extend({ |
|
754 expr: { |
|
755 "": "m[2]=='*'||jQuery.nodeName(a,m[2])", |
|
756 "#": "a.getAttribute('id')==m[2]", |
|
757 ":": { |
|
758 // Position Checks |
|
759 lt: "i<m[3]-0", |
|
760 gt: "i>m[3]-0", |
|
761 nth: "m[3]-0==i", |
|
762 eq: "m[3]-0==i", |
|
763 first: "i==0", |
|
764 last: "i==r.length-1", |
|
765 even: "i%2==0", |
|
766 odd: "i%2", |
|
767 |
|
768 // Child Checks |
|
769 "nth-child": "jQuery.nth(a.parentNode.firstChild,m[3],'nextSibling',a)==a", |
|
770 "first-child": "jQuery.nth(a.parentNode.firstChild,1,'nextSibling')==a", |
|
771 "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a", |
|
772 "only-child": "jQuery.sibling(a.parentNode.firstChild).length==1", |
|
773 |
|
774 // Parent Checks |
|
775 parent: "a.firstChild", |
|
776 empty: "!a.firstChild", |
|
777 |
|
778 // Text Check |
|
779 contains: "jQuery.fn.text.apply([a]).indexOf(m[3])>=0", |
|
780 |
|
781 // Visibility |
|
782 visible: 'a.type!="hidden"&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"', |
|
783 hidden: 'a.type=="hidden"||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"', |
|
784 |
|
785 // Form attributes |
|
786 enabled: "!a.disabled", |
|
787 disabled: "a.disabled", |
|
788 checked: "a.checked", |
|
789 selected: "a.selected||jQuery.attr(a,'selected')", |
|
790 |
|
791 // Form elements |
|
792 text: "a.type=='text'", |
|
793 radio: "a.type=='radio'", |
|
794 checkbox: "a.type=='checkbox'", |
|
795 file: "a.type=='file'", |
|
796 password: "a.type=='password'", |
|
797 submit: "a.type=='submit'", |
|
798 image: "a.type=='image'", |
|
799 reset: "a.type=='reset'", |
|
800 button: 'a.type=="button"||jQuery.nodeName(a,"button")', |
|
801 input: "/input|select|textarea|button/i.test(a.nodeName)" |
|
802 }, |
|
803 ".": "jQuery.className.has(a,m[2])", |
|
804 "@": { |
|
805 "=": "z==m[4]", |
|
806 "!=": "z!=m[4]", |
|
807 "^=": "z&&!z.indexOf(m[4])", |
|
808 "$=": "z&&z.substr(z.length - m[4].length,m[4].length)==m[4]", |
|
809 "*=": "z&&z.indexOf(m[4])>=0", |
|
810 "": "z", |
|
811 _resort: function(m){ |
|
812 return ["", m[1], m[3], m[2], m[5]]; |
|
813 }, |
|
814 _prefix: "z=a[m[3]];if(!z||/href|src/.test(m[3]))z=jQuery.attr(a,m[3]);" |
|
815 }, |
|
816 "[": "jQuery.find(m[2],a).length" |
|
817 }, |
|
818 |
|
819 // The regular expressions that power the parsing engine |
|
820 parse: [ |
|
821 // Match: [@value='test'], [@foo] |
|
822 /^\[ *(@)([a-z0-9_-]*) *([!*$^=]*) *('?"?)(.*?)\4 *\]/i, |
|
823 |
|
824 // Match: [div], [div p] |
|
825 /^(\[)\s*(.*?(\[.*?\])?[^[]*?)\s*\]/, |
|
826 |
|
827 // Match: :contains('foo') |
|
828 /^(:)([a-z0-9_-]*)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/i, |
|
829 |
|
830 // Match: :even, :last-chlid |
|
831 /^([:.#]*)([a-z0-9_*-]*)/i |
|
832 ], |
|
833 |
|
834 token: [ |
|
835 /^(\/?\.\.)/, "a.parentNode", |
|
836 /^(>|\/)/, "jQuery.sibling(a.firstChild)", |
|
837 /^(\+)/, "jQuery.nth(a,2,'nextSibling')", |
|
838 /^(~)/, function(a){ |
|
839 var s = jQuery.sibling(a.parentNode.firstChild); |
|
840 return s.slice(jQuery.inArray(a,s) + 1); |
|
841 } |
|
842 ], |
|
843 |
|
844 multiFilter: function( expr, elems, not ) { |
|
845 var old, cur = []; |
|
846 |
|
847 while ( expr && expr != old ) { |
|
848 old = expr; |
|
849 var f = jQuery.filter( expr, elems, not ); |
|
850 expr = f.t.replace(/^\s*,\s*/, "" ); |
|
851 cur = not ? elems = f.r : jQuery.merge( cur, f.r ); |
|
852 } |
|
853 |
|
854 return cur; |
|
855 }, |
|
856 find: function( t, context ) { |
|
857 // Quickly handle non-string expressions |
|
858 if ( typeof t != "string" ) |
|
859 return [ t ]; |
|
860 |
|
861 // Make sure that the context is a DOM Element |
|
862 if ( context && !context.nodeType ) |
|
863 context = null; |
|
864 |
|
865 // Set the correct context (if none is provided) |
|
866 context = context || document; |
|
867 |
|
868 // Handle the common XPath // expression |
|
869 if ( !t.indexOf("//") ) { |
|
870 context = context.documentElement; |
|
871 t = t.substr(2,t.length); |
|
872 |
|
873 // And the / root expression |
|
874 } else if ( !t.indexOf("/") ) { |
|
875 context = context.documentElement; |
|
876 t = t.substr(1,t.length); |
|
877 if ( t.indexOf("/") >= 1 ) |
|
878 t = t.substr(t.indexOf("/"),t.length); |
|
879 } |
|
880 |
|
881 // Initialize the search |
|
882 var ret = [context], done = [], last = null; |
|
883 |
|
884 // Continue while a selector expression exists, and while |
|
885 // we're no longer looping upon ourselves |
|
886 while ( t && last != t ) { |
|
887 var r = []; |
|
888 last = t; |
|
889 |
|
890 t = jQuery.trim(t).replace( /^\/\//i, "" ); |
|
891 |
|
892 var foundToken = false; |
|
893 |
|
894 // An attempt at speeding up child selectors that |
|
895 // point to a specific element tag |
|
896 var re = /^[\/>]\s*([a-z0-9*-]+)/i; |
|
897 var m = re.exec(t); |
|
898 |
|
899 if ( m ) { |
|
900 // Perform our own iteration and filter |
|
901 jQuery.each( ret, function(){ |
|
902 for ( var c = this.firstChild; c; c = c.nextSibling ) |
|
903 if ( c.nodeType == 1 && ( jQuery.nodeName(c, m[1]) || m[1] == "*" ) ) |
|
904 r.push( c ); |
|
905 }); |
|
906 |
|
907 ret = r; |
|
908 t = t.replace( re, "" ); |
|
909 if ( t.indexOf(" ") == 0 ) continue; |
|
910 foundToken = true; |
|
911 } else { |
|
912 // Look for pre-defined expression tokens |
|
913 for ( var i = 0; i < jQuery.token.length; i += 2 ) { |
|
914 // Attempt to match each, individual, token in |
|
915 // the specified order |
|
916 var re = jQuery.token[i]; |
|
917 var m = re.exec(t); |
|
918 |
|
919 // If the token match was found |
|
920 if ( m ) { |
|
921 // Map it against the token's handler |
|
922 r = ret = jQuery.map( ret, jQuery.isFunction( jQuery.token[i+1] ) ? |
|
923 jQuery.token[i+1] : |
|
924 function(a){ return eval(jQuery.token[i+1]); }); |
|
925 |
|
926 // And remove the token |
|
927 t = jQuery.trim( t.replace( re, "" ) ); |
|
928 foundToken = true; |
|
929 break; |
|
930 } |
|
931 } |
|
932 } |
|
933 |
|
934 // See if there's still an expression, and that we haven't already |
|
935 // matched a token |
|
936 if ( t && !foundToken ) { |
|
937 // Handle multiple expressions |
|
938 if ( !t.indexOf(",") ) { |
|
939 // Clean the result set |
|
940 if ( ret[0] == context ) ret.shift(); |
|
941 |
|
942 // Merge the result sets |
|
943 jQuery.merge( done, ret ); |
|
944 |
|
945 // Reset the context |
|
946 r = ret = [context]; |
|
947 |
|
948 // Touch up the selector string |
|
949 t = " " + t.substr(1,t.length); |
|
950 |
|
951 } else { |
|
952 // Optomize for the case nodeName#idName |
|
953 var re2 = /^([a-z0-9_-]+)(#)([a-z0-9\\*_-]*)/i; |
|
954 var m = re2.exec(t); |
|
955 |
|
956 // Re-organize the results, so that they're consistent |
|
957 if ( m ) { |
|
958 m = [ 0, m[2], m[3], m[1] ]; |
|
959 |
|
960 } else { |
|
961 // Otherwise, do a traditional filter check for |
|
962 // ID, class, and element selectors |
|
963 re2 = /^([#.]?)([a-z0-9\\*_-]*)/i; |
|
964 m = re2.exec(t); |
|
965 } |
|
966 |
|
967 // Try to do a global search by ID, where we can |
|
968 if ( m[1] == "#" && ret[ret.length-1].getElementById ) { |
|
969 // Optimization for HTML document case |
|
970 var oid = ret[ret.length-1].getElementById(m[2]); |
|
971 |
|
972 // Do a quick check for the existence of the actual ID attribute |
|
973 // to avoid selecting by the name attribute in IE |
|
974 if ( jQuery.browser.msie && oid && oid.id != m[2] ) |
|
975 oid = jQuery('[@id="'+m[2]+'"]', ret[ret.length-1])[0]; |
|
976 |
|
977 // Do a quick check for node name (where applicable) so |
|
978 // that div#foo searches will be really fast |
|
979 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; |
|
980 |
|
981 } else { |
|
982 // Pre-compile a regular expression to handle class searches |
|
983 if ( m[1] == "." ) |
|
984 var rec = new RegExp("(^|\\s)" + m[2] + "(\\s|$)"); |
|
985 |
|
986 // We need to find all descendant elements, it is more |
|
987 // efficient to use getAll() when we are already further down |
|
988 // the tree - we try to recognize that here |
|
989 jQuery.each( ret, function(){ |
|
990 // Grab the tag name being searched for |
|
991 var tag = m[1] != "" || m[0] == "" ? "*" : m[2]; |
|
992 |
|
993 // Handle IE7 being really dumb about <object>s |
|
994 if ( jQuery.nodeName(this, "object") && tag == "*" ) |
|
995 tag = "param"; |
|
996 |
|
997 jQuery.merge( r, |
|
998 m[1] != "" && ret.length != 1 ? |
|
999 jQuery.getAll( this, [], m[1], m[2], rec ) : |
|
1000 this.getElementsByTagName( tag ) |
|
1001 ); |
|
1002 }); |
|
1003 |
|
1004 // It's faster to filter by class and be done with it |
|
1005 if ( m[1] == "." && ret.length == 1 ) |
|
1006 r = jQuery.grep( r, function(e) { |
|
1007 return rec.test(e.className); |
|
1008 }); |
|
1009 |
|
1010 // Same with ID filtering |
|
1011 if ( m[1] == "#" && ret.length == 1 ) { |
|
1012 // Remember, then wipe out, the result set |
|
1013 var tmp = r; |
|
1014 r = []; |
|
1015 |
|
1016 // Then try to find the element with the ID |
|
1017 jQuery.each( tmp, function(){ |
|
1018 if ( this.getAttribute("id") == m[2] ) { |
|
1019 r = [ this ]; |
|
1020 return false; |
|
1021 } |
|
1022 }); |
|
1023 } |
|
1024 |
|
1025 ret = r; |
|
1026 } |
|
1027 |
|
1028 t = t.replace( re2, "" ); |
|
1029 } |
|
1030 |
|
1031 } |
|
1032 |
|
1033 // If a selector string still exists |
|
1034 if ( t ) { |
|
1035 // Attempt to filter it |
|
1036 var val = jQuery.filter(t,r); |
|
1037 ret = r = val.r; |
|
1038 t = jQuery.trim(val.t); |
|
1039 } |
|
1040 } |
|
1041 |
|
1042 // Remove the root context |
|
1043 if ( ret && ret[0] == context ) ret.shift(); |
|
1044 |
|
1045 // And combine the results |
|
1046 jQuery.merge( done, ret ); |
|
1047 |
|
1048 return done; |
|
1049 }, |
|
1050 |
|
1051 filter: function(t,r,not) { |
|
1052 // Look for common filter expressions |
|
1053 while ( t && /^[a-z[({<*:.#]/i.test(t) ) { |
|
1054 |
|
1055 var p = jQuery.parse, m; |
|
1056 |
|
1057 jQuery.each( p, function(i,re){ |
|
1058 |
|
1059 // Look for, and replace, string-like sequences |
|
1060 // and finally build a regexp out of it |
|
1061 m = re.exec( t ); |
|
1062 |
|
1063 if ( m ) { |
|
1064 // Remove what we just matched |
|
1065 t = t.substring( m[0].length ); |
|
1066 |
|
1067 // Re-organize the first match |
|
1068 if ( jQuery.expr[ m[1] ]._resort ) |
|
1069 m = jQuery.expr[ m[1] ]._resort( m ); |
|
1070 |
|
1071 return false; |
|
1072 } |
|
1073 }); |
|
1074 |
|
1075 // :not() is a special case that can be optimized by |
|
1076 // keeping it out of the expression list |
|
1077 if ( m[1] == ":" && m[2] == "not" ) |
|
1078 r = jQuery.filter(m[3], r, true).r; |
|
1079 |
|
1080 // Handle classes as a special case (this will help to |
|
1081 // improve the speed, as the regexp will only be compiled once) |
|
1082 else if ( m[1] == "." ) { |
|
1083 |
|
1084 var re = new RegExp("(^|\\s)" + m[2] + "(\\s|$)"); |
|
1085 r = jQuery.grep( r, function(e){ |
|
1086 return re.test(e.className || ""); |
|
1087 }, not); |
|
1088 |
|
1089 // Otherwise, find the expression to execute |
|
1090 } else { |
|
1091 var f = jQuery.expr[m[1]]; |
|
1092 if ( typeof f != "string" ) |
|
1093 f = jQuery.expr[m[1]][m[2]]; |
|
1094 |
|
1095 // Build a custom macro to enclose it |
|
1096 eval("f = function(a,i){" + |
|
1097 ( jQuery.expr[ m[1] ]._prefix || "" ) + |
|
1098 "return " + f + "}"); |
|
1099 |
|
1100 // Execute it against the current filter |
|
1101 r = jQuery.grep( r, f, not ); |
|
1102 } |
|
1103 } |
|
1104 |
|
1105 // Return an array of filtered elements (r) |
|
1106 // and the modified expression string (t) |
|
1107 return { r: r, t: t }; |
|
1108 }, |
|
1109 |
|
1110 getAll: function( o, r, token, name, re ) { |
|
1111 for ( var s = o.firstChild; s; s = s.nextSibling ) |
|
1112 if ( s.nodeType == 1 ) { |
|
1113 var add = true; |
|
1114 |
|
1115 if ( token == "." ) |
|
1116 add = s.className && re.test(s.className); |
|
1117 else if ( token == "#" ) |
|
1118 add = s.getAttribute("id") == name; |
|
1119 |
|
1120 if ( add ) |
|
1121 r.push( s ); |
|
1122 |
|
1123 if ( token == "#" && r.length ) break; |
|
1124 |
|
1125 if ( s.firstChild ) |
|
1126 jQuery.getAll( s, r, token, name, re ); |
|
1127 } |
|
1128 |
|
1129 return r; |
|
1130 }, |
|
1131 parents: function( elem ){ |
|
1132 var matched = []; |
|
1133 var cur = elem.parentNode; |
|
1134 while ( cur && cur != document ) { |
|
1135 matched.push( cur ); |
|
1136 cur = cur.parentNode; |
|
1137 } |
|
1138 return matched; |
|
1139 }, |
|
1140 nth: function(cur,result,dir,elem){ |
|
1141 result = result || 1; |
|
1142 var num = 0; |
|
1143 for ( ; cur; cur = cur[dir] ) { |
|
1144 if ( cur.nodeType == 1 ) num++; |
|
1145 if ( num == result || result == "even" && num % 2 == 0 && num > 1 && cur == elem || |
|
1146 result == "odd" && num % 2 == 1 && cur == elem ) return cur; |
|
1147 } |
|
1148 }, |
|
1149 sibling: function( n, elem ) { |
|
1150 var r = []; |
|
1151 |
|
1152 for ( ; n; n = n.nextSibling ) { |
|
1153 if ( n.nodeType == 1 && (!elem || n != elem) ) |
|
1154 r.push( n ); |
|
1155 } |
|
1156 |
|
1157 return r; |
|
1158 } |
|
1159 }); |
|
1160 /* |
|
1161 * A number of helper functions used for managing events. |
|
1162 * Many of the ideas behind this code orignated from |
|
1163 * Dean Edwards' addEvent library. |
|
1164 */ |
|
1165 jQuery.event = { |
|
1166 |
|
1167 // Bind an event to an element |
|
1168 // Original by Dean Edwards |
|
1169 add: function(element, type, handler, data) { |
|
1170 // For whatever reason, IE has trouble passing the window object |
|
1171 // around, causing it to be cloned in the process |
|
1172 if ( jQuery.browser.msie && element.setInterval != undefined ) |
|
1173 element = window; |
|
1174 |
|
1175 // if data is passed, bind to handler |
|
1176 if( data ) |
|
1177 handler.data = data; |
|
1178 |
|
1179 // Make sure that the function being executed has a unique ID |
|
1180 if ( !handler.guid ) |
|
1181 handler.guid = this.guid++; |
|
1182 |
|
1183 // Init the element's event structure |
|
1184 if (!element.$events) |
|
1185 element.$events = {}; |
|
1186 |
|
1187 // Get the current list of functions bound to this event |
|
1188 var handlers = element.$events[type]; |
|
1189 |
|
1190 // If it hasn't been initialized yet |
|
1191 if (!handlers) { |
|
1192 // Init the event handler queue |
|
1193 handlers = element.$events[type] = {}; |
|
1194 |
|
1195 // Remember an existing handler, if it's already there |
|
1196 if (element["on" + type]) |
|
1197 handlers[0] = element["on" + type]; |
|
1198 } |
|
1199 |
|
1200 // Add the function to the element's handler list |
|
1201 handlers[handler.guid] = handler; |
|
1202 |
|
1203 // And bind the global event handler to the element |
|
1204 element["on" + type] = this.handle; |
|
1205 |
|
1206 // Remember the function in a global list (for triggering) |
|
1207 if (!this.global[type]) |
|
1208 this.global[type] = []; |
|
1209 this.global[type].push( element ); |
|
1210 }, |
|
1211 |
|
1212 guid: 1, |
|
1213 global: {}, |
|
1214 |
|
1215 // Detach an event or set of events from an element |
|
1216 remove: function(element, type, handler) { |
|
1217 if (element.$events) { |
|
1218 var i,j,k; |
|
1219 if ( type && type.type ) { // type is actually an event object here |
|
1220 handler = type.handler; |
|
1221 type = type.type; |
|
1222 } |
|
1223 |
|
1224 if (type && element.$events[type]) |
|
1225 // remove the given handler for the given type |
|
1226 if ( handler ) |
|
1227 delete element.$events[type][handler.guid]; |
|
1228 |
|
1229 // remove all handlers for the given type |
|
1230 else |
|
1231 for ( i in element.$events[type] ) |
|
1232 delete element.$events[type][i]; |
|
1233 |
|
1234 // remove all handlers |
|
1235 else |
|
1236 for ( j in element.$events ) |
|
1237 this.remove( element, j ); |
|
1238 |
|
1239 // remove event handler if no more handlers exist |
|
1240 for ( k in element.$events[type] ) |
|
1241 if (k) { |
|
1242 k = true; |
|
1243 break; |
|
1244 } |
|
1245 if (!k) element["on" + type] = null; |
|
1246 } |
|
1247 }, |
|
1248 |
|
1249 trigger: function(type, data, element) { |
|
1250 // Clone the incoming data, if any |
|
1251 data = jQuery.makeArray(data || []); |
|
1252 |
|
1253 // Handle a global trigger |
|
1254 if ( !element ) |
|
1255 jQuery.each( this.global[type] || [], function(){ |
|
1256 jQuery.event.trigger( type, data, this ); |
|
1257 }); |
|
1258 |
|
1259 // Handle triggering a single element |
|
1260 else { |
|
1261 var handler = element["on" + type ], val, |
|
1262 fn = jQuery.isFunction( element[ type ] ); |
|
1263 |
|
1264 if ( handler ) { |
|
1265 // Pass along a fake event |
|
1266 data.unshift( this.fix({ type: type, target: element }) ); |
|
1267 |
|
1268 // Trigger the event |
|
1269 if ( (val = handler.apply( element, data )) !== false ) |
|
1270 this.triggered = true; |
|
1271 } |
|
1272 |
|
1273 if ( fn && val !== false ) |
|
1274 element[ type ](); |
|
1275 |
|
1276 this.triggered = false; |
|
1277 } |
|
1278 }, |
|
1279 |
|
1280 handle: function(event) { |
|
1281 // Handle the second event of a trigger and when |
|
1282 // an event is called after a page has unloaded |
|
1283 if ( typeof jQuery == "undefined" || jQuery.event.triggered ) return; |
|
1284 |
|
1285 // Empty object is for triggered events with no data |
|
1286 event = jQuery.event.fix( event || window.event || {} ); |
|
1287 |
|
1288 // returned undefined or false |
|
1289 var returnValue; |
|
1290 |
|
1291 var c = this.$events[event.type]; |
|
1292 |
|
1293 var args = [].slice.call( arguments, 1 ); |
|
1294 args.unshift( event ); |
|
1295 |
|
1296 for ( var j in c ) { |
|
1297 // Pass in a reference to the handler function itself |
|
1298 // So that we can later remove it |
|
1299 args[0].handler = c[j]; |
|
1300 args[0].data = c[j].data; |
|
1301 |
|
1302 if ( c[j].apply( this, args ) === false ) { |
|
1303 event.preventDefault(); |
|
1304 event.stopPropagation(); |
|
1305 returnValue = false; |
|
1306 } |
|
1307 } |
|
1308 |
|
1309 // Clean up added properties in IE to prevent memory leak |
|
1310 if (jQuery.browser.msie) event.target = event.preventDefault = event.stopPropagation = event.handler = event.data = null; |
|
1311 |
|
1312 return returnValue; |
|
1313 }, |
|
1314 |
|
1315 fix: function(event) { |
|
1316 // Fix target property, if necessary |
|
1317 if ( !event.target && event.srcElement ) |
|
1318 event.target = event.srcElement; |
|
1319 |
|
1320 // Calculate pageX/Y if missing and clientX/Y available |
|
1321 if ( event.pageX == undefined && event.clientX != undefined ) { |
|
1322 var e = document.documentElement, b = document.body; |
|
1323 event.pageX = event.clientX + (e.scrollLeft || b.scrollLeft); |
|
1324 event.pageY = event.clientY + (e.scrollTop || b.scrollTop); |
|
1325 } |
|
1326 |
|
1327 // check if target is a textnode (safari) |
|
1328 if (jQuery.browser.safari && event.target.nodeType == 3) { |
|
1329 // store a copy of the original event object |
|
1330 // and clone because target is read only |
|
1331 var originalEvent = event; |
|
1332 event = jQuery.extend({}, originalEvent); |
|
1333 |
|
1334 // get parentnode from textnode |
|
1335 event.target = originalEvent.target.parentNode; |
|
1336 |
|
1337 // add preventDefault and stopPropagation since |
|
1338 // they will not work on the clone |
|
1339 event.preventDefault = function() { |
|
1340 return originalEvent.preventDefault(); |
|
1341 }; |
|
1342 event.stopPropagation = function() { |
|
1343 return originalEvent.stopPropagation(); |
|
1344 }; |
|
1345 } |
|
1346 |
|
1347 // fix preventDefault and stopPropagation |
|
1348 if (!event.preventDefault) |
|
1349 event.preventDefault = function() { |
|
1350 this.returnValue = false; |
|
1351 }; |
|
1352 |
|
1353 if (!event.stopPropagation) |
|
1354 event.stopPropagation = function() { |
|
1355 this.cancelBubble = true; |
|
1356 }; |
|
1357 |
|
1358 return event; |
|
1359 } |
|
1360 }; |
|
1361 |
|
1362 jQuery.fn.extend({ |
|
1363 bind: function( type, data, fn ) { |
|
1364 return this.each(function(){ |
|
1365 jQuery.event.add( this, type, fn || data, data ); |
|
1366 }); |
|
1367 }, |
|
1368 one: function( type, data, fn ) { |
|
1369 return this.each(function(){ |
|
1370 jQuery.event.add( this, type, function(event) { |
|
1371 jQuery(this).unbind(event); |
|
1372 return (fn || data).apply( this, arguments); |
|
1373 }, data); |
|
1374 }); |
|
1375 }, |
|
1376 unbind: function( type, fn ) { |
|
1377 return this.each(function(){ |
|
1378 jQuery.event.remove( this, type, fn ); |
|
1379 }); |
|
1380 }, |
|
1381 trigger: function( type, data ) { |
|
1382 return this.each(function(){ |
|
1383 jQuery.event.trigger( type, data, this ); |
|
1384 }); |
|
1385 }, |
|
1386 toggle: function() { |
|
1387 // Save reference to arguments for access in closure |
|
1388 var a = arguments; |
|
1389 |
|
1390 return this.click(function(e) { |
|
1391 // Figure out which function to execute |
|
1392 this.lastToggle = this.lastToggle == 0 ? 1 : 0; |
|
1393 |
|
1394 // Make sure that clicks stop |
|
1395 e.preventDefault(); |
|
1396 |
|
1397 // and execute the function |
|
1398 return a[this.lastToggle].apply( this, [e] ) || false; |
|
1399 }); |
|
1400 }, |
|
1401 hover: function(f,g) { |
|
1402 |
|
1403 // A private function for handling mouse 'hovering' |
|
1404 function handleHover(e) { |
|
1405 // Check if mouse(over|out) are still within the same parent element |
|
1406 var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget; |
|
1407 |
|
1408 // Traverse up the tree |
|
1409 while ( p && p != this ) try { p = p.parentNode } catch(e) { p = this; }; |
|
1410 |
|
1411 // If we actually just moused on to a sub-element, ignore it |
|
1412 if ( p == this ) return false; |
|
1413 |
|
1414 // Execute the right function |
|
1415 return (e.type == "mouseover" ? f : g).apply(this, [e]); |
|
1416 } |
|
1417 |
|
1418 // Bind the function to the two event listeners |
|
1419 return this.mouseover(handleHover).mouseout(handleHover); |
|
1420 }, |
|
1421 ready: function(f) { |
|
1422 // If the DOM is already ready |
|
1423 if ( jQuery.isReady ) |
|
1424 // Execute the function immediately |
|
1425 f.apply( document, [jQuery] ); |
|
1426 |
|
1427 // Otherwise, remember the function for later |
|
1428 else { |
|
1429 // Add the function to the wait list |
|
1430 jQuery.readyList.push( function() { return f.apply(this, [jQuery]) } ); |
|
1431 } |
|
1432 |
|
1433 return this; |
|
1434 } |
|
1435 }); |
|
1436 |
|
1437 jQuery.extend({ |
|
1438 /* |
|
1439 * All the code that makes DOM Ready work nicely. |
|
1440 */ |
|
1441 isReady: false, |
|
1442 readyList: [], |
|
1443 |
|
1444 // Handle when the DOM is ready |
|
1445 ready: function() { |
|
1446 // Make sure that the DOM is not already loaded |
|
1447 if ( !jQuery.isReady ) { |
|
1448 // Remember that the DOM is ready |
|
1449 jQuery.isReady = true; |
|
1450 |
|
1451 // If there are functions bound, to execute |
|
1452 if ( jQuery.readyList ) { |
|
1453 // Execute all of them |
|
1454 jQuery.each( jQuery.readyList, function(){ |
|
1455 this.apply( document ); |
|
1456 }); |
|
1457 |
|
1458 // Reset the list of functions |
|
1459 jQuery.readyList = null; |
|
1460 } |
|
1461 // Remove event lisenter to avoid memory leak |
|
1462 if ( jQuery.browser.mozilla || jQuery.browser.opera ) |
|
1463 document.removeEventListener( "DOMContentLoaded", jQuery.ready, false ); |
|
1464 } |
|
1465 } |
|
1466 }); |
|
1467 |
|
1468 new function(){ |
|
1469 |
|
1470 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + |
|
1471 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + |
|
1472 "submit,keydown,keypress,keyup,error").split(","), function(i,o){ |
|
1473 |
|
1474 // Handle event binding |
|
1475 jQuery.fn[o] = function(f){ |
|
1476 return f ? this.bind(o, f) : this.trigger(o); |
|
1477 }; |
|
1478 |
|
1479 }); |
|
1480 |
|
1481 // If Mozilla is used |
|
1482 if ( jQuery.browser.mozilla || jQuery.browser.opera ) |
|
1483 // Use the handy event callback |
|
1484 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); |
|
1485 |
|
1486 // If IE is used, use the excellent hack by Matthias Miller |
|
1487 // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited |
|
1488 else if ( jQuery.browser.msie ) { |
|
1489 |
|
1490 // Only works if you document.write() it |
|
1491 document.write("<scr" + "ipt id=__ie_init defer=true " + |
|
1492 "src=//:><\/script>"); |
|
1493 |
|
1494 // Use the defer script hack |
|
1495 var script = document.getElementById("__ie_init"); |
|
1496 |
|
1497 // script does not exist if jQuery is loaded dynamically |
|
1498 if ( script ) |
|
1499 script.onreadystatechange = function() { |
|
1500 if ( this.readyState != "complete" ) return; |
|
1501 this.parentNode.removeChild( this ); |
|
1502 jQuery.ready(); |
|
1503 }; |
|
1504 |
|
1505 // Clear from memory |
|
1506 script = null; |
|
1507 |
|
1508 // If Safari is used |
|
1509 } else if ( jQuery.browser.safari ) |
|
1510 // Continually check to see if the document.readyState is valid |
|
1511 jQuery.safariTimer = setInterval(function(){ |
|
1512 // loaded and complete are both valid states |
|
1513 if ( document.readyState == "loaded" || |
|
1514 document.readyState == "complete" ) { |
|
1515 |
|
1516 // If either one are found, remove the timer |
|
1517 clearInterval( jQuery.safariTimer ); |
|
1518 jQuery.safariTimer = null; |
|
1519 |
|
1520 // and execute any waiting functions |
|
1521 jQuery.ready(); |
|
1522 } |
|
1523 }, 10); |
|
1524 |
|
1525 // A fallback to window.onload, that will always work |
|
1526 jQuery.event.add( window, "load", jQuery.ready ); |
|
1527 |
|
1528 }; |
|
1529 |
|
1530 // Clean up after IE to avoid memory leaks |
|
1531 if (jQuery.browser.msie) |
|
1532 jQuery(window).one("unload", function() { |
|
1533 var global = jQuery.event.global; |
|
1534 for ( var type in global ) { |
|
1535 var els = global[type], i = els.length; |
|
1536 if ( i && type != 'unload' ) |
|
1537 do |
|
1538 jQuery.event.remove(els[i-1], type); |
|
1539 while (--i); |
|
1540 } |
|
1541 }); |
|
1542 jQuery.fn.extend({ |
|
1543 loadIfModified: function( url, params, callback ) { |
|
1544 this.load( url, params, callback, 1 ); |
|
1545 }, |
|
1546 load: function( url, params, callback, ifModified ) { |
|
1547 if ( jQuery.isFunction( url ) ) |
|
1548 return this.bind("load", url); |
|
1549 |
|
1550 callback = callback || function(){}; |
|
1551 |
|
1552 // Default to a GET request |
|
1553 var type = "GET"; |
|
1554 |
|
1555 // If the second parameter was provided |
|
1556 if ( params ) |
|
1557 // If it's a function |
|
1558 if ( jQuery.isFunction( params ) ) { |
|
1559 // We assume that it's the callback |
|
1560 callback = params; |
|
1561 params = null; |
|
1562 |
|
1563 // Otherwise, build a param string |
|
1564 } else { |
|
1565 params = jQuery.param( params ); |
|
1566 type = "POST"; |
|
1567 } |
|
1568 |
|
1569 var self = this; |
|
1570 |
|
1571 // Request the remote document |
|
1572 jQuery.ajax({ |
|
1573 url: url, |
|
1574 type: type, |
|
1575 data: params, |
|
1576 ifModified: ifModified, |
|
1577 complete: function(res, status){ |
|
1578 if ( status == "success" || !ifModified && status == "notmodified" ) |
|
1579 // Inject the HTML into all the matched elements |
|
1580 self.attr("innerHTML", res.responseText) |
|
1581 // Execute all the scripts inside of the newly-injected HTML |
|
1582 .evalScripts() |
|
1583 // Execute callback |
|
1584 .each( callback, [res.responseText, status, res] ); |
|
1585 else |
|
1586 callback.apply( self, [res.responseText, status, res] ); |
|
1587 } |
|
1588 }); |
|
1589 return this; |
|
1590 }, |
|
1591 serialize: function() { |
|
1592 return jQuery.param( this ); |
|
1593 }, |
|
1594 evalScripts: function() { |
|
1595 return this.find("script").each(function(){ |
|
1596 if ( this.src ) |
|
1597 jQuery.getScript( this.src ); |
|
1598 else |
|
1599 jQuery.globalEval( this.text || this.textContent || this.innerHTML || "" ); |
|
1600 }).end(); |
|
1601 } |
|
1602 |
|
1603 }); |
|
1604 |
|
1605 // If IE is used, create a wrapper for the XMLHttpRequest object |
|
1606 if ( !window.XMLHttpRequest ) |
|
1607 XMLHttpRequest = function(){ |
|
1608 return new ActiveXObject("Microsoft.XMLHTTP"); |
|
1609 }; |
|
1610 |
|
1611 // Attach a bunch of functions for handling common AJAX events |
|
1612 |
|
1613 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ |
|
1614 jQuery.fn[o] = function(f){ |
|
1615 return this.bind(o, f); |
|
1616 }; |
|
1617 }); |
|
1618 |
|
1619 jQuery.extend({ |
|
1620 get: function( url, data, callback, type, ifModified ) { |
|
1621 // shift arguments if data argument was ommited |
|
1622 if ( jQuery.isFunction( data ) ) { |
|
1623 callback = data; |
|
1624 data = null; |
|
1625 } |
|
1626 |
|
1627 return jQuery.ajax({ |
|
1628 url: url, |
|
1629 data: data, |
|
1630 success: callback, |
|
1631 dataType: type, |
|
1632 ifModified: ifModified |
|
1633 }); |
|
1634 }, |
|
1635 getIfModified: function( url, data, callback, type ) { |
|
1636 return jQuery.get(url, data, callback, type, 1); |
|
1637 }, |
|
1638 getScript: function( url, callback ) { |
|
1639 return jQuery.get(url, null, callback, "script"); |
|
1640 }, |
|
1641 getJSON: function( url, data, callback ) { |
|
1642 return jQuery.get(url, data, callback, "json"); |
|
1643 }, |
|
1644 post: function( url, data, callback, type ) { |
|
1645 if ( jQuery.isFunction( data ) ) { |
|
1646 callback = data; |
|
1647 data = {}; |
|
1648 } |
|
1649 |
|
1650 return jQuery.ajax({ |
|
1651 type: "POST", |
|
1652 url: url, |
|
1653 data: data, |
|
1654 success: callback, |
|
1655 dataType: type |
|
1656 }); |
|
1657 }, |
|
1658 |
|
1659 // timeout (ms) |
|
1660 //timeout: 0, |
|
1661 ajaxTimeout: function( timeout ) { |
|
1662 jQuery.ajaxSettings.timeout = timeout; |
|
1663 }, |
|
1664 ajaxSetup: function( settings ) { |
|
1665 jQuery.extend( jQuery.ajaxSettings, settings ); |
|
1666 }, |
|
1667 |
|
1668 ajaxSettings: { |
|
1669 global: true, |
|
1670 type: "GET", |
|
1671 timeout: 0, |
|
1672 contentType: "application/x-www-form-urlencoded", |
|
1673 processData: true, |
|
1674 async: true, |
|
1675 data: null |
|
1676 }, |
|
1677 |
|
1678 // Last-Modified header cache for next request |
|
1679 lastModified: {}, |
|
1680 ajax: function( s ) { |
|
1681 // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout |
|
1682 s = jQuery.extend({}, jQuery.ajaxSettings, s); |
|
1683 |
|
1684 // if data available |
|
1685 if ( s.data ) { |
|
1686 // convert data if not already a string |
|
1687 if (s.processData && typeof s.data != "string") |
|
1688 s.data = jQuery.param(s.data); |
|
1689 // append data to url for get requests |
|
1690 if( s.type.toLowerCase() == "get" ) { |
|
1691 // "?" + data or "&" + data (in case there are already params) |
|
1692 s.url += ((s.url.indexOf("?") > -1) ? "&" : "?") + s.data; |
|
1693 // IE likes to send both get and post data, prevent this |
|
1694 s.data = null; |
|
1695 } |
|
1696 } |
|
1697 |
|
1698 // Watch for a new set of requests |
|
1699 if ( s.global && ! jQuery.active++ ) |
|
1700 jQuery.event.trigger( "ajaxStart" ); |
|
1701 |
|
1702 var requestDone = false; |
|
1703 |
|
1704 // Create the request object |
|
1705 var xml = new XMLHttpRequest(); |
|
1706 |
|
1707 // Open the socket |
|
1708 xml.open(s.type, s.url, s.async); |
|
1709 |
|
1710 // Set the correct header, if data is being sent |
|
1711 if ( s.data ) |
|
1712 xml.setRequestHeader("Content-Type", s.contentType); |
|
1713 |
|
1714 // Set the If-Modified-Since header, if ifModified mode. |
|
1715 if ( s.ifModified ) |
|
1716 xml.setRequestHeader("If-Modified-Since", |
|
1717 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); |
|
1718 |
|
1719 // Set header so the called script knows that it's an XMLHttpRequest |
|
1720 xml.setRequestHeader("X-Requested-With", "XMLHttpRequest"); |
|
1721 |
|
1722 // Make sure the browser sends the right content length |
|
1723 if ( xml.overrideMimeType ) |
|
1724 xml.setRequestHeader("Connection", "close"); |
|
1725 |
|
1726 // Allow custom headers/mimetypes |
|
1727 if( s.beforeSend ) |
|
1728 s.beforeSend(xml); |
|
1729 |
|
1730 if ( s.global ) |
|
1731 jQuery.event.trigger("ajaxSend", [xml, s]); |
|
1732 |
|
1733 // Wait for a response to come back |
|
1734 var onreadystatechange = function(isTimeout){ |
|
1735 // The transfer is complete and the data is available, or the request timed out |
|
1736 if ( xml && (xml.readyState == 4 || isTimeout == "timeout") ) { |
|
1737 requestDone = true; |
|
1738 |
|
1739 // clear poll interval |
|
1740 if (ival) { |
|
1741 clearInterval(ival); |
|
1742 ival = null; |
|
1743 } |
|
1744 |
|
1745 var status; |
|
1746 try { |
|
1747 status = jQuery.httpSuccess( xml ) && isTimeout != "timeout" ? |
|
1748 s.ifModified && jQuery.httpNotModified( xml, s.url ) ? "notmodified" : "success" : "error"; |
|
1749 // Make sure that the request was successful or notmodified |
|
1750 if ( status != "error" ) { |
|
1751 // Cache Last-Modified header, if ifModified mode. |
|
1752 var modRes; |
|
1753 try { |
|
1754 modRes = xml.getResponseHeader("Last-Modified"); |
|
1755 } catch(e) {} // swallow exception thrown by FF if header is not available |
|
1756 |
|
1757 if ( s.ifModified && modRes ) |
|
1758 jQuery.lastModified[s.url] = modRes; |
|
1759 |
|
1760 // process the data (runs the xml through httpData regardless of callback) |
|
1761 var data = jQuery.httpData( xml, s.dataType ); |
|
1762 |
|
1763 // If a local callback was specified, fire it and pass it the data |
|
1764 if ( s.success ) |
|
1765 s.success( data, status ); |
|
1766 |
|
1767 // Fire the global callback |
|
1768 if( s.global ) |
|
1769 jQuery.event.trigger( "ajaxSuccess", [xml, s] ); |
|
1770 } else |
|
1771 jQuery.handleError(s, xml, status); |
|
1772 } catch(e) { |
|
1773 status = "error"; |
|
1774 jQuery.handleError(s, xml, status, e); |
|
1775 } |
|
1776 |
|
1777 // The request was completed |
|
1778 if( s.global ) |
|
1779 jQuery.event.trigger( "ajaxComplete", [xml, s] ); |
|
1780 |
|
1781 // Handle the global AJAX counter |
|
1782 if ( s.global && ! --jQuery.active ) |
|
1783 jQuery.event.trigger( "ajaxStop" ); |
|
1784 |
|
1785 // Process result |
|
1786 if ( s.complete ) |
|
1787 s.complete(xml, status); |
|
1788 |
|
1789 // Stop memory leaks |
|
1790 if(s.async) |
|
1791 xml = null; |
|
1792 } |
|
1793 }; |
|
1794 |
|
1795 // don't attach the handler to the request, just poll it instead |
|
1796 var ival = setInterval(onreadystatechange, 13); |
|
1797 |
|
1798 // Timeout checker |
|
1799 if ( s.timeout > 0 ) |
|
1800 setTimeout(function(){ |
|
1801 // Check to see if the request is still happening |
|
1802 if ( xml ) { |
|
1803 // Cancel the request |
|
1804 xml.abort(); |
|
1805 |
|
1806 if( !requestDone ) |
|
1807 onreadystatechange( "timeout" ); |
|
1808 } |
|
1809 }, s.timeout); |
|
1810 |
|
1811 // Send the data |
|
1812 try { |
|
1813 xml.send(s.data); |
|
1814 } catch(e) { |
|
1815 jQuery.handleError(s, xml, null, e); |
|
1816 } |
|
1817 |
|
1818 // firefox 1.5 doesn't fire statechange for sync requests |
|
1819 if ( !s.async ) |
|
1820 onreadystatechange(); |
|
1821 |
|
1822 // return XMLHttpRequest to allow aborting the request etc. |
|
1823 return xml; |
|
1824 }, |
|
1825 |
|
1826 handleError: function( s, xml, status, e ) { |
|
1827 // If a local callback was specified, fire it |
|
1828 if ( s.error ) s.error( xml, status, e ); |
|
1829 |
|
1830 // Fire the global callback |
|
1831 if ( s.global ) |
|
1832 jQuery.event.trigger( "ajaxError", [xml, s, e] ); |
|
1833 }, |
|
1834 |
|
1835 // Counter for holding the number of active queries |
|
1836 active: 0, |
|
1837 |
|
1838 // Determines if an XMLHttpRequest was successful or not |
|
1839 httpSuccess: function( r ) { |
|
1840 try { |
|
1841 return !r.status && location.protocol == "file:" || |
|
1842 ( r.status >= 200 && r.status < 300 ) || r.status == 304 || |
|
1843 jQuery.browser.safari && r.status == undefined; |
|
1844 } catch(e){} |
|
1845 return false; |
|
1846 }, |
|
1847 |
|
1848 // Determines if an XMLHttpRequest returns NotModified |
|
1849 httpNotModified: function( xml, url ) { |
|
1850 try { |
|
1851 var xmlRes = xml.getResponseHeader("Last-Modified"); |
|
1852 |
|
1853 // Firefox always returns 200. check Last-Modified date |
|
1854 return xml.status == 304 || xmlRes == jQuery.lastModified[url] || |
|
1855 jQuery.browser.safari && xml.status == undefined; |
|
1856 } catch(e){} |
|
1857 return false; |
|
1858 }, |
|
1859 |
|
1860 /* Get the data out of an XMLHttpRequest. |
|
1861 * Return parsed XML if content-type header is "xml" and type is "xml" or omitted, |
|
1862 * otherwise return plain text. |
|
1863 * (String) data - The type of data that you're expecting back, |
|
1864 * (e.g. "xml", "html", "script") |
|
1865 */ |
|
1866 httpData: function( r, type ) { |
|
1867 var ct = r.getResponseHeader("content-type"); |
|
1868 var data = !type && ct && ct.indexOf("xml") >= 0; |
|
1869 data = type == "xml" || data ? r.responseXML : r.responseText; |
|
1870 |
|
1871 // If the type is "script", eval it in global context |
|
1872 if ( type == "script" ) |
|
1873 jQuery.globalEval( data ); |
|
1874 |
|
1875 // Get the JavaScript object, if JSON is used. |
|
1876 if ( type == "json" ) |
|
1877 eval( "data = " + data ); |
|
1878 |
|
1879 // evaluate scripts within html |
|
1880 if ( type == "html" ) |
|
1881 jQuery("<div>").html(data).evalScripts(); |
|
1882 |
|
1883 return data; |
|
1884 }, |
|
1885 |
|
1886 // Serialize an array of form elements or a set of |
|
1887 // key/values into a query string |
|
1888 param: function( a ) { |
|
1889 var s = []; |
|
1890 |
|
1891 // If an array was passed in, assume that it is an array |
|
1892 // of form elements |
|
1893 if ( a.constructor == Array || a.jquery ) |
|
1894 // Serialize the form elements |
|
1895 jQuery.each( a, function(){ |
|
1896 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) ); |
|
1897 }); |
|
1898 |
|
1899 // Otherwise, assume that it's an object of key/value pairs |
|
1900 else |
|
1901 // Serialize the key/values |
|
1902 for ( var j in a ) |
|
1903 // If the value is an array then the key names need to be repeated |
|
1904 if ( a[j] && a[j].constructor == Array ) |
|
1905 jQuery.each( a[j], function(){ |
|
1906 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); |
|
1907 }); |
|
1908 else |
|
1909 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) ); |
|
1910 |
|
1911 // Return the resulting serialization |
|
1912 return s.join("&"); |
|
1913 }, |
|
1914 |
|
1915 // evalulates a script in global context |
|
1916 // not reliable for safari |
|
1917 globalEval: function( data ) { |
|
1918 if ( window.execScript ) |
|
1919 window.execScript( data ); |
|
1920 else if ( jQuery.browser.safari ) |
|
1921 // safari doesn't provide a synchronous global eval |
|
1922 window.setTimeout( data, 0 ); |
|
1923 else |
|
1924 eval.call( window, data ); |
|
1925 } |
|
1926 |
|
1927 }); |
|
1928 jQuery.fn.extend({ |
|
1929 |
|
1930 show: function(speed,callback){ |
|
1931 var hidden = this.filter(":hidden"); |
|
1932 speed ? |
|
1933 hidden.animate({ |
|
1934 height: "show", width: "show", opacity: "show" |
|
1935 }, speed, callback) : |
|
1936 |
|
1937 hidden.each(function(){ |
|
1938 this.style.display = this.oldblock ? this.oldblock : ""; |
|
1939 if ( jQuery.css(this,"display") == "none" ) |
|
1940 this.style.display = "block"; |
|
1941 }); |
|
1942 return this; |
|
1943 }, |
|
1944 |
|
1945 hide: function(speed,callback){ |
|
1946 var visible = this.filter(":visible"); |
|
1947 speed ? |
|
1948 visible.animate({ |
|
1949 height: "hide", width: "hide", opacity: "hide" |
|
1950 }, speed, callback) : |
|
1951 |
|
1952 visible.each(function(){ |
|
1953 this.oldblock = this.oldblock || jQuery.css(this,"display"); |
|
1954 if ( this.oldblock == "none" ) |
|
1955 this.oldblock = "block"; |
|
1956 this.style.display = "none"; |
|
1957 }); |
|
1958 return this; |
|
1959 }, |
|
1960 |
|
1961 // Save the old toggle function |
|
1962 _toggle: jQuery.fn.toggle, |
|
1963 toggle: function( fn, fn2 ){ |
|
1964 var args = arguments; |
|
1965 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? |
|
1966 this._toggle( fn, fn2 ) : |
|
1967 this.each(function(){ |
|
1968 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ] |
|
1969 .apply( jQuery(this), args ); |
|
1970 }); |
|
1971 }, |
|
1972 slideDown: function(speed,callback){ |
|
1973 return this.animate({height: "show"}, speed, callback); |
|
1974 }, |
|
1975 slideUp: function(speed,callback){ |
|
1976 return this.animate({height: "hide"}, speed, callback); |
|
1977 }, |
|
1978 slideToggle: function(speed, callback){ |
|
1979 return this.each(function(){ |
|
1980 var state = jQuery(this).is(":hidden") ? "show" : "hide"; |
|
1981 jQuery(this).animate({height: state}, speed, callback); |
|
1982 }); |
|
1983 }, |
|
1984 fadeIn: function(speed, callback){ |
|
1985 return this.animate({opacity: "show"}, speed, callback); |
|
1986 }, |
|
1987 fadeOut: function(speed, callback){ |
|
1988 return this.animate({opacity: "hide"}, speed, callback); |
|
1989 }, |
|
1990 fadeTo: function(speed,to,callback){ |
|
1991 return this.animate({opacity: to}, speed, callback); |
|
1992 }, |
|
1993 animate: function( prop, speed, easing, callback ) { |
|
1994 return this.queue(function(){ |
|
1995 |
|
1996 this.curAnim = jQuery.extend({}, prop); |
|
1997 var opt = jQuery.speed(speed, easing, callback); |
|
1998 |
|
1999 for ( var p in prop ) { |
|
2000 var e = new jQuery.fx( this, opt, p ); |
|
2001 if ( prop[p].constructor == Number ) |
|
2002 e.custom( e.cur(), prop[p] ); |
|
2003 else |
|
2004 e[ prop[p] ]( prop ); |
|
2005 } |
|
2006 |
|
2007 }); |
|
2008 }, |
|
2009 queue: function(type,fn){ |
|
2010 if ( !fn ) { |
|
2011 fn = type; |
|
2012 type = "fx"; |
|
2013 } |
|
2014 |
|
2015 return this.each(function(){ |
|
2016 if ( !this.queue ) |
|
2017 this.queue = {}; |
|
2018 |
|
2019 if ( !this.queue[type] ) |
|
2020 this.queue[type] = []; |
|
2021 |
|
2022 this.queue[type].push( fn ); |
|
2023 |
|
2024 if ( this.queue[type].length == 1 ) |
|
2025 fn.apply(this); |
|
2026 }); |
|
2027 } |
|
2028 |
|
2029 }); |
|
2030 |
|
2031 jQuery.extend({ |
|
2032 |
|
2033 speed: function(speed, easing, fn) { |
|
2034 var opt = speed && speed.constructor == Object ? speed : { |
|
2035 complete: fn || !fn && easing || |
|
2036 jQuery.isFunction( speed ) && speed, |
|
2037 duration: speed, |
|
2038 easing: fn && easing || easing && easing.constructor != Function && easing |
|
2039 }; |
|
2040 |
|
2041 opt.duration = (opt.duration && opt.duration.constructor == Number ? |
|
2042 opt.duration : |
|
2043 { slow: 600, fast: 200 }[opt.duration]) || 400; |
|
2044 |
|
2045 // Queueing |
|
2046 opt.old = opt.complete; |
|
2047 opt.complete = function(){ |
|
2048 jQuery.dequeue(this, "fx"); |
|
2049 if ( jQuery.isFunction( opt.old ) ) |
|
2050 opt.old.apply( this ); |
|
2051 }; |
|
2052 |
|
2053 return opt; |
|
2054 }, |
|
2055 |
|
2056 easing: {}, |
|
2057 |
|
2058 queue: {}, |
|
2059 |
|
2060 dequeue: function(elem,type){ |
|
2061 type = type || "fx"; |
|
2062 |
|
2063 if ( elem.queue && elem.queue[type] ) { |
|
2064 // Remove self |
|
2065 elem.queue[type].shift(); |
|
2066 |
|
2067 // Get next function |
|
2068 var f = elem.queue[type][0]; |
|
2069 |
|
2070 if ( f ) f.apply( elem ); |
|
2071 } |
|
2072 }, |
|
2073 |
|
2074 /* |
|
2075 * I originally wrote fx() as a clone of moo.fx and in the process |
|
2076 * of making it small in size the code became illegible to sane |
|
2077 * people. You've been warned. |
|
2078 */ |
|
2079 |
|
2080 fx: function( elem, options, prop ){ |
|
2081 |
|
2082 var z = this; |
|
2083 |
|
2084 // The styles |
|
2085 var y = elem.style; |
|
2086 |
|
2087 // Store display property |
|
2088 var oldDisplay = jQuery.css(elem, "display"); |
|
2089 |
|
2090 // Make sure that nothing sneaks out |
|
2091 y.overflow = "hidden"; |
|
2092 |
|
2093 // Simple function for setting a style value |
|
2094 z.a = function(){ |
|
2095 if ( options.step ) |
|
2096 options.step.apply( elem, [ z.now ] ); |
|
2097 |
|
2098 if ( prop == "opacity" ) |
|
2099 jQuery.attr(y, "opacity", z.now); // Let attr handle opacity |
|
2100 else if ( parseInt(z.now) ) // My hate for IE will never die |
|
2101 y[prop] = parseInt(z.now) + "px"; |
|
2102 |
|
2103 y.display = "block"; // Set display property to block for animation |
|
2104 }; |
|
2105 |
|
2106 // Figure out the maximum number to run to |
|
2107 z.max = function(){ |
|
2108 return parseFloat( jQuery.css(elem,prop) ); |
|
2109 }; |
|
2110 |
|
2111 // Get the current size |
|
2112 z.cur = function(){ |
|
2113 var r = parseFloat( jQuery.curCSS(elem, prop) ); |
|
2114 return r && r > -10000 ? r : z.max(); |
|
2115 }; |
|
2116 |
|
2117 // Start an animation from one number to another |
|
2118 z.custom = function(from,to){ |
|
2119 z.startTime = (new Date()).getTime(); |
|
2120 z.now = from; |
|
2121 z.a(); |
|
2122 |
|
2123 z.timer = setInterval(function(){ |
|
2124 z.step(from, to); |
|
2125 }, 13); |
|
2126 }; |
|
2127 |
|
2128 // Simple 'show' function |
|
2129 z.show = function(){ |
|
2130 if ( !elem.orig ) elem.orig = {}; |
|
2131 |
|
2132 // Remember where we started, so that we can go back to it later |
|
2133 elem.orig[prop] = this.cur(); |
|
2134 |
|
2135 options.show = true; |
|
2136 |
|
2137 // Begin the animation |
|
2138 z.custom(0, elem.orig[prop]); |
|
2139 |
|
2140 // Stupid IE, look what you made me do |
|
2141 if ( prop != "opacity" ) |
|
2142 y[prop] = "1px"; |
|
2143 }; |
|
2144 |
|
2145 // Simple 'hide' function |
|
2146 z.hide = function(){ |
|
2147 if ( !elem.orig ) elem.orig = {}; |
|
2148 |
|
2149 // Remember where we started, so that we can go back to it later |
|
2150 elem.orig[prop] = this.cur(); |
|
2151 |
|
2152 options.hide = true; |
|
2153 |
|
2154 // Begin the animation |
|
2155 z.custom(elem.orig[prop], 0); |
|
2156 }; |
|
2157 |
|
2158 //Simple 'toggle' function |
|
2159 z.toggle = function() { |
|
2160 if ( !elem.orig ) elem.orig = {}; |
|
2161 |
|
2162 // Remember where we started, so that we can go back to it later |
|
2163 elem.orig[prop] = this.cur(); |
|
2164 |
|
2165 if(oldDisplay == "none") { |
|
2166 options.show = true; |
|
2167 |
|
2168 // Stupid IE, look what you made me do |
|
2169 if ( prop != "opacity" ) |
|
2170 y[prop] = "1px"; |
|
2171 |
|
2172 // Begin the animation |
|
2173 z.custom(0, elem.orig[prop]); |
|
2174 } else { |
|
2175 options.hide = true; |
|
2176 |
|
2177 // Begin the animation |
|
2178 z.custom(elem.orig[prop], 0); |
|
2179 } |
|
2180 }; |
|
2181 |
|
2182 // Each step of an animation |
|
2183 z.step = function(firstNum, lastNum){ |
|
2184 var t = (new Date()).getTime(); |
|
2185 |
|
2186 if (t > options.duration + z.startTime) { |
|
2187 // Stop the timer |
|
2188 clearInterval(z.timer); |
|
2189 z.timer = null; |
|
2190 |
|
2191 z.now = lastNum; |
|
2192 z.a(); |
|
2193 |
|
2194 if (elem.curAnim) elem.curAnim[ prop ] = true; |
|
2195 |
|
2196 var done = true; |
|
2197 for ( var i in elem.curAnim ) |
|
2198 if ( elem.curAnim[i] !== true ) |
|
2199 done = false; |
|
2200 |
|
2201 if ( done ) { |
|
2202 // Reset the overflow |
|
2203 y.overflow = ""; |
|
2204 |
|
2205 // Reset the display |
|
2206 y.display = oldDisplay; |
|
2207 if (jQuery.css(elem, "display") == "none") |
|
2208 y.display = "block"; |
|
2209 |
|
2210 // Hide the element if the "hide" operation was done |
|
2211 if ( options.hide ) |
|
2212 y.display = "none"; |
|
2213 |
|
2214 // Reset the properties, if the item has been hidden or shown |
|
2215 if ( options.hide || options.show ) |
|
2216 for ( var p in elem.curAnim ) |
|
2217 if (p == "opacity") |
|
2218 jQuery.attr(y, p, elem.orig[p]); |
|
2219 else |
|
2220 y[p] = ""; |
|
2221 } |
|
2222 |
|
2223 // If a callback was provided, execute it |
|
2224 if ( done && jQuery.isFunction( options.complete ) ) |
|
2225 // Execute the complete function |
|
2226 options.complete.apply( elem ); |
|
2227 } else { |
|
2228 var n = t - this.startTime; |
|
2229 // Figure out where in the animation we are and set the number |
|
2230 var p = n / options.duration; |
|
2231 |
|
2232 // If the easing function exists, then use it |
|
2233 z.now = options.easing && jQuery.easing[options.easing] ? |
|
2234 jQuery.easing[options.easing](p, n, firstNum, (lastNum-firstNum), options.duration) : |
|
2235 // else use default linear easing |
|
2236 ((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum; |
|
2237 |
|
2238 // Perform the next step of the animation |
|
2239 z.a(); |
|
2240 } |
|
2241 }; |
|
2242 |
|
2243 } |
|
2244 }); |
|
2245 } |
|
2246 |