lib_jquery_1.0.js (45369B)
1 /* 2 * jQuery - New Wave Javascript 3 * 4 * Copyright (c) 2006 John Resig (jquery.com) 5 * Dual licensed under the MIT (MIT-LICENSE.txt) 6 * and GPL (GPL-LICENSE.txt) licenses. 7 * 8 * $Date: 2006-10-27 23:14:48 -0400 (Fri, 27 Oct 2006) $ 9 * $Rev: 509 $ 10 */ 11 12 // Global undefined variable 13 window.undefined = window.undefined; 14 function jQuery(a,c) { 15 16 // Shortcut for document ready (because $(document).each() is silly) 17 if ( a && a.constructor == Function && jQuery.fn.ready ) 18 return jQuery(document).ready(a); 19 20 // Make sure that a selection was provided 21 a = a || jQuery.context || document; 22 23 // Watch for when a jQuery object is passed as the selector 24 if ( a.jquery ) 25 return $( jQuery.merge( a, [] ) ); 26 27 // Watch for when a jQuery object is passed at the context 28 if ( c && c.jquery ) 29 return $( c ).find(a); 30 31 // If the context is global, return a new object 32 if ( window == this ) 33 return new jQuery(a,c); 34 35 // Handle HTML strings 36 var m = /^[^<]*(<.+>)[^>]*$/.exec(a); 37 if ( m ) a = jQuery.clean( [ m[1] ] ); 38 39 // Watch for when an array is passed in 40 this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ? 41 // Assume that it is an array of DOM Elements 42 jQuery.merge( a, [] ) : 43 44 // Find the matching elements and save them for later 45 jQuery.find( a, c ) ); 46 47 // See if an extra function was provided 48 var fn = arguments[ arguments.length - 1 ]; 49 50 // If so, execute it in context 51 if ( fn && fn.constructor == Function ) 52 this.each(fn); 53 } 54 55 // Map over the $ in case of overwrite 56 if ( $ ) 57 jQuery._$ = $; 58 59 // Map the jQuery namespace to the '$' one 60 var $ = jQuery; 61 62 jQuery.fn = jQuery.prototype = { 63 jquery: "$Rev: 509 $", 64 65 size: function() { 66 return this.length; 67 }, 68 69 get: function( num ) { 70 // Watch for when an array (of elements) is passed in 71 if ( num && num.constructor == Array ) { 72 73 // Use a tricky hack to make the jQuery object 74 // look and feel like an array 75 this.length = 0; 76 [].push.apply( this, num ); 77 78 return this; 79 } else 80 return num == undefined ? 81 82 // Return a 'clean' array 83 jQuery.map( this, function(a){ return a } ) : 84 85 // Return just the object 86 this[num]; 87 }, 88 each: function( fn, args ) { 89 return jQuery.each( this, fn, args ); 90 }, 91 92 index: function( obj ) { 93 var pos = -1; 94 this.each(function(i){ 95 if ( this == obj ) pos = i; 96 }); 97 return pos; 98 }, 99 100 attr: function( key, value, type ) { 101 // Check to see if we're setting style values 102 return key.constructor != String || value != undefined ? 103 this.each(function(){ 104 // See if we're setting a hash of styles 105 if ( value == undefined ) 106 // Set all the styles 107 for ( var prop in key ) 108 jQuery.attr( 109 type ? this.style : this, 110 prop, key[prop] 111 ); 112 113 // See if we're setting a single key/value style 114 else 115 jQuery.attr( 116 type ? this.style : this, 117 key, value 118 ); 119 }) : 120 121 // Look for the case where we're accessing a style value 122 jQuery[ type || "attr" ]( this[0], key ); 123 }, 124 125 css: function( key, value ) { 126 return this.attr( key, value, "curCSS" ); 127 }, 128 text: function(e) { 129 e = e || this; 130 var t = ""; 131 for ( var j = 0; j < e.length; j++ ) { 132 var r = e[j].childNodes; 133 for ( var i = 0; i < r.length; i++ ) 134 t += r[i].nodeType != 1 ? 135 r[i].nodeValue : jQuery.fn.text([ r[i] ]); 136 } 137 return t; 138 }, 139 wrap: function() { 140 // The elements to wrap the target around 141 var a = jQuery.clean(arguments); 142 143 // Wrap each of the matched elements individually 144 return this.each(function(){ 145 // Clone the structure that we're using to wrap 146 var b = a[0].cloneNode(true); 147 148 // Insert it before the element to be wrapped 149 this.parentNode.insertBefore( b, this ); 150 151 // Find he deepest point in the wrap structure 152 while ( b.firstChild ) 153 b = b.firstChild; 154 155 // Move the matched element to within the wrap structure 156 b.appendChild( this ); 157 }); 158 }, 159 append: function() { 160 return this.domManip(arguments, true, 1, function(a){ 161 this.appendChild( a ); 162 }); 163 }, 164 prepend: function() { 165 return this.domManip(arguments, true, -1, function(a){ 166 this.insertBefore( a, this.firstChild ); 167 }); 168 }, 169 before: function() { 170 return this.domManip(arguments, false, 1, function(a){ 171 this.parentNode.insertBefore( a, this ); 172 }); 173 }, 174 after: function() { 175 return this.domManip(arguments, false, -1, function(a){ 176 this.parentNode.insertBefore( a, this.nextSibling ); 177 }); 178 }, 179 end: function() { 180 return this.get( this.stack.pop() ); 181 }, 182 find: function(t) { 183 return this.pushStack( jQuery.map( this, function(a){ 184 return jQuery.find(t,a); 185 }), arguments ); 186 }, 187 188 clone: function(deep) { 189 return this.pushStack( jQuery.map( this, function(a){ 190 return a.cloneNode( deep != undefined ? deep : true ); 191 }), arguments ); 192 }, 193 194 filter: function(t) { 195 return this.pushStack( 196 t.constructor == Array && 197 jQuery.map(this,function(a){ 198 for ( var i = 0; i < t.length; i++ ) 199 if ( jQuery.filter(t[i],[a]).r.length ) 200 return a; 201 }) || 202 203 t.constructor == Boolean && 204 ( t ? this.get() : [] ) || 205 206 t.constructor == Function && 207 jQuery.grep( this, t ) || 208 209 jQuery.filter(t,this).r, arguments ); 210 }, 211 212 not: function(t) { 213 return this.pushStack( t.constructor == String ? 214 jQuery.filter(t,this,false).r : 215 jQuery.grep(this,function(a){ return a != t; }), arguments ); 216 }, 217 218 add: function(t) { 219 return this.pushStack( jQuery.merge( this, t.constructor == String ? 220 jQuery.find(t) : t.constructor == Array ? t : [t] ), arguments ); 221 }, 222 is: function(expr) { 223 return expr ? jQuery.filter(expr,this).r.length > 0 : this.length > 0; 224 }, 225 domManip: function(args, table, dir, fn){ 226 var clone = this.size() > 1; 227 var a = jQuery.clean(args); 228 229 return this.each(function(){ 230 var obj = this; 231 232 if ( table && this.nodeName == "TABLE" && a[0].nodeName != "THEAD" ) { 233 var tbody = this.getElementsByTagName("tbody"); 234 235 if ( !tbody.length ) { 236 obj = document.createElement("tbody"); 237 this.appendChild( obj ); 238 } else 239 obj = tbody[0]; 240 } 241 242 for ( var i = ( dir < 0 ? a.length - 1 : 0 ); 243 i != ( dir < 0 ? dir : a.length ); i += dir ) { 244 fn.apply( obj, [ clone ? a[i].cloneNode(true) : a[i] ] ); 245 } 246 }); 247 }, 248 pushStack: function(a,args) { 249 var fn = args && args[args.length-1]; 250 251 if ( !fn || fn.constructor != Function ) { 252 if ( !this.stack ) this.stack = []; 253 this.stack.push( this.get() ); 254 this.get( a ); 255 } else { 256 var old = this.get(); 257 this.get( a ); 258 if ( fn.constructor == Function ) 259 return this.each( fn ); 260 this.get( old ); 261 } 262 263 return this; 264 } 265 }; 266 267 jQuery.extend = jQuery.fn.extend = function(obj,prop) { 268 if ( !prop ) { prop = obj; obj = this; } 269 for ( var i in prop ) obj[i] = prop[i]; 270 return obj; 271 }; 272 273 jQuery.extend({ 274 init: function(){ 275 jQuery.initDone = true; 276 277 jQuery.each( jQuery.macros.axis, function(i,n){ 278 jQuery.fn[ i ] = function(a) { 279 var ret = jQuery.map(this,n); 280 if ( a && a.constructor == String ) 281 ret = jQuery.filter(a,ret).r; 282 return this.pushStack( ret, arguments ); 283 }; 284 }); 285 286 jQuery.each( jQuery.macros.to, function(i,n){ 287 jQuery.fn[ i ] = function(){ 288 var a = arguments; 289 return this.each(function(){ 290 for ( var j = 0; j < a.length; j++ ) 291 $(a[j])[n]( this ); 292 }); 293 }; 294 }); 295 296 jQuery.each( jQuery.macros.each, function(i,n){ 297 jQuery.fn[ i ] = function() { 298 return this.each( n, arguments ); 299 }; 300 }); 301 302 jQuery.each( jQuery.macros.filter, function(i,n){ 303 jQuery.fn[ n ] = function(num,fn) { 304 return this.filter( ":" + n + "(" + num + ")", fn ); 305 }; 306 }); 307 308 jQuery.each( jQuery.macros.attr, function(i,n){ 309 n = n || i; 310 jQuery.fn[ i ] = function(h) { 311 return h == undefined ? 312 this.length ? this[0][n] : null : 313 this.attr( n, h ); 314 }; 315 }); 316 317 jQuery.each( jQuery.macros.css, function(i,n){ 318 jQuery.fn[ n ] = function(h) { 319 return h == undefined ? 320 ( this.length ? jQuery.css( this[0], n ) : null ) : 321 this.css( n, h ); 322 }; 323 }); 324 325 }, 326 each: function( obj, fn, args ) { 327 if ( obj.length == undefined ) 328 for ( var i in obj ) 329 fn.apply( obj[i], args || [i, obj[i]] ); 330 else 331 for ( var i = 0; i < obj.length; i++ ) 332 fn.apply( obj[i], args || [i, obj[i]] ); 333 return obj; 334 }, 335 336 className: { 337 add: function(o,c){ 338 if (jQuery.className.has(o,c)) return; 339 o.className += ( o.className ? " " : "" ) + c; 340 }, 341 remove: function(o,c){ 342 o.className = !c ? "" : 343 o.className.replace( 344 new RegExp("(^|\\s*\\b[^-])"+c+"($|\\b(?=[^-]))", "g"), ""); 345 }, 346 has: function(e,a) { 347 if ( e.className != undefined ) 348 e = e.className; 349 return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e); 350 } 351 }, 352 swap: function(e,o,f) { 353 for ( var i in o ) { 354 e.style["old"+i] = e.style[i]; 355 e.style[i] = o[i]; 356 } 357 f.apply( e, [] ); 358 for ( var i in o ) 359 e.style[i] = e.style["old"+i]; 360 }, 361 362 css: function(e,p) { 363 if ( p == "height" || p == "width" ) { 364 var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"]; 365 366 for ( var i in d ) { 367 old["padding" + d[i]] = 0; 368 old["border" + d[i] + "Width"] = 0; 369 } 370 371 jQuery.swap( e, old, function() { 372 if (jQuery.css(e,"display") != "none") { 373 oHeight = e.offsetHeight; 374 oWidth = e.offsetWidth; 375 } else { 376 e = $(e.cloneNode(true)).css({ 377 visibility: "hidden", position: "absolute", display: "block" 378 }).prependTo("body")[0]; 379 380 oHeight = e.clientHeight; 381 oWidth = e.clientWidth; 382 383 e.parentNode.removeChild(e); 384 } 385 }); 386 387 return p == "height" ? oHeight : oWidth; 388 } else if ( p == "opacity" && jQuery.browser.msie ) 389 return parseFloat( jQuery.curCSS(e,"filter").replace(/[^0-9.]/,"") ) || 1; 390 391 return jQuery.curCSS( e, p ); 392 }, 393 394 curCSS: function(elem, prop, force) { 395 var ret; 396 397 if (!force && elem.style[prop]) { 398 399 ret = elem.style[prop]; 400 401 } else if (elem.currentStyle) { 402 403 var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase()}); 404 ret = elem.currentStyle[prop] || elem.currentStyle[newProp]; 405 406 } else if (document.defaultView && document.defaultView.getComputedStyle) { 407 408 prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase(); 409 var cur = document.defaultView.getComputedStyle(elem, null); 410 411 if ( cur ) 412 ret = cur.getPropertyValue(prop); 413 else if ( prop == 'display' ) 414 ret = 'none'; 415 else 416 jQuery.swap(elem, { display: 'block' }, function() { 417 ret = document.defaultView.getComputedStyle(this,null).getPropertyValue(prop); 418 }); 419 420 } 421 422 return ret; 423 }, 424 425 clean: function(a) { 426 var r = []; 427 for ( var i = 0; i < a.length; i++ ) { 428 if ( a[i].constructor == String ) { 429 430 var table = ""; 431 432 if ( !a[i].indexOf("<thead") || !a[i].indexOf("<tbody") ) { 433 table = "thead"; 434 a[i] = "<table>" + a[i] + "</table>"; 435 } else if ( !a[i].indexOf("<tr") ) { 436 table = "tr"; 437 a[i] = "<table>" + a[i] + "</table>"; 438 } else if ( !a[i].indexOf("<td") || !a[i].indexOf("<th") ) { 439 table = "td"; 440 a[i] = "<table><tbody><tr>" + a[i] + "</tr></tbody></table>"; 441 } 442 443 var div = document.createElement("div"); 444 div.innerHTML = a[i]; 445 446 if ( table ) { 447 div = div.firstChild; 448 if ( table != "thead" ) div = div.firstChild; 449 if ( table == "td" ) div = div.firstChild; 450 } 451 452 for ( var j = 0; j < div.childNodes.length; j++ ) 453 r.push( div.childNodes[j] ); 454 } else if ( a[i].jquery || a[i].length && !a[i].nodeType ) 455 for ( var k = 0; k < a[i].length; k++ ) 456 r.push( a[i][k] ); 457 else if ( a[i] !== null ) 458 r.push( a[i].nodeType ? a[i] : document.createTextNode(a[i].toString()) ); 459 } 460 return r; 461 }, 462 463 expr: { 464 "": "m[2]== '*'||a.nodeName.toUpperCase()==m[2].toUpperCase()", 465 "#": "a.getAttribute('id')&&a.getAttribute('id')==m[2]", 466 ":": { 467 // Position Checks 468 lt: "i<m[3]-0", 469 gt: "i>m[3]-0", 470 nth: "m[3]-0==i", 471 eq: "m[3]-0==i", 472 first: "i==0", 473 last: "i==r.length-1", 474 even: "i%2==0", 475 odd: "i%2", 476 477 // Child Checks 478 "first-child": "jQuery.sibling(a,0).cur", 479 "last-child": "jQuery.sibling(a,0).last", 480 "only-child": "jQuery.sibling(a).length==1", 481 482 // Parent Checks 483 parent: "a.childNodes.length", 484 empty: "!a.childNodes.length", 485 486 // Text Check 487 contains: "(a.innerText||a.innerHTML).indexOf(m[3])>=0", 488 489 // Visibility 490 visible: "a.type!='hidden'&&jQuery.css(a,'display')!='none'&&jQuery.css(a,'visibility')!='hidden'", 491 hidden: "a.type=='hidden'||jQuery.css(a,'display')=='none'||jQuery.css(a,'visibility')=='hidden'", 492 493 // Form elements 494 enabled: "!a.disabled", 495 disabled: "a.disabled", 496 checked: "a.checked", 497 selected: "a.selected" 498 }, 499 ".": "jQuery.className.has(a,m[2])", 500 "@": { 501 "=": "z==m[4]", 502 "!=": "z!=m[4]", 503 "^=": "!z.indexOf(m[4])", 504 "$=": "z.substr(z.length - m[4].length,m[4].length)==m[4]", 505 "*=": "z.indexOf(m[4])>=0", 506 "": "z" 507 }, 508 "[": "jQuery.find(m[2],a).length" 509 }, 510 511 token: [ 512 "\\.\\.|/\\.\\.", "a.parentNode", 513 ">|/", "jQuery.sibling(a.firstChild)", 514 "\\+", "jQuery.sibling(a).next", 515 "~", function(a){ 516 var r = []; 517 var s = jQuery.sibling(a); 518 if ( s.n > 0 ) 519 for ( var i = s.n; i < s.length; i++ ) 520 r.push( s[i] ); 521 return r; 522 } 523 ], 524 find: function( t, context ) { 525 // Make sure that the context is a DOM Element 526 if ( context && context.nodeType == undefined ) 527 context = null; 528 529 // Set the correct context (if none is provided) 530 context = context || jQuery.context || document; 531 532 if ( t.constructor != String ) return [t]; 533 534 if ( !t.indexOf("//") ) { 535 context = context.documentElement; 536 t = t.substr(2,t.length); 537 } else if ( !t.indexOf("/") ) { 538 context = context.documentElement; 539 t = t.substr(1,t.length); 540 // FIX Assume the root element is right :( 541 if ( t.indexOf("/") >= 1 ) 542 t = t.substr(t.indexOf("/"),t.length); 543 } 544 545 var ret = [context]; 546 var done = []; 547 var last = null; 548 549 while ( t.length > 0 && last != t ) { 550 var r = []; 551 last = t; 552 553 t = jQuery.trim(t).replace( /^\/\//i, "" ); 554 555 var foundToken = false; 556 557 for ( var i = 0; i < jQuery.token.length; i += 2 ) { 558 var re = new RegExp("^(" + jQuery.token[i] + ")"); 559 var m = re.exec(t); 560 561 if ( m ) { 562 r = ret = jQuery.map( ret, jQuery.token[i+1] ); 563 t = jQuery.trim( t.replace( re, "" ) ); 564 foundToken = true; 565 } 566 } 567 568 if ( !foundToken ) { 569 if ( !t.indexOf(",") || !t.indexOf("|") ) { 570 if ( ret[0] == context ) ret.shift(); 571 done = jQuery.merge( done, ret ); 572 r = ret = [context]; 573 t = " " + t.substr(1,t.length); 574 } else { 575 var re2 = /^([#.]?)([a-z0-9\\*_-]*)/i; 576 var m = re2.exec(t); 577 578 if ( m[1] == "#" ) { 579 // Ummm, should make this work in all XML docs 580 var oid = document.getElementById(m[2]); 581 r = ret = oid ? [oid] : []; 582 t = t.replace( re2, "" ); 583 } else { 584 if ( !m[2] || m[1] == "." ) m[2] = "*"; 585 586 for ( var i = 0; i < ret.length; i++ ) 587 r = jQuery.merge( r, 588 m[2] == "*" ? 589 jQuery.getAll(ret[i]) : 590 ret[i].getElementsByTagName(m[2]) 591 ); 592 } 593 } 594 } 595 596 if ( t ) { 597 var val = jQuery.filter(t,r); 598 ret = r = val.r; 599 t = jQuery.trim(val.t); 600 } 601 } 602 603 if ( ret && ret[0] == context ) ret.shift(); 604 done = jQuery.merge( done, ret ); 605 606 return done; 607 }, 608 609 getAll: function(o,r) { 610 r = r || []; 611 var s = o.childNodes; 612 for ( var i = 0; i < s.length; i++ ) 613 if ( s[i].nodeType == 1 ) { 614 r.push( s[i] ); 615 jQuery.getAll( s[i], r ); 616 } 617 return r; 618 }, 619 620 attr: function(elem, name, value){ 621 var fix = { 622 "for": "htmlFor", 623 "class": "className", 624 "float": "cssFloat", 625 innerHTML: "innerHTML", 626 className: "className" 627 }; 628 629 if ( fix[name] ) { 630 if ( value != undefined ) elem[fix[name]] = value; 631 return elem[fix[name]]; 632 } else if ( elem.getAttribute ) { 633 if ( value != undefined ) elem.setAttribute( name, value ); 634 return elem.getAttribute( name, 2 ); 635 } else { 636 name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();}); 637 if ( value != undefined ) elem[name] = value; 638 return elem[name]; 639 } 640 }, 641 642 // The regular expressions that power the parsing engine 643 parse: [ 644 // Match: [@value='test'], [@foo] 645 [ "\\[ *(@)S *([!*$^=]*) *Q\\]", 1 ], 646 647 // Match: [div], [div p] 648 [ "(\\[)Q\\]", 0 ], 649 650 // Match: :contains('foo') 651 [ "(:)S\\(Q\\)", 0 ], 652 653 // Match: :even, :last-chlid 654 [ "([:.#]*)S", 0 ] 655 ], 656 657 filter: function(t,r,not) { 658 // Figure out if we're doing regular, or inverse, filtering 659 var g = not !== false ? jQuery.grep : 660 function(a,f) {return jQuery.grep(a,f,true);}; 661 662 while ( t && /^[a-z[({<*:.#]/i.test(t) ) { 663 664 var p = jQuery.parse; 665 666 for ( var i = 0; i < p.length; i++ ) { 667 var re = new RegExp( "^" + p[i][0] 668 669 // Look for a string-like sequence 670 .replace( 'S', "([a-z*_-][a-z0-9_-]*)" ) 671 672 // Look for something (optionally) enclosed with quotes 673 .replace( 'Q', " *'?\"?([^'\"]*?)'?\"? *" ), "i" ); 674 675 var m = re.exec( t ); 676 677 if ( m ) { 678 // Re-organize the match 679 if ( p[i][1] ) 680 m = ["", m[1], m[3], m[2], m[4]]; 681 682 // Remove what we just matched 683 t = t.replace( re, "" ); 684 685 break; 686 } 687 } 688 689 // :not() is a special case that can be optomized by 690 // keeping it out of the expression list 691 if ( m[1] == ":" && m[2] == "not" ) 692 r = jQuery.filter(m[3],r,false).r; 693 694 // Otherwise, find the expression to execute 695 else { 696 var f = jQuery.expr[m[1]]; 697 if ( f.constructor != String ) 698 f = jQuery.expr[m[1]][m[2]]; 699 700 // Build a custom macro to enclose it 701 eval("f = function(a,i){" + 702 ( m[1] == "@" ? "z=jQuery.attr(a,m[3]);" : "" ) + 703 "return " + f + "}"); 704 705 // Execute it against the current filter 706 r = g( r, f ); 707 } 708 } 709 710 // Return an array of filtered elements (r) 711 // and the modified expression string (t) 712 return { r: r, t: t }; 713 }, 714 trim: function(t){ 715 return t.replace(/^\s+|\s+$/g, ""); 716 }, 717 parents: function( elem ){ 718 var matched = []; 719 var cur = elem.parentNode; 720 while ( cur && cur != document ) { 721 matched.push( cur ); 722 cur = cur.parentNode; 723 } 724 return matched; 725 }, 726 sibling: function(elem, pos, not) { 727 var elems = []; 728 729 var siblings = elem.parentNode.childNodes; 730 for ( var i = 0; i < siblings.length; i++ ) { 731 if ( not === true && siblings[i] == elem ) continue; 732 733 if ( siblings[i].nodeType == 1 ) 734 elems.push( siblings[i] ); 735 if ( siblings[i] == elem ) 736 elems.n = elems.length - 1; 737 } 738 739 return jQuery.extend( elems, { 740 last: elems.n == elems.length - 1, 741 cur: pos == "even" && elems.n % 2 == 0 || pos == "odd" && elems.n % 2 || elems[pos] == elem, 742 prev: elems[elems.n - 1], 743 next: elems[elems.n + 1] 744 }); 745 }, 746 merge: function(first, second) { 747 var result = []; 748 749 // Move b over to the new array (this helps to avoid 750 // StaticNodeList instances) 751 for ( var k = 0; k < first.length; k++ ) 752 result[k] = first[k]; 753 754 // Now check for duplicates between a and b and only 755 // add the unique items 756 for ( var i = 0; i < second.length; i++ ) { 757 var noCollision = true; 758 759 // The collision-checking process 760 for ( var j = 0; j < first.length; j++ ) 761 if ( second[i] == first[j] ) 762 noCollision = false; 763 764 // If the item is unique, add it 765 if ( noCollision ) 766 result.push( second[i] ); 767 } 768 769 return result; 770 }, 771 grep: function(elems, fn, inv) { 772 // If a string is passed in for the function, make a function 773 // for it (a handy shortcut) 774 if ( fn.constructor == String ) 775 fn = new Function("a","i","return " + fn); 776 777 var result = []; 778 779 // Go through the array, only saving the items 780 // that pass the validator function 781 for ( var i = 0; i < elems.length; i++ ) 782 if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) ) 783 result.push( elems[i] ); 784 785 return result; 786 }, 787 map: function(elems, fn) { 788 // If a string is passed in for the function, make a function 789 // for it (a handy shortcut) 790 if ( fn.constructor == String ) 791 fn = new Function("a","return " + fn); 792 793 var result = []; 794 795 // Go through the array, translating each of the items to their 796 // new value (or values). 797 for ( var i = 0; i < elems.length; i++ ) { 798 var val = fn(elems[i],i); 799 800 if ( val !== null && val != undefined ) { 801 if ( val.constructor != Array ) val = [val]; 802 result = jQuery.merge( result, val ); 803 } 804 } 805 806 return result; 807 }, 808 809 /* 810 * A number of helper functions used for managing events. 811 * Many of the ideas behind this code orignated from Dean Edwards' addEvent library. 812 */ 813 event: { 814 815 // Bind an event to an element 816 // Original by Dean Edwards 817 add: function(element, type, handler) { 818 // For whatever reason, IE has trouble passing the window object 819 // around, causing it to be cloned in the process 820 if ( jQuery.browser.msie && element.setInterval != undefined ) 821 element = window; 822 823 // Make sure that the function being executed has a unique ID 824 if ( !handler.guid ) 825 handler.guid = this.guid++; 826 827 // Init the element's event structure 828 if (!element.events) 829 element.events = {}; 830 831 // Get the current list of functions bound to this event 832 var handlers = element.events[type]; 833 834 // If it hasn't been initialized yet 835 if (!handlers) { 836 // Init the event handler queue 837 handlers = element.events[type] = {}; 838 839 // Remember an existing handler, if it's already there 840 if (element["on" + type]) 841 handlers[0] = element["on" + type]; 842 } 843 844 // Add the function to the element's handler list 845 handlers[handler.guid] = handler; 846 847 // And bind the global event handler to the element 848 element["on" + type] = this.handle; 849 850 // Remember the function in a global list (for triggering) 851 if (!this.global[type]) 852 this.global[type] = []; 853 this.global[type].push( element ); 854 }, 855 856 guid: 1, 857 global: {}, 858 859 // Detach an event or set of events from an element 860 remove: function(element, type, handler) { 861 if (element.events) 862 if (type && element.events[type]) 863 if ( handler ) 864 delete element.events[type][handler.guid]; 865 else 866 for ( var i in element.events[type] ) 867 delete element.events[type][i]; 868 else 869 for ( var j in element.events ) 870 this.remove( element, j ); 871 }, 872 873 trigger: function(type,data,element) { 874 // Touch up the incoming data 875 data = data || []; 876 877 // Handle a global trigger 878 if ( !element ) { 879 var g = this.global[type]; 880 if ( g ) 881 for ( var i = 0; i < g.length; i++ ) 882 this.trigger( type, data, g[i] ); 883 884 // Handle triggering a single element 885 } else if ( element["on" + type] ) { 886 // Pass along a fake event 887 data.unshift( this.fix({ type: type, target: element }) ); 888 889 // Trigger the event 890 element["on" + type].apply( element, data ); 891 } 892 }, 893 894 handle: function(event) { 895 if ( typeof jQuery == "undefined" ) return; 896 897 event = event || jQuery.event.fix( window.event ); 898 899 // If no correct event was found, fail 900 if ( !event ) return; 901 902 var returnValue = true; 903 904 var c = this.events[event.type]; 905 906 for ( var j in c ) { 907 if ( c[j].apply( this, [event] ) === false ) { 908 event.preventDefault(); 909 event.stopPropagation(); 910 returnValue = false; 911 } 912 } 913 914 return returnValue; 915 }, 916 917 fix: function(event) { 918 if ( event ) { 919 event.preventDefault = function() { 920 this.returnValue = false; 921 }; 922 923 event.stopPropagation = function() { 924 this.cancelBubble = true; 925 }; 926 } 927 928 return event; 929 } 930 931 } 932 }); 933 934 new function() { 935 var b = navigator.userAgent.toLowerCase(); 936 937 // Figure out what browser is being used 938 jQuery.browser = { 939 safari: /webkit/.test(b), 940 opera: /opera/.test(b), 941 msie: /msie/.test(b) && !/opera/.test(b), 942 mozilla: /mozilla/.test(b) && !/compatible/.test(b) 943 }; 944 945 // Check to see if the W3C box model is being used 946 jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat"; 947 }; 948 949 jQuery.macros = { 950 to: { 951 appendTo: "append", 952 prependTo: "prepend", 953 insertBefore: "before", 954 insertAfter: "after" 955 }, 956 957 958 css: "width,height,top,left,position,float,overflow,color,background".split(","), 959 960 filter: [ "eq", "lt", "gt", "contains" ], 961 962 attr: { 963 964 val: "value", 965 966 html: "innerHTML", 967 968 id: null, 969 970 title: null, 971 972 name: null, 973 974 href: null, 975 976 src: null, 977 978 rel: null 979 }, 980 981 axis: { 982 983 parent: "a.parentNode", 984 985 ancestors: jQuery.parents, 986 987 parents: jQuery.parents, 988 989 next: "jQuery.sibling(a).next", 990 991 prev: "jQuery.sibling(a).prev", 992 993 siblings: jQuery.sibling, 994 995 children: "a.childNodes" 996 }, 997 998 each: { 999 1000 removeAttr: function( key ) { 1001 this.removeAttribute( key ); 1002 }, 1003 show: function(){ 1004 this.style.display = this.oldblock ? this.oldblock : ""; 1005 if ( jQuery.css(this,"display") == "none" ) 1006 this.style.display = "block"; 1007 }, 1008 hide: function(){ 1009 this.oldblock = this.oldblock || jQuery.css(this,"display"); 1010 if ( this.oldblock == "none" ) 1011 this.oldblock = "block"; 1012 this.style.display = "none"; 1013 }, 1014 toggle: function(){ 1015 $(this)[ $(this).is(":hidden") ? "show" : "hide" ].apply( $(this), arguments ); 1016 }, 1017 addClass: function(c){ 1018 jQuery.className.add(this,c); 1019 }, 1020 removeClass: function(c){ 1021 jQuery.className.remove(this,c); 1022 }, 1023 toggleClass: function( c ){ 1024 jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this,c); 1025 }, 1026 1027 remove: function(a){ 1028 if ( !a || jQuery.filter( [this], a ).r ) 1029 this.parentNode.removeChild( this ); 1030 }, 1031 empty: function(){ 1032 while ( this.firstChild ) 1033 this.removeChild( this.firstChild ); 1034 }, 1035 bind: function( type, fn ) { 1036 if ( fn.constructor == String ) 1037 fn = new Function("e", ( !fn.indexOf(".") ? "$(this)" : "return " ) + fn); 1038 jQuery.event.add( this, type, fn ); 1039 }, 1040 1041 unbind: function( type, fn ) { 1042 jQuery.event.remove( this, type, fn ); 1043 }, 1044 trigger: function( type, data ) { 1045 jQuery.event.trigger( type, data, this ); 1046 } 1047 } 1048 }; 1049 1050 jQuery.init();jQuery.fn.extend({ 1051 1052 // We're overriding the old toggle function, so 1053 // remember it for later 1054 _toggle: jQuery.fn.toggle, 1055 toggle: function(a,b) { 1056 // If two functions are passed in, we're 1057 // toggling on a click 1058 return a && b && a.constructor == Function && b.constructor == Function ? this.click(function(e){ 1059 // Figure out which function to execute 1060 this.last = this.last == a ? b : a; 1061 1062 // Make sure that clicks stop 1063 e.preventDefault(); 1064 1065 // and execute the function 1066 return this.last.apply( this, [e] ) || false; 1067 }) : 1068 1069 // Otherwise, execute the old toggle function 1070 this._toggle.apply( this, arguments ); 1071 }, 1072 1073 hover: function(f,g) { 1074 1075 // A private function for haandling mouse 'hovering' 1076 function handleHover(e) { 1077 // Check if mouse(over|out) are still within the same parent element 1078 var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget; 1079 1080 // Traverse up the tree 1081 while ( p && p != this ) p = p.parentNode; 1082 1083 // If we actually just moused on to a sub-element, ignore it 1084 if ( p == this ) return false; 1085 1086 // Execute the right function 1087 return (e.type == "mouseover" ? f : g).apply(this, [e]); 1088 } 1089 1090 // Bind the function to the two event listeners 1091 return this.mouseover(handleHover).mouseout(handleHover); 1092 }, 1093 ready: function(f) { 1094 // If the DOM is already ready 1095 if ( jQuery.isReady ) 1096 // Execute the function immediately 1097 f.apply( document ); 1098 1099 // Otherwise, remember the function for later 1100 else { 1101 // Add the function to the wait list 1102 jQuery.readyList.push( f ); 1103 } 1104 1105 return this; 1106 } 1107 }); 1108 1109 jQuery.extend({ 1110 /* 1111 * All the code that makes DOM Ready work nicely. 1112 */ 1113 isReady: false, 1114 readyList: [], 1115 1116 // Handle when the DOM is ready 1117 ready: function() { 1118 // Make sure that the DOM is not already loaded 1119 if ( !jQuery.isReady ) { 1120 // Remember that the DOM is ready 1121 jQuery.isReady = true; 1122 1123 // If there are functions bound, to execute 1124 if ( jQuery.readyList ) { 1125 // Execute all of them 1126 for ( var i = 0; i < jQuery.readyList.length; i++ ) 1127 jQuery.readyList[i].apply( document ); 1128 1129 // Reset the list of functions 1130 jQuery.readyList = null; 1131 } 1132 } 1133 } 1134 }); 1135 1136 new function(){ 1137 1138 var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," + 1139 "mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select," + 1140 "submit,keydown,keypress,keyup,error").split(","); 1141 1142 // Go through all the event names, but make sure that 1143 // it is enclosed properly 1144 for ( var i = 0; i < e.length; i++ ) new function(){ 1145 1146 var o = e[i]; 1147 1148 // Handle event binding 1149 jQuery.fn[o] = function(f){ 1150 return f ? this.bind(o, f) : this.trigger(o); 1151 }; 1152 1153 // Handle event unbinding 1154 jQuery.fn["un"+o] = function(f){ return this.unbind(o, f); }; 1155 1156 // Finally, handle events that only fire once 1157 jQuery.fn["one"+o] = function(f){ 1158 // Attach the event listener 1159 return this.each(function(){ 1160 1161 var count = 0; 1162 1163 // Add the event 1164 jQuery.event.add( this, o, function(e){ 1165 // If this function has already been executed, stop 1166 if ( count++ ) return; 1167 1168 // And execute the bound function 1169 return f.apply(this, [e]); 1170 }); 1171 }); 1172 }; 1173 1174 }; 1175 1176 // If Mozilla is used 1177 if ( jQuery.browser.mozilla || jQuery.browser.opera ) { 1178 // Use the handy event callback 1179 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 1180 1181 // If IE is used, use the excellent hack by Matthias Miller 1182 // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited 1183 } else if ( jQuery.browser.msie ) { 1184 1185 // Only works if you document.write() it 1186 document.write("<scr" + "ipt id=__ie_init defer=true " + 1187 "src=//:><\/script>"); 1188 1189 // Use the defer script hack 1190 var script = document.getElementById("__ie_init"); 1191 script.onreadystatechange = function() { 1192 if ( this.readyState == "complete" ) 1193 jQuery.ready(); 1194 }; 1195 1196 // Clear from memory 1197 script = null; 1198 1199 // If Safari is used 1200 } else if ( jQuery.browser.safari ) { 1201 // Continually check to see if the document.readyState is valid 1202 jQuery.safariTimer = setInterval(function(){ 1203 // loaded and complete are both valid states 1204 if ( document.readyState == "loaded" || 1205 document.readyState == "complete" ) { 1206 1207 // If either one are found, remove the timer 1208 clearInterval( jQuery.safariTimer ); 1209 jQuery.safariTimer = null; 1210 1211 // and execute any waiting functions 1212 jQuery.ready(); 1213 } 1214 }, 10); 1215 } 1216 1217 // A fallback to window.onload, that will always work 1218 jQuery.event.add( window, "load", jQuery.ready ); 1219 1220 }; 1221 jQuery.fn.extend({ 1222 1223 // overwrite the old show method 1224 _show: jQuery.fn.show, 1225 1226 show: function(speed,callback){ 1227 return speed ? this.animate({ 1228 height: "show", width: "show", opacity: "show" 1229 }, speed, callback) : this._show(); 1230 }, 1231 1232 // Overwrite the old hide method 1233 _hide: jQuery.fn.hide, 1234 1235 hide: function(speed,callback){ 1236 return speed ? this.animate({ 1237 height: "hide", width: "hide", opacity: "hide" 1238 }, speed, callback) : this._hide(); 1239 }, 1240 1241 slideDown: function(speed,callback){ 1242 return this.animate({height: "show"}, speed, callback); 1243 }, 1244 1245 slideUp: function(speed,callback){ 1246 return this.animate({height: "hide"}, speed, callback); 1247 }, 1248 1249 slideToggle: function(speed,callback){ 1250 return this.each(function(){ 1251 var state = $(this).is(":hidden") ? "show" : "hide"; 1252 $(this).animate({height: state}, speed, callback); 1253 }); 1254 }, 1255 1256 fadeIn: function(speed,callback){ 1257 return this.animate({opacity: "show"}, speed, callback); 1258 }, 1259 1260 fadeOut: function(speed,callback){ 1261 return this.animate({opacity: "hide"}, speed, callback); 1262 }, 1263 1264 fadeTo: function(speed,to,callback){ 1265 return this.animate({opacity: to}, speed, callback); 1266 }, 1267 animate: function(prop,speed,callback) { 1268 return this.queue(function(){ 1269 1270 this.curAnim = prop; 1271 1272 for ( var p in prop ) { 1273 var e = new jQuery.fx( this, jQuery.speed(speed,callback), p ); 1274 if ( prop[p].constructor == Number ) 1275 e.custom( e.cur(), prop[p] ); 1276 else 1277 e[ prop[p] ]( prop ); 1278 } 1279 1280 }); 1281 }, 1282 queue: function(type,fn){ 1283 if ( !fn ) { 1284 fn = type; 1285 type = "fx"; 1286 } 1287 1288 return this.each(function(){ 1289 if ( !this.queue ) 1290 this.queue = {}; 1291 1292 if ( !this.queue[type] ) 1293 this.queue[type] = []; 1294 1295 this.queue[type].push( fn ); 1296 1297 if ( this.queue[type].length == 1 ) 1298 fn.apply(this); 1299 }); 1300 } 1301 1302 }); 1303 1304 jQuery.extend({ 1305 1306 setAuto: function(e,p) { 1307 if ( e.notAuto ) return; 1308 1309 if ( p == "height" && e.scrollHeight != parseInt(jQuery.curCSS(e,p)) ) return; 1310 if ( p == "width" && e.scrollWidth != parseInt(jQuery.curCSS(e,p)) ) return; 1311 1312 // Remember the original height 1313 var a = e.style[p]; 1314 1315 // Figure out the size of the height right now 1316 var o = jQuery.curCSS(e,p,1); 1317 1318 if ( p == "height" && e.scrollHeight != o || 1319 p == "width" && e.scrollWidth != o ) return; 1320 1321 // Set the height to auto 1322 e.style[p] = e.currentStyle ? "" : "auto"; 1323 1324 // See what the size of "auto" is 1325 var n = jQuery.curCSS(e,p,1); 1326 1327 // Revert back to the original size 1328 if ( o != n && n != "auto" ) { 1329 e.style[p] = a; 1330 e.notAuto = true; 1331 } 1332 }, 1333 1334 speed: function(s,o) { 1335 o = o || {}; 1336 1337 if ( o.constructor == Function ) 1338 o = { complete: o }; 1339 1340 var ss = { slow: 600, fast: 200 }; 1341 o.duration = (s && s.constructor == Number ? s : ss[s]) || 400; 1342 1343 // Queueing 1344 o.oldComplete = o.complete; 1345 o.complete = function(){ 1346 jQuery.dequeue(this, "fx"); 1347 if ( o.oldComplete && o.oldComplete.constructor == Function ) 1348 o.oldComplete.apply( this ); 1349 }; 1350 1351 return o; 1352 }, 1353 1354 queue: {}, 1355 1356 dequeue: function(elem,type){ 1357 type = type || "fx"; 1358 1359 if ( elem.queue && elem.queue[type] ) { 1360 // Remove self 1361 elem.queue[type].shift(); 1362 1363 // Get next function 1364 var f = elem.queue[type][0]; 1365 1366 if ( f ) f.apply( elem ); 1367 } 1368 }, 1369 1370 /* 1371 * I originally wrote fx() as a clone of moo.fx and in the process 1372 * of making it small in size the code became illegible to sane 1373 * people. You've been warned. 1374 */ 1375 1376 fx: function( elem, options, prop ){ 1377 1378 var z = this; 1379 1380 // The users options 1381 z.o = { 1382 duration: options.duration || 400, 1383 complete: options.complete, 1384 step: options.step 1385 }; 1386 1387 // The element 1388 z.el = elem; 1389 1390 // The styles 1391 var y = z.el.style; 1392 1393 // Simple function for setting a style value 1394 z.a = function(){ 1395 if ( options.step ) 1396 options.step.apply( elem, [ z.now ] ); 1397 1398 if ( prop == "opacity" ) { 1399 if (z.now == 1) z.now = 0.9999; 1400 if (window.ActiveXObject) 1401 y.filter = "alpha(opacity=" + z.now*100 + ")"; 1402 else 1403 y.opacity = z.now; 1404 1405 // My hate for IE will never die 1406 } else if ( parseInt(z.now) ) 1407 y[prop] = parseInt(z.now) + "px"; 1408 1409 y.display = "block"; 1410 }; 1411 1412 // Figure out the maximum number to run to 1413 z.max = function(){ 1414 return parseFloat( jQuery.css(z.el,prop) ); 1415 }; 1416 1417 // Get the current size 1418 z.cur = function(){ 1419 var r = parseFloat( jQuery.curCSS(z.el, prop) ); 1420 return r && r > -10000 ? r : z.max(); 1421 }; 1422 1423 // Start an animation from one number to another 1424 z.custom = function(from,to){ 1425 z.startTime = (new Date()).getTime(); 1426 z.now = from; 1427 z.a(); 1428 1429 z.timer = setInterval(function(){ 1430 z.step(from, to); 1431 }, 13); 1432 }; 1433 1434 // Simple 'show' function 1435 z.show = function( p ){ 1436 if ( !z.el.orig ) z.el.orig = {}; 1437 1438 // Remember where we started, so that we can go back to it later 1439 z.el.orig[prop] = this.cur(); 1440 1441 z.custom( 0, z.el.orig[prop] ); 1442 1443 // Stupid IE, look what you made me do 1444 if ( prop != "opacity" ) 1445 y[prop] = "1px"; 1446 }; 1447 1448 // Simple 'hide' function 1449 z.hide = function(){ 1450 if ( !z.el.orig ) z.el.orig = {}; 1451 1452 // Remember where we started, so that we can go back to it later 1453 z.el.orig[prop] = this.cur(); 1454 1455 z.o.hide = true; 1456 1457 // Begin the animation 1458 z.custom(z.el.orig[prop], 0); 1459 }; 1460 1461 // IE has trouble with opacity if it does not have layout 1462 if ( jQuery.browser.msie && !z.el.currentStyle.hasLayout ) 1463 y.zoom = "1"; 1464 1465 // Remember the overflow of the element 1466 if ( !z.el.oldOverlay ) 1467 z.el.oldOverflow = jQuery.css( z.el, "overflow" ); 1468 1469 // Make sure that nothing sneaks out 1470 y.overflow = "hidden"; 1471 1472 // Each step of an animation 1473 z.step = function(firstNum, lastNum){ 1474 var t = (new Date()).getTime(); 1475 1476 if (t > z.o.duration + z.startTime) { 1477 // Stop the timer 1478 clearInterval(z.timer); 1479 z.timer = null; 1480 1481 z.now = lastNum; 1482 z.a(); 1483 1484 z.el.curAnim[ prop ] = true; 1485 1486 var done = true; 1487 for ( var i in z.el.curAnim ) 1488 if ( z.el.curAnim[i] !== true ) 1489 done = false; 1490 1491 if ( done ) { 1492 // Reset the overflow 1493 y.overflow = z.el.oldOverflow; 1494 1495 // Hide the element if the "hide" operation was done 1496 if ( z.o.hide ) 1497 y.display = 'none'; 1498 1499 // Reset the property, if the item has been hidden 1500 if ( z.o.hide ) { 1501 for ( var p in z.el.curAnim ) { 1502 y[ p ] = z.el.orig[p] + ( p == "opacity" ? "" : "px" ); 1503 1504 // set its height and/or width to auto 1505 if ( p == 'height' || p == 'width' ) 1506 jQuery.setAuto( z.el, p ); 1507 } 1508 } 1509 } 1510 1511 // If a callback was provided, execute it 1512 if( done && z.o.complete && z.o.complete.constructor == Function ) 1513 // Execute the complete function 1514 z.o.complete.apply( z.el ); 1515 } else { 1516 // Figure out where in the animation we are and set the number 1517 var p = (t - this.startTime) / z.o.duration; 1518 z.now = ((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum; 1519 1520 // Perform the next step of the animation 1521 z.a(); 1522 } 1523 }; 1524 1525 } 1526 1527 }); 1528 // AJAX Plugin 1529 // Docs Here: 1530 // http://jquery.com/docs/ajax/ 1531 jQuery.fn.loadIfModified = function( url, params, callback ) { 1532 this.load( url, params, callback, 1 ); 1533 }; 1534 1535 jQuery.fn.load = function( url, params, callback, ifModified ) { 1536 if ( url.constructor == Function ) 1537 return this.bind("load", url); 1538 1539 callback = callback || function(){}; 1540 1541 // Default to a GET request 1542 var type = "GET"; 1543 1544 // If the second parameter was provided 1545 if ( params ) { 1546 // If it's a function 1547 if ( params.constructor == Function ) { 1548 // We assume that it's the callback 1549 callback = params; 1550 params = null; 1551 1552 // Otherwise, build a param string 1553 } else { 1554 params = jQuery.param( params ); 1555 type = "POST"; 1556 } 1557 } 1558 1559 var self = this; 1560 1561 // Request the remote document 1562 jQuery.ajax( type, url, params,function(res, status){ 1563 1564 if ( status == "success" || !ifModified && status == "notmodified" ) { 1565 // Inject the HTML into all the matched elements 1566 self.html(res.responseText).each( callback, [res.responseText, status] ); 1567 1568 // Execute all the scripts inside of the newly-injected HTML 1569 $("script", self).each(function(){ 1570 if ( this.src ) 1571 $.getScript( this.src ); 1572 else 1573 eval.call( window, this.text || this.textContent || this.innerHTML || "" ); 1574 }); 1575 } else 1576 callback.apply( self, [res.responseText, status] ); 1577 1578 }, ifModified); 1579 1580 return this; 1581 }; 1582 1583 // If IE is used, create a wrapper for the XMLHttpRequest object 1584 if ( jQuery.browser.msie ) 1585 XMLHttpRequest = function(){ 1586 return new ActiveXObject( 1587 navigator.userAgent.indexOf("MSIE 5") >= 0 ? 1588 "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP" 1589 ); 1590 }; 1591 1592 // Attach a bunch of functions for handling common AJAX events 1593 new function(){ 1594 var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(','); 1595 1596 for ( var i = 0; i < e.length; i++ ) new function(){ 1597 var o = e[i]; 1598 jQuery.fn[o] = function(f){ 1599 return this.bind(o, f); 1600 }; 1601 }; 1602 }; 1603 1604 jQuery.extend({ 1605 get: function( url, data, callback, type, ifModified ) { 1606 if ( data.constructor == Function ) { 1607 type = callback; 1608 callback = data; 1609 data = null; 1610 } 1611 1612 if ( data ) url += "?" + jQuery.param(data); 1613 1614 // Build and start the HTTP Request 1615 jQuery.ajax( "GET", url, null, function(r, status) { 1616 if ( callback ) callback( jQuery.httpData(r,type), status ); 1617 }, ifModified); 1618 }, 1619 1620 getIfModified: function( url, data, callback, type ) { 1621 jQuery.get(url, data, callback, type, 1); 1622 }, 1623 1624 getScript: function( url, data, callback ) { 1625 jQuery.get(url, data, callback, "script"); 1626 }, 1627 post: function( url, data, callback, type ) { 1628 // Build and start the HTTP Request 1629 jQuery.ajax( "POST", url, jQuery.param(data), function(r, status) { 1630 if ( callback ) callback( jQuery.httpData(r,type), status ); 1631 }); 1632 }, 1633 1634 // timeout (ms) 1635 timeout: 0, 1636 1637 ajaxTimeout: function(timeout) { 1638 jQuery.timeout = timeout; 1639 }, 1640 1641 // Last-Modified header cache for next request 1642 lastModified: {}, 1643 ajax: function( type, url, data, ret, ifModified ) { 1644 // If only a single argument was passed in, 1645 // assume that it is a object of key/value pairs 1646 if ( !url ) { 1647 ret = type.complete; 1648 var success = type.success; 1649 var error = type.error; 1650 data = type.data; 1651 url = type.url; 1652 type = type.type; 1653 } 1654 1655 // Watch for a new set of requests 1656 if ( ! jQuery.active++ ) 1657 jQuery.event.trigger( "ajaxStart" ); 1658 1659 var requestDone = false; 1660 1661 // Create the request object 1662 var xml = new XMLHttpRequest(); 1663 1664 // Open the socket 1665 xml.open(type || "GET", url, true); 1666 1667 // Set the correct header, if data is being sent 1668 if ( data ) 1669 xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 1670 1671 // Set the If-Modified-Since header, if ifModified mode. 1672 if ( ifModified ) 1673 xml.setRequestHeader("If-Modified-Since", 1674 jQuery.lastModified[url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 1675 1676 // Set header so calling script knows that it's an XMLHttpRequest 1677 xml.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 1678 1679 // Make sure the browser sends the right content length 1680 if ( xml.overrideMimeType ) 1681 xml.setRequestHeader("Connection", "close"); 1682 1683 // Wait for a response to come back 1684 var onreadystatechange = function(istimeout){ 1685 // The transfer is complete and the data is available, or the request timed out 1686 if ( xml && (xml.readyState == 4 || istimeout == "timeout") ) { 1687 requestDone = true; 1688 1689 var status = jQuery.httpSuccess( xml ) && istimeout != "timeout" ? 1690 ifModified && jQuery.httpNotModified( xml, url ) ? "notmodified" : "success" : "error"; 1691 1692 // Make sure that the request was successful or notmodified 1693 if ( status != "error" ) { 1694 // Cache Last-Modified header, if ifModified mode. 1695 var modRes = xml.getResponseHeader("Last-Modified"); 1696 if ( ifModified && modRes ) jQuery.lastModified[url] = modRes; 1697 1698 // If a local callback was specified, fire it 1699 if ( success ) success( xml, status ); 1700 1701 // Fire the global callback 1702 jQuery.event.trigger( "ajaxSuccess" ); 1703 1704 // Otherwise, the request was not successful 1705 } else { 1706 // If a local callback was specified, fire it 1707 if ( error ) error( xml, status ); 1708 1709 // Fire the global callback 1710 jQuery.event.trigger( "ajaxError" ); 1711 } 1712 1713 // The request was completed 1714 jQuery.event.trigger( "ajaxComplete" ); 1715 1716 // Handle the global AJAX counter 1717 if ( ! --jQuery.active ) 1718 jQuery.event.trigger( "ajaxStop" ); 1719 1720 // Process result 1721 if ( ret ) ret(xml, status); 1722 1723 // Stop memory leaks 1724 xml.onreadystatechange = function(){}; 1725 xml = null; 1726 1727 } 1728 }; 1729 xml.onreadystatechange = onreadystatechange; 1730 1731 // Timeout checker 1732 if(jQuery.timeout > 0) 1733 setTimeout(function(){ 1734 // Check to see if the request is still happening 1735 if (xml) { 1736 // Cancel the request 1737 xml.abort(); 1738 1739 if ( !requestDone ) onreadystatechange( "timeout" ); 1740 1741 // Clear from memory 1742 xml = null; 1743 } 1744 }, jQuery.timeout); 1745 1746 // Send the data 1747 xml.send(data); 1748 }, 1749 1750 // Counter for holding the number of active queries 1751 active: 0, 1752 1753 // Determines if an XMLHttpRequest was successful or not 1754 httpSuccess: function(r) { 1755 try { 1756 return !r.status && location.protocol == "file:" || 1757 ( r.status >= 200 && r.status < 300 ) || r.status == 304 || 1758 jQuery.browser.safari && r.status == undefined; 1759 } catch(e){} 1760 1761 return false; 1762 }, 1763 1764 // Determines if an XMLHttpRequest returns NotModified 1765 httpNotModified: function(xml, url) { 1766 try { 1767 var xmlRes = xml.getResponseHeader("Last-Modified"); 1768 1769 // Firefox always returns 200. check Last-Modified date 1770 return xml.status == 304 || xmlRes == jQuery.lastModified[url] || 1771 jQuery.browser.safari && xml.status == undefined; 1772 } catch(e){} 1773 1774 return false; 1775 }, 1776 1777 // Get the data out of an XMLHttpRequest. 1778 // Return parsed XML if content-type header is "xml" and type is "xml" or omitted, 1779 // otherwise return plain text. 1780 httpData: function(r,type) { 1781 var ct = r.getResponseHeader("content-type"); 1782 var data = !type && ct && ct.indexOf("xml") >= 0; 1783 data = type == "xml" || data ? r.responseXML : r.responseText; 1784 1785 // If the type is "script", eval it 1786 if ( type == "script" ) eval.call( window, data ); 1787 1788 return data; 1789 }, 1790 1791 // Serialize an array of form elements or a set of 1792 // key/values into a query string 1793 param: function(a) { 1794 var s = []; 1795 1796 // If an array was passed in, assume that it is an array 1797 // of form elements 1798 if ( a.constructor == Array ) { 1799 // Serialize the form elements 1800 for ( var i = 0; i < a.length; i++ ) 1801 s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) ); 1802 1803 // Otherwise, assume that it's an object of key/value pairs 1804 } else { 1805 // Serialize the key/values 1806 for ( var j in a ) 1807 s.push( j + "=" + encodeURIComponent( a[j] ) ); 1808 } 1809 1810 // Return the resulting serialization 1811 return s.join("&"); 1812 } 1813 1814 });