annotate js-lib/jquery.js @ 79:343dc947f999 laserkard

read JavaSctipt: the good parts
author Robert McIntyre <rlm@mit.edu>
date Sun, 25 Jul 2010 01:33:22 -0400
parents
children
rev   line source
rlm@79 1 /*!
rlm@79 2 * jQuery JavaScript Library v1.4.2
rlm@79 3 * http://jquery.com/
rlm@79 4 *
rlm@79 5 * Copyright 2010, John Resig
rlm@79 6 * Dual licensed under the MIT or GPL Version 2 licenses.
rlm@79 7 * http://jquery.org/license
rlm@79 8 *
rlm@79 9 * Includes Sizzle.js
rlm@79 10 * http://sizzlejs.com/
rlm@79 11 * Copyright 2010, The Dojo Foundation
rlm@79 12 * Released under the MIT, BSD, and GPL Licenses.
rlm@79 13 *
rlm@79 14 * Date: Sat Feb 13 22:33:48 2010 -0500
rlm@79 15 */
rlm@79 16 (function( window, undefined ) {
rlm@79 17
rlm@79 18 // Define a local copy of jQuery
rlm@79 19 var jQuery = function( selector, context ) {
rlm@79 20 // The jQuery object is actually just the init constructor 'enhanced'
rlm@79 21 return new jQuery.fn.init( selector, context );
rlm@79 22 },
rlm@79 23
rlm@79 24 // Map over jQuery in case of overwrite
rlm@79 25 _jQuery = window.jQuery,
rlm@79 26
rlm@79 27 // Map over the $ in case of overwrite
rlm@79 28 _$ = window.$,
rlm@79 29
rlm@79 30 // Use the correct document accordingly with window argument (sandbox)
rlm@79 31 document = window.document,
rlm@79 32
rlm@79 33 // A central reference to the root jQuery(document)
rlm@79 34 rootjQuery,
rlm@79 35
rlm@79 36 // A simple way to check for HTML strings or ID strings
rlm@79 37 // (both of which we optimize for)
rlm@79 38 quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
rlm@79 39
rlm@79 40 // Is it a simple selector
rlm@79 41 isSimple = /^.[^:#\[\.,]*$/,
rlm@79 42
rlm@79 43 // Check if a string has a non-whitespace character in it
rlm@79 44 rnotwhite = /\S/,
rlm@79 45
rlm@79 46 // Used for trimming whitespace
rlm@79 47 rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
rlm@79 48
rlm@79 49 // Match a standalone tag
rlm@79 50 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
rlm@79 51
rlm@79 52 // Keep a UserAgent string for use with jQuery.browser
rlm@79 53 userAgent = navigator.userAgent,
rlm@79 54
rlm@79 55 // For matching the engine and version of the browser
rlm@79 56 browserMatch,
rlm@79 57
rlm@79 58 // Has the ready events already been bound?
rlm@79 59 readyBound = false,
rlm@79 60
rlm@79 61 // The functions to execute on DOM ready
rlm@79 62 readyList = [],
rlm@79 63
rlm@79 64 // The ready event handler
rlm@79 65 DOMContentLoaded,
rlm@79 66
rlm@79 67 // Save a reference to some core methods
rlm@79 68 toString = Object.prototype.toString,
rlm@79 69 hasOwnProperty = Object.prototype.hasOwnProperty,
rlm@79 70 push = Array.prototype.push,
rlm@79 71 slice = Array.prototype.slice,
rlm@79 72 indexOf = Array.prototype.indexOf;
rlm@79 73
rlm@79 74 jQuery.fn = jQuery.prototype = {
rlm@79 75 init: function( selector, context ) {
rlm@79 76 var match, elem, ret, doc;
rlm@79 77
rlm@79 78 // Handle $(""), $(null), or $(undefined)
rlm@79 79 if ( !selector ) {
rlm@79 80 return this;
rlm@79 81 }
rlm@79 82
rlm@79 83 // Handle $(DOMElement)
rlm@79 84 if ( selector.nodeType ) {
rlm@79 85 this.context = this[0] = selector;
rlm@79 86 this.length = 1;
rlm@79 87 return this;
rlm@79 88 }
rlm@79 89
rlm@79 90 // The body element only exists once, optimize finding it
rlm@79 91 if ( selector === "body" && !context ) {
rlm@79 92 this.context = document;
rlm@79 93 this[0] = document.body;
rlm@79 94 this.selector = "body";
rlm@79 95 this.length = 1;
rlm@79 96 return this;
rlm@79 97 }
rlm@79 98
rlm@79 99 // Handle HTML strings
rlm@79 100 if ( typeof selector === "string" ) {
rlm@79 101 // Are we dealing with HTML string or an ID?
rlm@79 102 match = quickExpr.exec( selector );
rlm@79 103
rlm@79 104 // Verify a match, and that no context was specified for #id
rlm@79 105 if ( match && (match[1] || !context) ) {
rlm@79 106
rlm@79 107 // HANDLE: $(html) -> $(array)
rlm@79 108 if ( match[1] ) {
rlm@79 109 doc = (context ? context.ownerDocument || context : document);
rlm@79 110
rlm@79 111 // If a single string is passed in and it's a single tag
rlm@79 112 // just do a createElement and skip the rest
rlm@79 113 ret = rsingleTag.exec( selector );
rlm@79 114
rlm@79 115 if ( ret ) {
rlm@79 116 if ( jQuery.isPlainObject( context ) ) {
rlm@79 117 selector = [ document.createElement( ret[1] ) ];
rlm@79 118 jQuery.fn.attr.call( selector, context, true );
rlm@79 119
rlm@79 120 } else {
rlm@79 121 selector = [ doc.createElement( ret[1] ) ];
rlm@79 122 }
rlm@79 123
rlm@79 124 } else {
rlm@79 125 ret = buildFragment( [ match[1] ], [ doc ] );
rlm@79 126 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
rlm@79 127 }
rlm@79 128
rlm@79 129 return jQuery.merge( this, selector );
rlm@79 130
rlm@79 131 // HANDLE: $("#id")
rlm@79 132 } else {
rlm@79 133 elem = document.getElementById( match[2] );
rlm@79 134
rlm@79 135 if ( elem ) {
rlm@79 136 // Handle the case where IE and Opera return items
rlm@79 137 // by name instead of ID
rlm@79 138 if ( elem.id !== match[2] ) {
rlm@79 139 return rootjQuery.find( selector );
rlm@79 140 }
rlm@79 141
rlm@79 142 // Otherwise, we inject the element directly into the jQuery object
rlm@79 143 this.length = 1;
rlm@79 144 this[0] = elem;
rlm@79 145 }
rlm@79 146
rlm@79 147 this.context = document;
rlm@79 148 this.selector = selector;
rlm@79 149 return this;
rlm@79 150 }
rlm@79 151
rlm@79 152 // HANDLE: $("TAG")
rlm@79 153 } else if ( !context && /^\w+$/.test( selector ) ) {
rlm@79 154 this.selector = selector;
rlm@79 155 this.context = document;
rlm@79 156 selector = document.getElementsByTagName( selector );
rlm@79 157 return jQuery.merge( this, selector );
rlm@79 158
rlm@79 159 // HANDLE: $(expr, $(...))
rlm@79 160 } else if ( !context || context.jquery ) {
rlm@79 161 return (context || rootjQuery).find( selector );
rlm@79 162
rlm@79 163 // HANDLE: $(expr, context)
rlm@79 164 // (which is just equivalent to: $(context).find(expr)
rlm@79 165 } else {
rlm@79 166 return jQuery( context ).find( selector );
rlm@79 167 }
rlm@79 168
rlm@79 169 // HANDLE: $(function)
rlm@79 170 // Shortcut for document ready
rlm@79 171 } else if ( jQuery.isFunction( selector ) ) {
rlm@79 172 return rootjQuery.ready( selector );
rlm@79 173 }
rlm@79 174
rlm@79 175 if (selector.selector !== undefined) {
rlm@79 176 this.selector = selector.selector;
rlm@79 177 this.context = selector.context;
rlm@79 178 }
rlm@79 179
rlm@79 180 return jQuery.makeArray( selector, this );
rlm@79 181 },
rlm@79 182
rlm@79 183 // Start with an empty selector
rlm@79 184 selector: "",
rlm@79 185
rlm@79 186 // The current version of jQuery being used
rlm@79 187 jquery: "1.4.2",
rlm@79 188
rlm@79 189 // The default length of a jQuery object is 0
rlm@79 190 length: 0,
rlm@79 191
rlm@79 192 // The number of elements contained in the matched element set
rlm@79 193 size: function() {
rlm@79 194 return this.length;
rlm@79 195 },
rlm@79 196
rlm@79 197 toArray: function() {
rlm@79 198 return slice.call( this, 0 );
rlm@79 199 },
rlm@79 200
rlm@79 201 // Get the Nth element in the matched element set OR
rlm@79 202 // Get the whole matched element set as a clean array
rlm@79 203 get: function( num ) {
rlm@79 204 return num == null ?
rlm@79 205
rlm@79 206 // Return a 'clean' array
rlm@79 207 this.toArray() :
rlm@79 208
rlm@79 209 // Return just the object
rlm@79 210 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
rlm@79 211 },
rlm@79 212
rlm@79 213 // Take an array of elements and push it onto the stack
rlm@79 214 // (returning the new matched element set)
rlm@79 215 pushStack: function( elems, name, selector ) {
rlm@79 216 // Build a new jQuery matched element set
rlm@79 217 var ret = jQuery();
rlm@79 218
rlm@79 219 if ( jQuery.isArray( elems ) ) {
rlm@79 220 push.apply( ret, elems );
rlm@79 221
rlm@79 222 } else {
rlm@79 223 jQuery.merge( ret, elems );
rlm@79 224 }
rlm@79 225
rlm@79 226 // Add the old object onto the stack (as a reference)
rlm@79 227 ret.prevObject = this;
rlm@79 228
rlm@79 229 ret.context = this.context;
rlm@79 230
rlm@79 231 if ( name === "find" ) {
rlm@79 232 ret.selector = this.selector + (this.selector ? " " : "") + selector;
rlm@79 233 } else if ( name ) {
rlm@79 234 ret.selector = this.selector + "." + name + "(" + selector + ")";
rlm@79 235 }
rlm@79 236
rlm@79 237 // Return the newly-formed element set
rlm@79 238 return ret;
rlm@79 239 },
rlm@79 240
rlm@79 241 // Execute a callback for every element in the matched set.
rlm@79 242 // (You can seed the arguments with an array of args, but this is
rlm@79 243 // only used internally.)
rlm@79 244 each: function( callback, args ) {
rlm@79 245 return jQuery.each( this, callback, args );
rlm@79 246 },
rlm@79 247
rlm@79 248 ready: function( fn ) {
rlm@79 249 // Attach the listeners
rlm@79 250 jQuery.bindReady();
rlm@79 251
rlm@79 252 // If the DOM is already ready
rlm@79 253 if ( jQuery.isReady ) {
rlm@79 254 // Execute the function immediately
rlm@79 255 fn.call( document, jQuery );
rlm@79 256
rlm@79 257 // Otherwise, remember the function for later
rlm@79 258 } else if ( readyList ) {
rlm@79 259 // Add the function to the wait list
rlm@79 260 readyList.push( fn );
rlm@79 261 }
rlm@79 262
rlm@79 263 return this;
rlm@79 264 },
rlm@79 265
rlm@79 266 eq: function( i ) {
rlm@79 267 return i === -1 ?
rlm@79 268 this.slice( i ) :
rlm@79 269 this.slice( i, +i + 1 );
rlm@79 270 },
rlm@79 271
rlm@79 272 first: function() {
rlm@79 273 return this.eq( 0 );
rlm@79 274 },
rlm@79 275
rlm@79 276 last: function() {
rlm@79 277 return this.eq( -1 );
rlm@79 278 },
rlm@79 279
rlm@79 280 slice: function() {
rlm@79 281 return this.pushStack( slice.apply( this, arguments ),
rlm@79 282 "slice", slice.call(arguments).join(",") );
rlm@79 283 },
rlm@79 284
rlm@79 285 map: function( callback ) {
rlm@79 286 return this.pushStack( jQuery.map(this, function( elem, i ) {
rlm@79 287 return callback.call( elem, i, elem );
rlm@79 288 }));
rlm@79 289 },
rlm@79 290
rlm@79 291 end: function() {
rlm@79 292 return this.prevObject || jQuery(null);
rlm@79 293 },
rlm@79 294
rlm@79 295 // For internal use only.
rlm@79 296 // Behaves like an Array's method, not like a jQuery method.
rlm@79 297 push: push,
rlm@79 298 sort: [].sort,
rlm@79 299 splice: [].splice
rlm@79 300 };
rlm@79 301
rlm@79 302 // Give the init function the jQuery prototype for later instantiation
rlm@79 303 jQuery.fn.init.prototype = jQuery.fn;
rlm@79 304
rlm@79 305 jQuery.extend = jQuery.fn.extend = function() {
rlm@79 306 // copy reference to target object
rlm@79 307 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
rlm@79 308
rlm@79 309 // Handle a deep copy situation
rlm@79 310 if ( typeof target === "boolean" ) {
rlm@79 311 deep = target;
rlm@79 312 target = arguments[1] || {};
rlm@79 313 // skip the boolean and the target
rlm@79 314 i = 2;
rlm@79 315 }
rlm@79 316
rlm@79 317 // Handle case when target is a string or something (possible in deep copy)
rlm@79 318 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
rlm@79 319 target = {};
rlm@79 320 }
rlm@79 321
rlm@79 322 // extend jQuery itself if only one argument is passed
rlm@79 323 if ( length === i ) {
rlm@79 324 target = this;
rlm@79 325 --i;
rlm@79 326 }
rlm@79 327
rlm@79 328 for ( ; i < length; i++ ) {
rlm@79 329 // Only deal with non-null/undefined values
rlm@79 330 if ( (options = arguments[ i ]) != null ) {
rlm@79 331 // Extend the base object
rlm@79 332 for ( name in options ) {
rlm@79 333 src = target[ name ];
rlm@79 334 copy = options[ name ];
rlm@79 335
rlm@79 336 // Prevent never-ending loop
rlm@79 337 if ( target === copy ) {
rlm@79 338 continue;
rlm@79 339 }
rlm@79 340
rlm@79 341 // Recurse if we're merging object literal values or arrays
rlm@79 342 if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
rlm@79 343 var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
rlm@79 344 : jQuery.isArray(copy) ? [] : {};
rlm@79 345
rlm@79 346 // Never move original objects, clone them
rlm@79 347 target[ name ] = jQuery.extend( deep, clone, copy );
rlm@79 348
rlm@79 349 // Don't bring in undefined values
rlm@79 350 } else if ( copy !== undefined ) {
rlm@79 351 target[ name ] = copy;
rlm@79 352 }
rlm@79 353 }
rlm@79 354 }
rlm@79 355 }
rlm@79 356
rlm@79 357 // Return the modified object
rlm@79 358 return target;
rlm@79 359 };
rlm@79 360
rlm@79 361 jQuery.extend({
rlm@79 362 noConflict: function( deep ) {
rlm@79 363 window.$ = _$;
rlm@79 364
rlm@79 365 if ( deep ) {
rlm@79 366 window.jQuery = _jQuery;
rlm@79 367 }
rlm@79 368
rlm@79 369 return jQuery;
rlm@79 370 },
rlm@79 371
rlm@79 372 // Is the DOM ready to be used? Set to true once it occurs.
rlm@79 373 isReady: false,
rlm@79 374
rlm@79 375 // Handle when the DOM is ready
rlm@79 376 ready: function() {
rlm@79 377 // Make sure that the DOM is not already loaded
rlm@79 378 if ( !jQuery.isReady ) {
rlm@79 379 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
rlm@79 380 if ( !document.body ) {
rlm@79 381 return setTimeout( jQuery.ready, 13 );
rlm@79 382 }
rlm@79 383
rlm@79 384 // Remember that the DOM is ready
rlm@79 385 jQuery.isReady = true;
rlm@79 386
rlm@79 387 // If there are functions bound, to execute
rlm@79 388 if ( readyList ) {
rlm@79 389 // Execute all of them
rlm@79 390 var fn, i = 0;
rlm@79 391 while ( (fn = readyList[ i++ ]) ) {
rlm@79 392 fn.call( document, jQuery );
rlm@79 393 }
rlm@79 394
rlm@79 395 // Reset the list of functions
rlm@79 396 readyList = null;
rlm@79 397 }
rlm@79 398
rlm@79 399 // Trigger any bound ready events
rlm@79 400 if ( jQuery.fn.triggerHandler ) {
rlm@79 401 jQuery( document ).triggerHandler( "ready" );
rlm@79 402 }
rlm@79 403 }
rlm@79 404 },
rlm@79 405
rlm@79 406 bindReady: function() {
rlm@79 407 if ( readyBound ) {
rlm@79 408 return;
rlm@79 409 }
rlm@79 410
rlm@79 411 readyBound = true;
rlm@79 412
rlm@79 413 // Catch cases where $(document).ready() is called after the
rlm@79 414 // browser event has already occurred.
rlm@79 415 if ( document.readyState === "complete" ) {
rlm@79 416 return jQuery.ready();
rlm@79 417 }
rlm@79 418
rlm@79 419 // Mozilla, Opera and webkit nightlies currently support this event
rlm@79 420 if ( document.addEventListener ) {
rlm@79 421 // Use the handy event callback
rlm@79 422 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
rlm@79 423
rlm@79 424 // A fallback to window.onload, that will always work
rlm@79 425 window.addEventListener( "load", jQuery.ready, false );
rlm@79 426
rlm@79 427 // If IE event model is used
rlm@79 428 } else if ( document.attachEvent ) {
rlm@79 429 // ensure firing before onload,
rlm@79 430 // maybe late but safe also for iframes
rlm@79 431 document.attachEvent("onreadystatechange", DOMContentLoaded);
rlm@79 432
rlm@79 433 // A fallback to window.onload, that will always work
rlm@79 434 window.attachEvent( "onload", jQuery.ready );
rlm@79 435
rlm@79 436 // If IE and not a frame
rlm@79 437 // continually check to see if the document is ready
rlm@79 438 var toplevel = false;
rlm@79 439
rlm@79 440 try {
rlm@79 441 toplevel = window.frameElement == null;
rlm@79 442 } catch(e) {}
rlm@79 443
rlm@79 444 if ( document.documentElement.doScroll && toplevel ) {
rlm@79 445 doScrollCheck();
rlm@79 446 }
rlm@79 447 }
rlm@79 448 },
rlm@79 449
rlm@79 450 // See test/unit/core.js for details concerning isFunction.
rlm@79 451 // Since version 1.3, DOM methods and functions like alert
rlm@79 452 // aren't supported. They return false on IE (#2968).
rlm@79 453 isFunction: function( obj ) {
rlm@79 454 return toString.call(obj) === "[object Function]";
rlm@79 455 },
rlm@79 456
rlm@79 457 isArray: function( obj ) {
rlm@79 458 return toString.call(obj) === "[object Array]";
rlm@79 459 },
rlm@79 460
rlm@79 461 isPlainObject: function( obj ) {
rlm@79 462 // Must be an Object.
rlm@79 463 // Because of IE, we also have to check the presence of the constructor property.
rlm@79 464 // Make sure that DOM nodes and window objects don't pass through, as well
rlm@79 465 if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
rlm@79 466 return false;
rlm@79 467 }
rlm@79 468
rlm@79 469 // Not own constructor property must be Object
rlm@79 470 if ( obj.constructor
rlm@79 471 && !hasOwnProperty.call(obj, "constructor")
rlm@79 472 && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
rlm@79 473 return false;
rlm@79 474 }
rlm@79 475
rlm@79 476 // Own properties are enumerated firstly, so to speed up,
rlm@79 477 // if last one is own, then all properties are own.
rlm@79 478
rlm@79 479 var key;
rlm@79 480 for ( key in obj ) {}
rlm@79 481
rlm@79 482 return key === undefined || hasOwnProperty.call( obj, key );
rlm@79 483 },
rlm@79 484
rlm@79 485 isEmptyObject: function( obj ) {
rlm@79 486 for ( var name in obj ) {
rlm@79 487 return false;
rlm@79 488 }
rlm@79 489 return true;
rlm@79 490 },
rlm@79 491
rlm@79 492 error: function( msg ) {
rlm@79 493 throw msg;
rlm@79 494 },
rlm@79 495
rlm@79 496 parseJSON: function( data ) {
rlm@79 497 if ( typeof data !== "string" || !data ) {
rlm@79 498 return null;
rlm@79 499 }
rlm@79 500
rlm@79 501 // Make sure leading/trailing whitespace is removed (IE can't handle it)
rlm@79 502 data = jQuery.trim( data );
rlm@79 503
rlm@79 504 // Make sure the incoming data is actual JSON
rlm@79 505 // Logic borrowed from http://json.org/json2.js
rlm@79 506 if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
rlm@79 507 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
rlm@79 508 .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
rlm@79 509
rlm@79 510 // Try to use the native JSON parser first
rlm@79 511 return window.JSON && window.JSON.parse ?
rlm@79 512 window.JSON.parse( data ) :
rlm@79 513 (new Function("return " + data))();
rlm@79 514
rlm@79 515 } else {
rlm@79 516 jQuery.error( "Invalid JSON: " + data );
rlm@79 517 }
rlm@79 518 },
rlm@79 519
rlm@79 520 noop: function() {},
rlm@79 521
rlm@79 522 // Evalulates a script in a global context
rlm@79 523 globalEval: function( data ) {
rlm@79 524 if ( data && rnotwhite.test(data) ) {
rlm@79 525 // Inspired by code by Andrea Giammarchi
rlm@79 526 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
rlm@79 527 var head = document.getElementsByTagName("head")[0] || document.documentElement,
rlm@79 528 script = document.createElement("script");
rlm@79 529
rlm@79 530 script.type = "text/javascript";
rlm@79 531
rlm@79 532 if ( jQuery.support.scriptEval ) {
rlm@79 533 script.appendChild( document.createTextNode( data ) );
rlm@79 534 } else {
rlm@79 535 script.text = data;
rlm@79 536 }
rlm@79 537
rlm@79 538 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
rlm@79 539 // This arises when a base node is used (#2709).
rlm@79 540 head.insertBefore( script, head.firstChild );
rlm@79 541 head.removeChild( script );
rlm@79 542 }
rlm@79 543 },
rlm@79 544
rlm@79 545 nodeName: function( elem, name ) {
rlm@79 546 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
rlm@79 547 },
rlm@79 548
rlm@79 549 // args is for internal usage only
rlm@79 550 each: function( object, callback, args ) {
rlm@79 551 var name, i = 0,
rlm@79 552 length = object.length,
rlm@79 553 isObj = length === undefined || jQuery.isFunction(object);
rlm@79 554
rlm@79 555 if ( args ) {
rlm@79 556 if ( isObj ) {
rlm@79 557 for ( name in object ) {
rlm@79 558 if ( callback.apply( object[ name ], args ) === false ) {
rlm@79 559 break;
rlm@79 560 }
rlm@79 561 }
rlm@79 562 } else {
rlm@79 563 for ( ; i < length; ) {
rlm@79 564 if ( callback.apply( object[ i++ ], args ) === false ) {
rlm@79 565 break;
rlm@79 566 }
rlm@79 567 }
rlm@79 568 }
rlm@79 569
rlm@79 570 // A special, fast, case for the most common use of each
rlm@79 571 } else {
rlm@79 572 if ( isObj ) {
rlm@79 573 for ( name in object ) {
rlm@79 574 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
rlm@79 575 break;
rlm@79 576 }
rlm@79 577 }
rlm@79 578 } else {
rlm@79 579 for ( var value = object[0];
rlm@79 580 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
rlm@79 581 }
rlm@79 582 }
rlm@79 583
rlm@79 584 return object;
rlm@79 585 },
rlm@79 586
rlm@79 587 trim: function( text ) {
rlm@79 588 return (text || "").replace( rtrim, "" );
rlm@79 589 },
rlm@79 590
rlm@79 591 // results is for internal usage only
rlm@79 592 makeArray: function( array, results ) {
rlm@79 593 var ret = results || [];
rlm@79 594
rlm@79 595 if ( array != null ) {
rlm@79 596 // The window, strings (and functions) also have 'length'
rlm@79 597 // The extra typeof function check is to prevent crashes
rlm@79 598 // in Safari 2 (See: #3039)
rlm@79 599 if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
rlm@79 600 push.call( ret, array );
rlm@79 601 } else {
rlm@79 602 jQuery.merge( ret, array );
rlm@79 603 }
rlm@79 604 }
rlm@79 605
rlm@79 606 return ret;
rlm@79 607 },
rlm@79 608
rlm@79 609 inArray: function( elem, array ) {
rlm@79 610 if ( array.indexOf ) {
rlm@79 611 return array.indexOf( elem );
rlm@79 612 }
rlm@79 613
rlm@79 614 for ( var i = 0, length = array.length; i < length; i++ ) {
rlm@79 615 if ( array[ i ] === elem ) {
rlm@79 616 return i;
rlm@79 617 }
rlm@79 618 }
rlm@79 619
rlm@79 620 return -1;
rlm@79 621 },
rlm@79 622
rlm@79 623 merge: function( first, second ) {
rlm@79 624 var i = first.length, j = 0;
rlm@79 625
rlm@79 626 if ( typeof second.length === "number" ) {
rlm@79 627 for ( var l = second.length; j < l; j++ ) {
rlm@79 628 first[ i++ ] = second[ j ];
rlm@79 629 }
rlm@79 630
rlm@79 631 } else {
rlm@79 632 while ( second[j] !== undefined ) {
rlm@79 633 first[ i++ ] = second[ j++ ];
rlm@79 634 }
rlm@79 635 }
rlm@79 636
rlm@79 637 first.length = i;
rlm@79 638
rlm@79 639 return first;
rlm@79 640 },
rlm@79 641
rlm@79 642 grep: function( elems, callback, inv ) {
rlm@79 643 var ret = [];
rlm@79 644
rlm@79 645 // Go through the array, only saving the items
rlm@79 646 // that pass the validator function
rlm@79 647 for ( var i = 0, length = elems.length; i < length; i++ ) {
rlm@79 648 if ( !inv !== !callback( elems[ i ], i ) ) {
rlm@79 649 ret.push( elems[ i ] );
rlm@79 650 }
rlm@79 651 }
rlm@79 652
rlm@79 653 return ret;
rlm@79 654 },
rlm@79 655
rlm@79 656 // arg is for internal usage only
rlm@79 657 map: function( elems, callback, arg ) {
rlm@79 658 var ret = [], value;
rlm@79 659
rlm@79 660 // Go through the array, translating each of the items to their
rlm@79 661 // new value (or values).
rlm@79 662 for ( var i = 0, length = elems.length; i < length; i++ ) {
rlm@79 663 value = callback( elems[ i ], i, arg );
rlm@79 664
rlm@79 665 if ( value != null ) {
rlm@79 666 ret[ ret.length ] = value;
rlm@79 667 }
rlm@79 668 }
rlm@79 669
rlm@79 670 return ret.concat.apply( [], ret );
rlm@79 671 },
rlm@79 672
rlm@79 673 // A global GUID counter for objects
rlm@79 674 guid: 1,
rlm@79 675
rlm@79 676 proxy: function( fn, proxy, thisObject ) {
rlm@79 677 if ( arguments.length === 2 ) {
rlm@79 678 if ( typeof proxy === "string" ) {
rlm@79 679 thisObject = fn;
rlm@79 680 fn = thisObject[ proxy ];
rlm@79 681 proxy = undefined;
rlm@79 682
rlm@79 683 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
rlm@79 684 thisObject = proxy;
rlm@79 685 proxy = undefined;
rlm@79 686 }
rlm@79 687 }
rlm@79 688
rlm@79 689 if ( !proxy && fn ) {
rlm@79 690 proxy = function() {
rlm@79 691 return fn.apply( thisObject || this, arguments );
rlm@79 692 };
rlm@79 693 }
rlm@79 694
rlm@79 695 // Set the guid of unique handler to the same of original handler, so it can be removed
rlm@79 696 if ( fn ) {
rlm@79 697 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
rlm@79 698 }
rlm@79 699
rlm@79 700 // So proxy can be declared as an argument
rlm@79 701 return proxy;
rlm@79 702 },
rlm@79 703
rlm@79 704 // Use of jQuery.browser is frowned upon.
rlm@79 705 // More details: http://docs.jquery.com/Utilities/jQuery.browser
rlm@79 706 uaMatch: function( ua ) {
rlm@79 707 ua = ua.toLowerCase();
rlm@79 708
rlm@79 709 var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
rlm@79 710 /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
rlm@79 711 /(msie) ([\w.]+)/.exec( ua ) ||
rlm@79 712 !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
rlm@79 713 [];
rlm@79 714
rlm@79 715 return { browser: match[1] || "", version: match[2] || "0" };
rlm@79 716 },
rlm@79 717
rlm@79 718 browser: {}
rlm@79 719 });
rlm@79 720
rlm@79 721 browserMatch = jQuery.uaMatch( userAgent );
rlm@79 722 if ( browserMatch.browser ) {
rlm@79 723 jQuery.browser[ browserMatch.browser ] = true;
rlm@79 724 jQuery.browser.version = browserMatch.version;
rlm@79 725 }
rlm@79 726
rlm@79 727 // Deprecated, use jQuery.browser.webkit instead
rlm@79 728 if ( jQuery.browser.webkit ) {
rlm@79 729 jQuery.browser.safari = true;
rlm@79 730 }
rlm@79 731
rlm@79 732 if ( indexOf ) {
rlm@79 733 jQuery.inArray = function( elem, array ) {
rlm@79 734 return indexOf.call( array, elem );
rlm@79 735 };
rlm@79 736 }
rlm@79 737
rlm@79 738 // All jQuery objects should point back to these
rlm@79 739 rootjQuery = jQuery(document);
rlm@79 740
rlm@79 741 // Cleanup functions for the document ready method
rlm@79 742 if ( document.addEventListener ) {
rlm@79 743 DOMContentLoaded = function() {
rlm@79 744 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
rlm@79 745 jQuery.ready();
rlm@79 746 };
rlm@79 747
rlm@79 748 } else if ( document.attachEvent ) {
rlm@79 749 DOMContentLoaded = function() {
rlm@79 750 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
rlm@79 751 if ( document.readyState === "complete" ) {
rlm@79 752 document.detachEvent( "onreadystatechange", DOMContentLoaded );
rlm@79 753 jQuery.ready();
rlm@79 754 }
rlm@79 755 };
rlm@79 756 }
rlm@79 757
rlm@79 758 // The DOM ready check for Internet Explorer
rlm@79 759 function doScrollCheck() {
rlm@79 760 if ( jQuery.isReady ) {
rlm@79 761 return;
rlm@79 762 }
rlm@79 763
rlm@79 764 try {
rlm@79 765 // If IE is used, use the trick by Diego Perini
rlm@79 766 // http://javascript.nwbox.com/IEContentLoaded/
rlm@79 767 document.documentElement.doScroll("left");
rlm@79 768 } catch( error ) {
rlm@79 769 setTimeout( doScrollCheck, 1 );
rlm@79 770 return;
rlm@79 771 }
rlm@79 772
rlm@79 773 // and execute any waiting functions
rlm@79 774 jQuery.ready();
rlm@79 775 }
rlm@79 776
rlm@79 777 function evalScript( i, elem ) {
rlm@79 778 if ( elem.src ) {
rlm@79 779 jQuery.ajax({
rlm@79 780 url: elem.src,
rlm@79 781 async: false,
rlm@79 782 dataType: "script"
rlm@79 783 });
rlm@79 784 } else {
rlm@79 785 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
rlm@79 786 }
rlm@79 787
rlm@79 788 if ( elem.parentNode ) {
rlm@79 789 elem.parentNode.removeChild( elem );
rlm@79 790 }
rlm@79 791 }
rlm@79 792
rlm@79 793 // Mutifunctional method to get and set values to a collection
rlm@79 794 // The value/s can be optionally by executed if its a function
rlm@79 795 function access( elems, key, value, exec, fn, pass ) {
rlm@79 796 var length = elems.length;
rlm@79 797
rlm@79 798 // Setting many attributes
rlm@79 799 if ( typeof key === "object" ) {
rlm@79 800 for ( var k in key ) {
rlm@79 801 access( elems, k, key[k], exec, fn, value );
rlm@79 802 }
rlm@79 803 return elems;
rlm@79 804 }
rlm@79 805
rlm@79 806 // Setting one attribute
rlm@79 807 if ( value !== undefined ) {
rlm@79 808 // Optionally, function values get executed if exec is true
rlm@79 809 exec = !pass && exec && jQuery.isFunction(value);
rlm@79 810
rlm@79 811 for ( var i = 0; i < length; i++ ) {
rlm@79 812 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
rlm@79 813 }
rlm@79 814
rlm@79 815 return elems;
rlm@79 816 }
rlm@79 817
rlm@79 818 // Getting an attribute
rlm@79 819 return length ? fn( elems[0], key ) : undefined;
rlm@79 820 }
rlm@79 821
rlm@79 822 function now() {
rlm@79 823 return (new Date).getTime();
rlm@79 824 }
rlm@79 825 (function() {
rlm@79 826
rlm@79 827 jQuery.support = {};
rlm@79 828
rlm@79 829 var root = document.documentElement,
rlm@79 830 script = document.createElement("script"),
rlm@79 831 div = document.createElement("div"),
rlm@79 832 id = "script" + now();
rlm@79 833
rlm@79 834 div.style.display = "none";
rlm@79 835 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
rlm@79 836
rlm@79 837 var all = div.getElementsByTagName("*"),
rlm@79 838 a = div.getElementsByTagName("a")[0];
rlm@79 839
rlm@79 840 // Can't get basic test support
rlm@79 841 if ( !all || !all.length || !a ) {
rlm@79 842 return;
rlm@79 843 }
rlm@79 844
rlm@79 845 jQuery.support = {
rlm@79 846 // IE strips leading whitespace when .innerHTML is used
rlm@79 847 leadingWhitespace: div.firstChild.nodeType === 3,
rlm@79 848
rlm@79 849 // Make sure that tbody elements aren't automatically inserted
rlm@79 850 // IE will insert them into empty tables
rlm@79 851 tbody: !div.getElementsByTagName("tbody").length,
rlm@79 852
rlm@79 853 // Make sure that link elements get serialized correctly by innerHTML
rlm@79 854 // This requires a wrapper element in IE
rlm@79 855 htmlSerialize: !!div.getElementsByTagName("link").length,
rlm@79 856
rlm@79 857 // Get the style information from getAttribute
rlm@79 858 // (IE uses .cssText insted)
rlm@79 859 style: /red/.test( a.getAttribute("style") ),
rlm@79 860
rlm@79 861 // Make sure that URLs aren't manipulated
rlm@79 862 // (IE normalizes it by default)
rlm@79 863 hrefNormalized: a.getAttribute("href") === "/a",
rlm@79 864
rlm@79 865 // Make sure that element opacity exists
rlm@79 866 // (IE uses filter instead)
rlm@79 867 // Use a regex to work around a WebKit issue. See #5145
rlm@79 868 opacity: /^0.55$/.test( a.style.opacity ),
rlm@79 869
rlm@79 870 // Verify style float existence
rlm@79 871 // (IE uses styleFloat instead of cssFloat)
rlm@79 872 cssFloat: !!a.style.cssFloat,
rlm@79 873
rlm@79 874 // Make sure that if no value is specified for a checkbox
rlm@79 875 // that it defaults to "on".
rlm@79 876 // (WebKit defaults to "" instead)
rlm@79 877 checkOn: div.getElementsByTagName("input")[0].value === "on",
rlm@79 878
rlm@79 879 // Make sure that a selected-by-default option has a working selected property.
rlm@79 880 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
rlm@79 881 optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
rlm@79 882
rlm@79 883 parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
rlm@79 884
rlm@79 885 // Will be defined later
rlm@79 886 deleteExpando: true,
rlm@79 887 checkClone: false,
rlm@79 888 scriptEval: false,
rlm@79 889 noCloneEvent: true,
rlm@79 890 boxModel: null
rlm@79 891 };
rlm@79 892
rlm@79 893 script.type = "text/javascript";
rlm@79 894 try {
rlm@79 895 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
rlm@79 896 } catch(e) {}
rlm@79 897
rlm@79 898 root.insertBefore( script, root.firstChild );
rlm@79 899
rlm@79 900 // Make sure that the execution of code works by injecting a script
rlm@79 901 // tag with appendChild/createTextNode
rlm@79 902 // (IE doesn't support this, fails, and uses .text instead)
rlm@79 903 if ( window[ id ] ) {
rlm@79 904 jQuery.support.scriptEval = true;
rlm@79 905 delete window[ id ];
rlm@79 906 }
rlm@79 907
rlm@79 908 // Test to see if it's possible to delete an expando from an element
rlm@79 909 // Fails in Internet Explorer
rlm@79 910 try {
rlm@79 911 delete script.test;
rlm@79 912
rlm@79 913 } catch(e) {
rlm@79 914 jQuery.support.deleteExpando = false;
rlm@79 915 }
rlm@79 916
rlm@79 917 root.removeChild( script );
rlm@79 918
rlm@79 919 if ( div.attachEvent && div.fireEvent ) {
rlm@79 920 div.attachEvent("onclick", function click() {
rlm@79 921 // Cloning a node shouldn't copy over any
rlm@79 922 // bound event handlers (IE does this)
rlm@79 923 jQuery.support.noCloneEvent = false;
rlm@79 924 div.detachEvent("onclick", click);
rlm@79 925 });
rlm@79 926 div.cloneNode(true).fireEvent("onclick");
rlm@79 927 }
rlm@79 928
rlm@79 929 div = document.createElement("div");
rlm@79 930 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
rlm@79 931
rlm@79 932 var fragment = document.createDocumentFragment();
rlm@79 933 fragment.appendChild( div.firstChild );
rlm@79 934
rlm@79 935 // WebKit doesn't clone checked state correctly in fragments
rlm@79 936 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
rlm@79 937
rlm@79 938 // Figure out if the W3C box model works as expected
rlm@79 939 // document.body must exist before we can do this
rlm@79 940 jQuery(function() {
rlm@79 941 var div = document.createElement("div");
rlm@79 942 div.style.width = div.style.paddingLeft = "1px";
rlm@79 943
rlm@79 944 document.body.appendChild( div );
rlm@79 945 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
rlm@79 946 document.body.removeChild( div ).style.display = 'none';
rlm@79 947
rlm@79 948 div = null;
rlm@79 949 });
rlm@79 950
rlm@79 951 // Technique from Juriy Zaytsev
rlm@79 952 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
rlm@79 953 var eventSupported = function( eventName ) {
rlm@79 954 var el = document.createElement("div");
rlm@79 955 eventName = "on" + eventName;
rlm@79 956
rlm@79 957 var isSupported = (eventName in el);
rlm@79 958 if ( !isSupported ) {
rlm@79 959 el.setAttribute(eventName, "return;");
rlm@79 960 isSupported = typeof el[eventName] === "function";
rlm@79 961 }
rlm@79 962 el = null;
rlm@79 963
rlm@79 964 return isSupported;
rlm@79 965 };
rlm@79 966
rlm@79 967 jQuery.support.submitBubbles = eventSupported("submit");
rlm@79 968 jQuery.support.changeBubbles = eventSupported("change");
rlm@79 969
rlm@79 970 // release memory in IE
rlm@79 971 root = script = div = all = a = null;
rlm@79 972 })();
rlm@79 973
rlm@79 974 jQuery.props = {
rlm@79 975 "for": "htmlFor",
rlm@79 976 "class": "className",
rlm@79 977 readonly: "readOnly",
rlm@79 978 maxlength: "maxLength",
rlm@79 979 cellspacing: "cellSpacing",
rlm@79 980 rowspan: "rowSpan",
rlm@79 981 colspan: "colSpan",
rlm@79 982 tabindex: "tabIndex",
rlm@79 983 usemap: "useMap",
rlm@79 984 frameborder: "frameBorder"
rlm@79 985 };
rlm@79 986 var expando = "jQuery" + now(), uuid = 0, windowData = {};
rlm@79 987
rlm@79 988 jQuery.extend({
rlm@79 989 cache: {},
rlm@79 990
rlm@79 991 expando:expando,
rlm@79 992
rlm@79 993 // The following elements throw uncatchable exceptions if you
rlm@79 994 // attempt to add expando properties to them.
rlm@79 995 noData: {
rlm@79 996 "embed": true,
rlm@79 997 "object": true,
rlm@79 998 "applet": true
rlm@79 999 },
rlm@79 1000
rlm@79 1001 data: function( elem, name, data ) {
rlm@79 1002 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
rlm@79 1003 return;
rlm@79 1004 }
rlm@79 1005
rlm@79 1006 elem = elem == window ?
rlm@79 1007 windowData :
rlm@79 1008 elem;
rlm@79 1009
rlm@79 1010 var id = elem[ expando ], cache = jQuery.cache, thisCache;
rlm@79 1011
rlm@79 1012 if ( !id && typeof name === "string" && data === undefined ) {
rlm@79 1013 return null;
rlm@79 1014 }
rlm@79 1015
rlm@79 1016 // Compute a unique ID for the element
rlm@79 1017 if ( !id ) {
rlm@79 1018 id = ++uuid;
rlm@79 1019 }
rlm@79 1020
rlm@79 1021 // Avoid generating a new cache unless none exists and we
rlm@79 1022 // want to manipulate it.
rlm@79 1023 if ( typeof name === "object" ) {
rlm@79 1024 elem[ expando ] = id;
rlm@79 1025 thisCache = cache[ id ] = jQuery.extend(true, {}, name);
rlm@79 1026
rlm@79 1027 } else if ( !cache[ id ] ) {
rlm@79 1028 elem[ expando ] = id;
rlm@79 1029 cache[ id ] = {};
rlm@79 1030 }
rlm@79 1031
rlm@79 1032 thisCache = cache[ id ];
rlm@79 1033
rlm@79 1034 // Prevent overriding the named cache with undefined values
rlm@79 1035 if ( data !== undefined ) {
rlm@79 1036 thisCache[ name ] = data;
rlm@79 1037 }
rlm@79 1038
rlm@79 1039 return typeof name === "string" ? thisCache[ name ] : thisCache;
rlm@79 1040 },
rlm@79 1041
rlm@79 1042 removeData: function( elem, name ) {
rlm@79 1043 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
rlm@79 1044 return;
rlm@79 1045 }
rlm@79 1046
rlm@79 1047 elem = elem == window ?
rlm@79 1048 windowData :
rlm@79 1049 elem;
rlm@79 1050
rlm@79 1051 var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
rlm@79 1052
rlm@79 1053 // If we want to remove a specific section of the element's data
rlm@79 1054 if ( name ) {
rlm@79 1055 if ( thisCache ) {
rlm@79 1056 // Remove the section of cache data
rlm@79 1057 delete thisCache[ name ];
rlm@79 1058
rlm@79 1059 // If we've removed all the data, remove the element's cache
rlm@79 1060 if ( jQuery.isEmptyObject(thisCache) ) {
rlm@79 1061 jQuery.removeData( elem );
rlm@79 1062 }
rlm@79 1063 }
rlm@79 1064
rlm@79 1065 // Otherwise, we want to remove all of the element's data
rlm@79 1066 } else {
rlm@79 1067 if ( jQuery.support.deleteExpando ) {
rlm@79 1068 delete elem[ jQuery.expando ];
rlm@79 1069
rlm@79 1070 } else if ( elem.removeAttribute ) {
rlm@79 1071 elem.removeAttribute( jQuery.expando );
rlm@79 1072 }
rlm@79 1073
rlm@79 1074 // Completely remove the data cache
rlm@79 1075 delete cache[ id ];
rlm@79 1076 }
rlm@79 1077 }
rlm@79 1078 });
rlm@79 1079
rlm@79 1080 jQuery.fn.extend({
rlm@79 1081 data: function( key, value ) {
rlm@79 1082 if ( typeof key === "undefined" && this.length ) {
rlm@79 1083 return jQuery.data( this[0] );
rlm@79 1084
rlm@79 1085 } else if ( typeof key === "object" ) {
rlm@79 1086 return this.each(function() {
rlm@79 1087 jQuery.data( this, key );
rlm@79 1088 });
rlm@79 1089 }
rlm@79 1090
rlm@79 1091 var parts = key.split(".");
rlm@79 1092 parts[1] = parts[1] ? "." + parts[1] : "";
rlm@79 1093
rlm@79 1094 if ( value === undefined ) {
rlm@79 1095 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
rlm@79 1096
rlm@79 1097 if ( data === undefined && this.length ) {
rlm@79 1098 data = jQuery.data( this[0], key );
rlm@79 1099 }
rlm@79 1100 return data === undefined && parts[1] ?
rlm@79 1101 this.data( parts[0] ) :
rlm@79 1102 data;
rlm@79 1103 } else {
rlm@79 1104 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
rlm@79 1105 jQuery.data( this, key, value );
rlm@79 1106 });
rlm@79 1107 }
rlm@79 1108 },
rlm@79 1109
rlm@79 1110 removeData: function( key ) {
rlm@79 1111 return this.each(function() {
rlm@79 1112 jQuery.removeData( this, key );
rlm@79 1113 });
rlm@79 1114 }
rlm@79 1115 });
rlm@79 1116 jQuery.extend({
rlm@79 1117 queue: function( elem, type, data ) {
rlm@79 1118 if ( !elem ) {
rlm@79 1119 return;
rlm@79 1120 }
rlm@79 1121
rlm@79 1122 type = (type || "fx") + "queue";
rlm@79 1123 var q = jQuery.data( elem, type );
rlm@79 1124
rlm@79 1125 // Speed up dequeue by getting out quickly if this is just a lookup
rlm@79 1126 if ( !data ) {
rlm@79 1127 return q || [];
rlm@79 1128 }
rlm@79 1129
rlm@79 1130 if ( !q || jQuery.isArray(data) ) {
rlm@79 1131 q = jQuery.data( elem, type, jQuery.makeArray(data) );
rlm@79 1132
rlm@79 1133 } else {
rlm@79 1134 q.push( data );
rlm@79 1135 }
rlm@79 1136
rlm@79 1137 return q;
rlm@79 1138 },
rlm@79 1139
rlm@79 1140 dequeue: function( elem, type ) {
rlm@79 1141 type = type || "fx";
rlm@79 1142
rlm@79 1143 var queue = jQuery.queue( elem, type ), fn = queue.shift();
rlm@79 1144
rlm@79 1145 // If the fx queue is dequeued, always remove the progress sentinel
rlm@79 1146 if ( fn === "inprogress" ) {
rlm@79 1147 fn = queue.shift();
rlm@79 1148 }
rlm@79 1149
rlm@79 1150 if ( fn ) {
rlm@79 1151 // Add a progress sentinel to prevent the fx queue from being
rlm@79 1152 // automatically dequeued
rlm@79 1153 if ( type === "fx" ) {
rlm@79 1154 queue.unshift("inprogress");
rlm@79 1155 }
rlm@79 1156
rlm@79 1157 fn.call(elem, function() {
rlm@79 1158 jQuery.dequeue(elem, type);
rlm@79 1159 });
rlm@79 1160 }
rlm@79 1161 }
rlm@79 1162 });
rlm@79 1163
rlm@79 1164 jQuery.fn.extend({
rlm@79 1165 queue: function( type, data ) {
rlm@79 1166 if ( typeof type !== "string" ) {
rlm@79 1167 data = type;
rlm@79 1168 type = "fx";
rlm@79 1169 }
rlm@79 1170
rlm@79 1171 if ( data === undefined ) {
rlm@79 1172 return jQuery.queue( this[0], type );
rlm@79 1173 }
rlm@79 1174 return this.each(function( i, elem ) {
rlm@79 1175 var queue = jQuery.queue( this, type, data );
rlm@79 1176
rlm@79 1177 if ( type === "fx" && queue[0] !== "inprogress" ) {
rlm@79 1178 jQuery.dequeue( this, type );
rlm@79 1179 }
rlm@79 1180 });
rlm@79 1181 },
rlm@79 1182 dequeue: function( type ) {
rlm@79 1183 return this.each(function() {
rlm@79 1184 jQuery.dequeue( this, type );
rlm@79 1185 });
rlm@79 1186 },
rlm@79 1187
rlm@79 1188 // Based off of the plugin by Clint Helfers, with permission.
rlm@79 1189 // http://blindsignals.com/index.php/2009/07/jquery-delay/
rlm@79 1190 delay: function( time, type ) {
rlm@79 1191 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
rlm@79 1192 type = type || "fx";
rlm@79 1193
rlm@79 1194 return this.queue( type, function() {
rlm@79 1195 var elem = this;
rlm@79 1196 setTimeout(function() {
rlm@79 1197 jQuery.dequeue( elem, type );
rlm@79 1198 }, time );
rlm@79 1199 });
rlm@79 1200 },
rlm@79 1201
rlm@79 1202 clearQueue: function( type ) {
rlm@79 1203 return this.queue( type || "fx", [] );
rlm@79 1204 }
rlm@79 1205 });
rlm@79 1206 var rclass = /[\n\t]/g,
rlm@79 1207 rspace = /\s+/,
rlm@79 1208 rreturn = /\r/g,
rlm@79 1209 rspecialurl = /href|src|style/,
rlm@79 1210 rtype = /(button|input)/i,
rlm@79 1211 rfocusable = /(button|input|object|select|textarea)/i,
rlm@79 1212 rclickable = /^(a|area)$/i,
rlm@79 1213 rradiocheck = /radio|checkbox/;
rlm@79 1214
rlm@79 1215 jQuery.fn.extend({
rlm@79 1216 attr: function( name, value ) {
rlm@79 1217 return access( this, name, value, true, jQuery.attr );
rlm@79 1218 },
rlm@79 1219
rlm@79 1220 removeAttr: function( name, fn ) {
rlm@79 1221 return this.each(function(){
rlm@79 1222 jQuery.attr( this, name, "" );
rlm@79 1223 if ( this.nodeType === 1 ) {
rlm@79 1224 this.removeAttribute( name );
rlm@79 1225 }
rlm@79 1226 });
rlm@79 1227 },
rlm@79 1228
rlm@79 1229 addClass: function( value ) {
rlm@79 1230 if ( jQuery.isFunction(value) ) {
rlm@79 1231 return this.each(function(i) {
rlm@79 1232 var self = jQuery(this);
rlm@79 1233 self.addClass( value.call(this, i, self.attr("class")) );
rlm@79 1234 });
rlm@79 1235 }
rlm@79 1236
rlm@79 1237 if ( value && typeof value === "string" ) {
rlm@79 1238 var classNames = (value || "").split( rspace );
rlm@79 1239
rlm@79 1240 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 1241 var elem = this[i];
rlm@79 1242
rlm@79 1243 if ( elem.nodeType === 1 ) {
rlm@79 1244 if ( !elem.className ) {
rlm@79 1245 elem.className = value;
rlm@79 1246
rlm@79 1247 } else {
rlm@79 1248 var className = " " + elem.className + " ", setClass = elem.className;
rlm@79 1249 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
rlm@79 1250 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
rlm@79 1251 setClass += " " + classNames[c];
rlm@79 1252 }
rlm@79 1253 }
rlm@79 1254 elem.className = jQuery.trim( setClass );
rlm@79 1255 }
rlm@79 1256 }
rlm@79 1257 }
rlm@79 1258 }
rlm@79 1259
rlm@79 1260 return this;
rlm@79 1261 },
rlm@79 1262
rlm@79 1263 removeClass: function( value ) {
rlm@79 1264 if ( jQuery.isFunction(value) ) {
rlm@79 1265 return this.each(function(i) {
rlm@79 1266 var self = jQuery(this);
rlm@79 1267 self.removeClass( value.call(this, i, self.attr("class")) );
rlm@79 1268 });
rlm@79 1269 }
rlm@79 1270
rlm@79 1271 if ( (value && typeof value === "string") || value === undefined ) {
rlm@79 1272 var classNames = (value || "").split(rspace);
rlm@79 1273
rlm@79 1274 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 1275 var elem = this[i];
rlm@79 1276
rlm@79 1277 if ( elem.nodeType === 1 && elem.className ) {
rlm@79 1278 if ( value ) {
rlm@79 1279 var className = (" " + elem.className + " ").replace(rclass, " ");
rlm@79 1280 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
rlm@79 1281 className = className.replace(" " + classNames[c] + " ", " ");
rlm@79 1282 }
rlm@79 1283 elem.className = jQuery.trim( className );
rlm@79 1284
rlm@79 1285 } else {
rlm@79 1286 elem.className = "";
rlm@79 1287 }
rlm@79 1288 }
rlm@79 1289 }
rlm@79 1290 }
rlm@79 1291
rlm@79 1292 return this;
rlm@79 1293 },
rlm@79 1294
rlm@79 1295 toggleClass: function( value, stateVal ) {
rlm@79 1296 var type = typeof value, isBool = typeof stateVal === "boolean";
rlm@79 1297
rlm@79 1298 if ( jQuery.isFunction( value ) ) {
rlm@79 1299 return this.each(function(i) {
rlm@79 1300 var self = jQuery(this);
rlm@79 1301 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
rlm@79 1302 });
rlm@79 1303 }
rlm@79 1304
rlm@79 1305 return this.each(function() {
rlm@79 1306 if ( type === "string" ) {
rlm@79 1307 // toggle individual class names
rlm@79 1308 var className, i = 0, self = jQuery(this),
rlm@79 1309 state = stateVal,
rlm@79 1310 classNames = value.split( rspace );
rlm@79 1311
rlm@79 1312 while ( (className = classNames[ i++ ]) ) {
rlm@79 1313 // check each className given, space seperated list
rlm@79 1314 state = isBool ? state : !self.hasClass( className );
rlm@79 1315 self[ state ? "addClass" : "removeClass" ]( className );
rlm@79 1316 }
rlm@79 1317
rlm@79 1318 } else if ( type === "undefined" || type === "boolean" ) {
rlm@79 1319 if ( this.className ) {
rlm@79 1320 // store className if set
rlm@79 1321 jQuery.data( this, "__className__", this.className );
rlm@79 1322 }
rlm@79 1323
rlm@79 1324 // toggle whole className
rlm@79 1325 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
rlm@79 1326 }
rlm@79 1327 });
rlm@79 1328 },
rlm@79 1329
rlm@79 1330 hasClass: function( selector ) {
rlm@79 1331 var className = " " + selector + " ";
rlm@79 1332 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 1333 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
rlm@79 1334 return true;
rlm@79 1335 }
rlm@79 1336 }
rlm@79 1337
rlm@79 1338 return false;
rlm@79 1339 },
rlm@79 1340
rlm@79 1341 val: function( value ) {
rlm@79 1342 if ( value === undefined ) {
rlm@79 1343 var elem = this[0];
rlm@79 1344
rlm@79 1345 if ( elem ) {
rlm@79 1346 if ( jQuery.nodeName( elem, "option" ) ) {
rlm@79 1347 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
rlm@79 1348 }
rlm@79 1349
rlm@79 1350 // We need to handle select boxes special
rlm@79 1351 if ( jQuery.nodeName( elem, "select" ) ) {
rlm@79 1352 var index = elem.selectedIndex,
rlm@79 1353 values = [],
rlm@79 1354 options = elem.options,
rlm@79 1355 one = elem.type === "select-one";
rlm@79 1356
rlm@79 1357 // Nothing was selected
rlm@79 1358 if ( index < 0 ) {
rlm@79 1359 return null;
rlm@79 1360 }
rlm@79 1361
rlm@79 1362 // Loop through all the selected options
rlm@79 1363 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
rlm@79 1364 var option = options[ i ];
rlm@79 1365
rlm@79 1366 if ( option.selected ) {
rlm@79 1367 // Get the specifc value for the option
rlm@79 1368 value = jQuery(option).val();
rlm@79 1369
rlm@79 1370 // We don't need an array for one selects
rlm@79 1371 if ( one ) {
rlm@79 1372 return value;
rlm@79 1373 }
rlm@79 1374
rlm@79 1375 // Multi-Selects return an array
rlm@79 1376 values.push( value );
rlm@79 1377 }
rlm@79 1378 }
rlm@79 1379
rlm@79 1380 return values;
rlm@79 1381 }
rlm@79 1382
rlm@79 1383 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
rlm@79 1384 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
rlm@79 1385 return elem.getAttribute("value") === null ? "on" : elem.value;
rlm@79 1386 }
rlm@79 1387
rlm@79 1388
rlm@79 1389 // Everything else, we just grab the value
rlm@79 1390 return (elem.value || "").replace(rreturn, "");
rlm@79 1391
rlm@79 1392 }
rlm@79 1393
rlm@79 1394 return undefined;
rlm@79 1395 }
rlm@79 1396
rlm@79 1397 var isFunction = jQuery.isFunction(value);
rlm@79 1398
rlm@79 1399 return this.each(function(i) {
rlm@79 1400 var self = jQuery(this), val = value;
rlm@79 1401
rlm@79 1402 if ( this.nodeType !== 1 ) {
rlm@79 1403 return;
rlm@79 1404 }
rlm@79 1405
rlm@79 1406 if ( isFunction ) {
rlm@79 1407 val = value.call(this, i, self.val());
rlm@79 1408 }
rlm@79 1409
rlm@79 1410 // Typecast each time if the value is a Function and the appended
rlm@79 1411 // value is therefore different each time.
rlm@79 1412 if ( typeof val === "number" ) {
rlm@79 1413 val += "";
rlm@79 1414 }
rlm@79 1415
rlm@79 1416 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
rlm@79 1417 this.checked = jQuery.inArray( self.val(), val ) >= 0;
rlm@79 1418
rlm@79 1419 } else if ( jQuery.nodeName( this, "select" ) ) {
rlm@79 1420 var values = jQuery.makeArray(val);
rlm@79 1421
rlm@79 1422 jQuery( "option", this ).each(function() {
rlm@79 1423 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
rlm@79 1424 });
rlm@79 1425
rlm@79 1426 if ( !values.length ) {
rlm@79 1427 this.selectedIndex = -1;
rlm@79 1428 }
rlm@79 1429
rlm@79 1430 } else {
rlm@79 1431 this.value = val;
rlm@79 1432 }
rlm@79 1433 });
rlm@79 1434 }
rlm@79 1435 });
rlm@79 1436
rlm@79 1437 jQuery.extend({
rlm@79 1438 attrFn: {
rlm@79 1439 val: true,
rlm@79 1440 css: true,
rlm@79 1441 html: true,
rlm@79 1442 text: true,
rlm@79 1443 data: true,
rlm@79 1444 width: true,
rlm@79 1445 height: true,
rlm@79 1446 offset: true
rlm@79 1447 },
rlm@79 1448
rlm@79 1449 attr: function( elem, name, value, pass ) {
rlm@79 1450 // don't set attributes on text and comment nodes
rlm@79 1451 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
rlm@79 1452 return undefined;
rlm@79 1453 }
rlm@79 1454
rlm@79 1455 if ( pass && name in jQuery.attrFn ) {
rlm@79 1456 return jQuery(elem)[name](value);
rlm@79 1457 }
rlm@79 1458
rlm@79 1459 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
rlm@79 1460 // Whether we are setting (or getting)
rlm@79 1461 set = value !== undefined;
rlm@79 1462
rlm@79 1463 // Try to normalize/fix the name
rlm@79 1464 name = notxml && jQuery.props[ name ] || name;
rlm@79 1465
rlm@79 1466 // Only do all the following if this is a node (faster for style)
rlm@79 1467 if ( elem.nodeType === 1 ) {
rlm@79 1468 // These attributes require special treatment
rlm@79 1469 var special = rspecialurl.test( name );
rlm@79 1470
rlm@79 1471 // Safari mis-reports the default selected property of an option
rlm@79 1472 // Accessing the parent's selectedIndex property fixes it
rlm@79 1473 if ( name === "selected" && !jQuery.support.optSelected ) {
rlm@79 1474 var parent = elem.parentNode;
rlm@79 1475 if ( parent ) {
rlm@79 1476 parent.selectedIndex;
rlm@79 1477
rlm@79 1478 // Make sure that it also works with optgroups, see #5701
rlm@79 1479 if ( parent.parentNode ) {
rlm@79 1480 parent.parentNode.selectedIndex;
rlm@79 1481 }
rlm@79 1482 }
rlm@79 1483 }
rlm@79 1484
rlm@79 1485 // If applicable, access the attribute via the DOM 0 way
rlm@79 1486 if ( name in elem && notxml && !special ) {
rlm@79 1487 if ( set ) {
rlm@79 1488 // We can't allow the type property to be changed (since it causes problems in IE)
rlm@79 1489 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
rlm@79 1490 jQuery.error( "type property can't be changed" );
rlm@79 1491 }
rlm@79 1492
rlm@79 1493 elem[ name ] = value;
rlm@79 1494 }
rlm@79 1495
rlm@79 1496 // browsers index elements by id/name on forms, give priority to attributes.
rlm@79 1497 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
rlm@79 1498 return elem.getAttributeNode( name ).nodeValue;
rlm@79 1499 }
rlm@79 1500
rlm@79 1501 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
rlm@79 1502 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
rlm@79 1503 if ( name === "tabIndex" ) {
rlm@79 1504 var attributeNode = elem.getAttributeNode( "tabIndex" );
rlm@79 1505
rlm@79 1506 return attributeNode && attributeNode.specified ?
rlm@79 1507 attributeNode.value :
rlm@79 1508 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
rlm@79 1509 0 :
rlm@79 1510 undefined;
rlm@79 1511 }
rlm@79 1512
rlm@79 1513 return elem[ name ];
rlm@79 1514 }
rlm@79 1515
rlm@79 1516 if ( !jQuery.support.style && notxml && name === "style" ) {
rlm@79 1517 if ( set ) {
rlm@79 1518 elem.style.cssText = "" + value;
rlm@79 1519 }
rlm@79 1520
rlm@79 1521 return elem.style.cssText;
rlm@79 1522 }
rlm@79 1523
rlm@79 1524 if ( set ) {
rlm@79 1525 // convert the value to a string (all browsers do this but IE) see #1070
rlm@79 1526 elem.setAttribute( name, "" + value );
rlm@79 1527 }
rlm@79 1528
rlm@79 1529 var attr = !jQuery.support.hrefNormalized && notxml && special ?
rlm@79 1530 // Some attributes require a special call on IE
rlm@79 1531 elem.getAttribute( name, 2 ) :
rlm@79 1532 elem.getAttribute( name );
rlm@79 1533
rlm@79 1534 // Non-existent attributes return null, we normalize to undefined
rlm@79 1535 return attr === null ? undefined : attr;
rlm@79 1536 }
rlm@79 1537
rlm@79 1538 // elem is actually elem.style ... set the style
rlm@79 1539 // Using attr for specific style information is now deprecated. Use style instead.
rlm@79 1540 return jQuery.style( elem, name, value );
rlm@79 1541 }
rlm@79 1542 });
rlm@79 1543 var rnamespaces = /\.(.*)$/,
rlm@79 1544 fcleanup = function( nm ) {
rlm@79 1545 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
rlm@79 1546 return "\\" + ch;
rlm@79 1547 });
rlm@79 1548 };
rlm@79 1549
rlm@79 1550 /*
rlm@79 1551 * A number of helper functions used for managing events.
rlm@79 1552 * Many of the ideas behind this code originated from
rlm@79 1553 * Dean Edwards' addEvent library.
rlm@79 1554 */
rlm@79 1555 jQuery.event = {
rlm@79 1556
rlm@79 1557 // Bind an event to an element
rlm@79 1558 // Original by Dean Edwards
rlm@79 1559 add: function( elem, types, handler, data ) {
rlm@79 1560 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
rlm@79 1561 return;
rlm@79 1562 }
rlm@79 1563
rlm@79 1564 // For whatever reason, IE has trouble passing the window object
rlm@79 1565 // around, causing it to be cloned in the process
rlm@79 1566 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
rlm@79 1567 elem = window;
rlm@79 1568 }
rlm@79 1569
rlm@79 1570 var handleObjIn, handleObj;
rlm@79 1571
rlm@79 1572 if ( handler.handler ) {
rlm@79 1573 handleObjIn = handler;
rlm@79 1574 handler = handleObjIn.handler;
rlm@79 1575 }
rlm@79 1576
rlm@79 1577 // Make sure that the function being executed has a unique ID
rlm@79 1578 if ( !handler.guid ) {
rlm@79 1579 handler.guid = jQuery.guid++;
rlm@79 1580 }
rlm@79 1581
rlm@79 1582 // Init the element's event structure
rlm@79 1583 var elemData = jQuery.data( elem );
rlm@79 1584
rlm@79 1585 // If no elemData is found then we must be trying to bind to one of the
rlm@79 1586 // banned noData elements
rlm@79 1587 if ( !elemData ) {
rlm@79 1588 return;
rlm@79 1589 }
rlm@79 1590
rlm@79 1591 var events = elemData.events = elemData.events || {},
rlm@79 1592 eventHandle = elemData.handle, eventHandle;
rlm@79 1593
rlm@79 1594 if ( !eventHandle ) {
rlm@79 1595 elemData.handle = eventHandle = function() {
rlm@79 1596 // Handle the second event of a trigger and when
rlm@79 1597 // an event is called after a page has unloaded
rlm@79 1598 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
rlm@79 1599 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
rlm@79 1600 undefined;
rlm@79 1601 };
rlm@79 1602 }
rlm@79 1603
rlm@79 1604 // Add elem as a property of the handle function
rlm@79 1605 // This is to prevent a memory leak with non-native events in IE.
rlm@79 1606 eventHandle.elem = elem;
rlm@79 1607
rlm@79 1608 // Handle multiple events separated by a space
rlm@79 1609 // jQuery(...).bind("mouseover mouseout", fn);
rlm@79 1610 types = types.split(" ");
rlm@79 1611
rlm@79 1612 var type, i = 0, namespaces;
rlm@79 1613
rlm@79 1614 while ( (type = types[ i++ ]) ) {
rlm@79 1615 handleObj = handleObjIn ?
rlm@79 1616 jQuery.extend({}, handleObjIn) :
rlm@79 1617 { handler: handler, data: data };
rlm@79 1618
rlm@79 1619 // Namespaced event handlers
rlm@79 1620 if ( type.indexOf(".") > -1 ) {
rlm@79 1621 namespaces = type.split(".");
rlm@79 1622 type = namespaces.shift();
rlm@79 1623 handleObj.namespace = namespaces.slice(0).sort().join(".");
rlm@79 1624
rlm@79 1625 } else {
rlm@79 1626 namespaces = [];
rlm@79 1627 handleObj.namespace = "";
rlm@79 1628 }
rlm@79 1629
rlm@79 1630 handleObj.type = type;
rlm@79 1631 handleObj.guid = handler.guid;
rlm@79 1632
rlm@79 1633 // Get the current list of functions bound to this event
rlm@79 1634 var handlers = events[ type ],
rlm@79 1635 special = jQuery.event.special[ type ] || {};
rlm@79 1636
rlm@79 1637 // Init the event handler queue
rlm@79 1638 if ( !handlers ) {
rlm@79 1639 handlers = events[ type ] = [];
rlm@79 1640
rlm@79 1641 // Check for a special event handler
rlm@79 1642 // Only use addEventListener/attachEvent if the special
rlm@79 1643 // events handler returns false
rlm@79 1644 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
rlm@79 1645 // Bind the global event handler to the element
rlm@79 1646 if ( elem.addEventListener ) {
rlm@79 1647 elem.addEventListener( type, eventHandle, false );
rlm@79 1648
rlm@79 1649 } else if ( elem.attachEvent ) {
rlm@79 1650 elem.attachEvent( "on" + type, eventHandle );
rlm@79 1651 }
rlm@79 1652 }
rlm@79 1653 }
rlm@79 1654
rlm@79 1655 if ( special.add ) {
rlm@79 1656 special.add.call( elem, handleObj );
rlm@79 1657
rlm@79 1658 if ( !handleObj.handler.guid ) {
rlm@79 1659 handleObj.handler.guid = handler.guid;
rlm@79 1660 }
rlm@79 1661 }
rlm@79 1662
rlm@79 1663 // Add the function to the element's handler list
rlm@79 1664 handlers.push( handleObj );
rlm@79 1665
rlm@79 1666 // Keep track of which events have been used, for global triggering
rlm@79 1667 jQuery.event.global[ type ] = true;
rlm@79 1668 }
rlm@79 1669
rlm@79 1670 // Nullify elem to prevent memory leaks in IE
rlm@79 1671 elem = null;
rlm@79 1672 },
rlm@79 1673
rlm@79 1674 global: {},
rlm@79 1675
rlm@79 1676 // Detach an event or set of events from an element
rlm@79 1677 remove: function( elem, types, handler, pos ) {
rlm@79 1678 // don't do events on text and comment nodes
rlm@79 1679 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
rlm@79 1680 return;
rlm@79 1681 }
rlm@79 1682
rlm@79 1683 var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
rlm@79 1684 elemData = jQuery.data( elem ),
rlm@79 1685 events = elemData && elemData.events;
rlm@79 1686
rlm@79 1687 if ( !elemData || !events ) {
rlm@79 1688 return;
rlm@79 1689 }
rlm@79 1690
rlm@79 1691 // types is actually an event object here
rlm@79 1692 if ( types && types.type ) {
rlm@79 1693 handler = types.handler;
rlm@79 1694 types = types.type;
rlm@79 1695 }
rlm@79 1696
rlm@79 1697 // Unbind all events for the element
rlm@79 1698 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
rlm@79 1699 types = types || "";
rlm@79 1700
rlm@79 1701 for ( type in events ) {
rlm@79 1702 jQuery.event.remove( elem, type + types );
rlm@79 1703 }
rlm@79 1704
rlm@79 1705 return;
rlm@79 1706 }
rlm@79 1707
rlm@79 1708 // Handle multiple events separated by a space
rlm@79 1709 // jQuery(...).unbind("mouseover mouseout", fn);
rlm@79 1710 types = types.split(" ");
rlm@79 1711
rlm@79 1712 while ( (type = types[ i++ ]) ) {
rlm@79 1713 origType = type;
rlm@79 1714 handleObj = null;
rlm@79 1715 all = type.indexOf(".") < 0;
rlm@79 1716 namespaces = [];
rlm@79 1717
rlm@79 1718 if ( !all ) {
rlm@79 1719 // Namespaced event handlers
rlm@79 1720 namespaces = type.split(".");
rlm@79 1721 type = namespaces.shift();
rlm@79 1722
rlm@79 1723 namespace = new RegExp("(^|\\.)" +
rlm@79 1724 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
rlm@79 1725 }
rlm@79 1726
rlm@79 1727 eventType = events[ type ];
rlm@79 1728
rlm@79 1729 if ( !eventType ) {
rlm@79 1730 continue;
rlm@79 1731 }
rlm@79 1732
rlm@79 1733 if ( !handler ) {
rlm@79 1734 for ( var j = 0; j < eventType.length; j++ ) {
rlm@79 1735 handleObj = eventType[ j ];
rlm@79 1736
rlm@79 1737 if ( all || namespace.test( handleObj.namespace ) ) {
rlm@79 1738 jQuery.event.remove( elem, origType, handleObj.handler, j );
rlm@79 1739 eventType.splice( j--, 1 );
rlm@79 1740 }
rlm@79 1741 }
rlm@79 1742
rlm@79 1743 continue;
rlm@79 1744 }
rlm@79 1745
rlm@79 1746 special = jQuery.event.special[ type ] || {};
rlm@79 1747
rlm@79 1748 for ( var j = pos || 0; j < eventType.length; j++ ) {
rlm@79 1749 handleObj = eventType[ j ];
rlm@79 1750
rlm@79 1751 if ( handler.guid === handleObj.guid ) {
rlm@79 1752 // remove the given handler for the given type
rlm@79 1753 if ( all || namespace.test( handleObj.namespace ) ) {
rlm@79 1754 if ( pos == null ) {
rlm@79 1755 eventType.splice( j--, 1 );
rlm@79 1756 }
rlm@79 1757
rlm@79 1758 if ( special.remove ) {
rlm@79 1759 special.remove.call( elem, handleObj );
rlm@79 1760 }
rlm@79 1761 }
rlm@79 1762
rlm@79 1763 if ( pos != null ) {
rlm@79 1764 break;
rlm@79 1765 }
rlm@79 1766 }
rlm@79 1767 }
rlm@79 1768
rlm@79 1769 // remove generic event handler if no more handlers exist
rlm@79 1770 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
rlm@79 1771 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
rlm@79 1772 removeEvent( elem, type, elemData.handle );
rlm@79 1773 }
rlm@79 1774
rlm@79 1775 ret = null;
rlm@79 1776 delete events[ type ];
rlm@79 1777 }
rlm@79 1778 }
rlm@79 1779
rlm@79 1780 // Remove the expando if it's no longer used
rlm@79 1781 if ( jQuery.isEmptyObject( events ) ) {
rlm@79 1782 var handle = elemData.handle;
rlm@79 1783 if ( handle ) {
rlm@79 1784 handle.elem = null;
rlm@79 1785 }
rlm@79 1786
rlm@79 1787 delete elemData.events;
rlm@79 1788 delete elemData.handle;
rlm@79 1789
rlm@79 1790 if ( jQuery.isEmptyObject( elemData ) ) {
rlm@79 1791 jQuery.removeData( elem );
rlm@79 1792 }
rlm@79 1793 }
rlm@79 1794 },
rlm@79 1795
rlm@79 1796 // bubbling is internal
rlm@79 1797 trigger: function( event, data, elem /*, bubbling */ ) {
rlm@79 1798 // Event object or event type
rlm@79 1799 var type = event.type || event,
rlm@79 1800 bubbling = arguments[3];
rlm@79 1801
rlm@79 1802 if ( !bubbling ) {
rlm@79 1803 event = typeof event === "object" ?
rlm@79 1804 // jQuery.Event object
rlm@79 1805 event[expando] ? event :
rlm@79 1806 // Object literal
rlm@79 1807 jQuery.extend( jQuery.Event(type), event ) :
rlm@79 1808 // Just the event type (string)
rlm@79 1809 jQuery.Event(type);
rlm@79 1810
rlm@79 1811 if ( type.indexOf("!") >= 0 ) {
rlm@79 1812 event.type = type = type.slice(0, -1);
rlm@79 1813 event.exclusive = true;
rlm@79 1814 }
rlm@79 1815
rlm@79 1816 // Handle a global trigger
rlm@79 1817 if ( !elem ) {
rlm@79 1818 // Don't bubble custom events when global (to avoid too much overhead)
rlm@79 1819 event.stopPropagation();
rlm@79 1820
rlm@79 1821 // Only trigger if we've ever bound an event for it
rlm@79 1822 if ( jQuery.event.global[ type ] ) {
rlm@79 1823 jQuery.each( jQuery.cache, function() {
rlm@79 1824 if ( this.events && this.events[type] ) {
rlm@79 1825 jQuery.event.trigger( event, data, this.handle.elem );
rlm@79 1826 }
rlm@79 1827 });
rlm@79 1828 }
rlm@79 1829 }
rlm@79 1830
rlm@79 1831 // Handle triggering a single element
rlm@79 1832
rlm@79 1833 // don't do events on text and comment nodes
rlm@79 1834 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
rlm@79 1835 return undefined;
rlm@79 1836 }
rlm@79 1837
rlm@79 1838 // Clean up in case it is reused
rlm@79 1839 event.result = undefined;
rlm@79 1840 event.target = elem;
rlm@79 1841
rlm@79 1842 // Clone the incoming data, if any
rlm@79 1843 data = jQuery.makeArray( data );
rlm@79 1844 data.unshift( event );
rlm@79 1845 }
rlm@79 1846
rlm@79 1847 event.currentTarget = elem;
rlm@79 1848
rlm@79 1849 // Trigger the event, it is assumed that "handle" is a function
rlm@79 1850 var handle = jQuery.data( elem, "handle" );
rlm@79 1851 if ( handle ) {
rlm@79 1852 handle.apply( elem, data );
rlm@79 1853 }
rlm@79 1854
rlm@79 1855 var parent = elem.parentNode || elem.ownerDocument;
rlm@79 1856
rlm@79 1857 // Trigger an inline bound script
rlm@79 1858 try {
rlm@79 1859 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
rlm@79 1860 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
rlm@79 1861 event.result = false;
rlm@79 1862 }
rlm@79 1863 }
rlm@79 1864
rlm@79 1865 // prevent IE from throwing an error for some elements with some event types, see #3533
rlm@79 1866 } catch (e) {}
rlm@79 1867
rlm@79 1868 if ( !event.isPropagationStopped() && parent ) {
rlm@79 1869 jQuery.event.trigger( event, data, parent, true );
rlm@79 1870
rlm@79 1871 } else if ( !event.isDefaultPrevented() ) {
rlm@79 1872 var target = event.target, old,
rlm@79 1873 isClick = jQuery.nodeName(target, "a") && type === "click",
rlm@79 1874 special = jQuery.event.special[ type ] || {};
rlm@79 1875
rlm@79 1876 if ( (!special._default || special._default.call( elem, event ) === false) &&
rlm@79 1877 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
rlm@79 1878
rlm@79 1879 try {
rlm@79 1880 if ( target[ type ] ) {
rlm@79 1881 // Make sure that we don't accidentally re-trigger the onFOO events
rlm@79 1882 old = target[ "on" + type ];
rlm@79 1883
rlm@79 1884 if ( old ) {
rlm@79 1885 target[ "on" + type ] = null;
rlm@79 1886 }
rlm@79 1887
rlm@79 1888 jQuery.event.triggered = true;
rlm@79 1889 target[ type ]();
rlm@79 1890 }
rlm@79 1891
rlm@79 1892 // prevent IE from throwing an error for some elements with some event types, see #3533
rlm@79 1893 } catch (e) {}
rlm@79 1894
rlm@79 1895 if ( old ) {
rlm@79 1896 target[ "on" + type ] = old;
rlm@79 1897 }
rlm@79 1898
rlm@79 1899 jQuery.event.triggered = false;
rlm@79 1900 }
rlm@79 1901 }
rlm@79 1902 },
rlm@79 1903
rlm@79 1904 handle: function( event ) {
rlm@79 1905 var all, handlers, namespaces, namespace, events;
rlm@79 1906
rlm@79 1907 event = arguments[0] = jQuery.event.fix( event || window.event );
rlm@79 1908 event.currentTarget = this;
rlm@79 1909
rlm@79 1910 // Namespaced event handlers
rlm@79 1911 all = event.type.indexOf(".") < 0 && !event.exclusive;
rlm@79 1912
rlm@79 1913 if ( !all ) {
rlm@79 1914 namespaces = event.type.split(".");
rlm@79 1915 event.type = namespaces.shift();
rlm@79 1916 namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
rlm@79 1917 }
rlm@79 1918
rlm@79 1919 var events = jQuery.data(this, "events"), handlers = events[ event.type ];
rlm@79 1920
rlm@79 1921 if ( events && handlers ) {
rlm@79 1922 // Clone the handlers to prevent manipulation
rlm@79 1923 handlers = handlers.slice(0);
rlm@79 1924
rlm@79 1925 for ( var j = 0, l = handlers.length; j < l; j++ ) {
rlm@79 1926 var handleObj = handlers[ j ];
rlm@79 1927
rlm@79 1928 // Filter the functions by class
rlm@79 1929 if ( all || namespace.test( handleObj.namespace ) ) {
rlm@79 1930 // Pass in a reference to the handler function itself
rlm@79 1931 // So that we can later remove it
rlm@79 1932 event.handler = handleObj.handler;
rlm@79 1933 event.data = handleObj.data;
rlm@79 1934 event.handleObj = handleObj;
rlm@79 1935
rlm@79 1936 var ret = handleObj.handler.apply( this, arguments );
rlm@79 1937
rlm@79 1938 if ( ret !== undefined ) {
rlm@79 1939 event.result = ret;
rlm@79 1940 if ( ret === false ) {
rlm@79 1941 event.preventDefault();
rlm@79 1942 event.stopPropagation();
rlm@79 1943 }
rlm@79 1944 }
rlm@79 1945
rlm@79 1946 if ( event.isImmediatePropagationStopped() ) {
rlm@79 1947 break;
rlm@79 1948 }
rlm@79 1949 }
rlm@79 1950 }
rlm@79 1951 }
rlm@79 1952
rlm@79 1953 return event.result;
rlm@79 1954 },
rlm@79 1955
rlm@79 1956 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
rlm@79 1957
rlm@79 1958 fix: function( event ) {
rlm@79 1959 if ( event[ expando ] ) {
rlm@79 1960 return event;
rlm@79 1961 }
rlm@79 1962
rlm@79 1963 // store a copy of the original event object
rlm@79 1964 // and "clone" to set read-only properties
rlm@79 1965 var originalEvent = event;
rlm@79 1966 event = jQuery.Event( originalEvent );
rlm@79 1967
rlm@79 1968 for ( var i = this.props.length, prop; i; ) {
rlm@79 1969 prop = this.props[ --i ];
rlm@79 1970 event[ prop ] = originalEvent[ prop ];
rlm@79 1971 }
rlm@79 1972
rlm@79 1973 // Fix target property, if necessary
rlm@79 1974 if ( !event.target ) {
rlm@79 1975 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
rlm@79 1976 }
rlm@79 1977
rlm@79 1978 // check if target is a textnode (safari)
rlm@79 1979 if ( event.target.nodeType === 3 ) {
rlm@79 1980 event.target = event.target.parentNode;
rlm@79 1981 }
rlm@79 1982
rlm@79 1983 // Add relatedTarget, if necessary
rlm@79 1984 if ( !event.relatedTarget && event.fromElement ) {
rlm@79 1985 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
rlm@79 1986 }
rlm@79 1987
rlm@79 1988 // Calculate pageX/Y if missing and clientX/Y available
rlm@79 1989 if ( event.pageX == null && event.clientX != null ) {
rlm@79 1990 var doc = document.documentElement, body = document.body;
rlm@79 1991 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
rlm@79 1992 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
rlm@79 1993 }
rlm@79 1994
rlm@79 1995 // Add which for key events
rlm@79 1996 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
rlm@79 1997 event.which = event.charCode || event.keyCode;
rlm@79 1998 }
rlm@79 1999
rlm@79 2000 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
rlm@79 2001 if ( !event.metaKey && event.ctrlKey ) {
rlm@79 2002 event.metaKey = event.ctrlKey;
rlm@79 2003 }
rlm@79 2004
rlm@79 2005 // Add which for click: 1 === left; 2 === middle; 3 === right
rlm@79 2006 // Note: button is not normalized, so don't use it
rlm@79 2007 if ( !event.which && event.button !== undefined ) {
rlm@79 2008 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
rlm@79 2009 }
rlm@79 2010
rlm@79 2011 return event;
rlm@79 2012 },
rlm@79 2013
rlm@79 2014 // Deprecated, use jQuery.guid instead
rlm@79 2015 guid: 1E8,
rlm@79 2016
rlm@79 2017 // Deprecated, use jQuery.proxy instead
rlm@79 2018 proxy: jQuery.proxy,
rlm@79 2019
rlm@79 2020 special: {
rlm@79 2021 ready: {
rlm@79 2022 // Make sure the ready event is setup
rlm@79 2023 setup: jQuery.bindReady,
rlm@79 2024 teardown: jQuery.noop
rlm@79 2025 },
rlm@79 2026
rlm@79 2027 live: {
rlm@79 2028 add: function( handleObj ) {
rlm@79 2029 jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
rlm@79 2030 },
rlm@79 2031
rlm@79 2032 remove: function( handleObj ) {
rlm@79 2033 var remove = true,
rlm@79 2034 type = handleObj.origType.replace(rnamespaces, "");
rlm@79 2035
rlm@79 2036 jQuery.each( jQuery.data(this, "events").live || [], function() {
rlm@79 2037 if ( type === this.origType.replace(rnamespaces, "") ) {
rlm@79 2038 remove = false;
rlm@79 2039 return false;
rlm@79 2040 }
rlm@79 2041 });
rlm@79 2042
rlm@79 2043 if ( remove ) {
rlm@79 2044 jQuery.event.remove( this, handleObj.origType, liveHandler );
rlm@79 2045 }
rlm@79 2046 }
rlm@79 2047
rlm@79 2048 },
rlm@79 2049
rlm@79 2050 beforeunload: {
rlm@79 2051 setup: function( data, namespaces, eventHandle ) {
rlm@79 2052 // We only want to do this special case on windows
rlm@79 2053 if ( this.setInterval ) {
rlm@79 2054 this.onbeforeunload = eventHandle;
rlm@79 2055 }
rlm@79 2056
rlm@79 2057 return false;
rlm@79 2058 },
rlm@79 2059 teardown: function( namespaces, eventHandle ) {
rlm@79 2060 if ( this.onbeforeunload === eventHandle ) {
rlm@79 2061 this.onbeforeunload = null;
rlm@79 2062 }
rlm@79 2063 }
rlm@79 2064 }
rlm@79 2065 }
rlm@79 2066 };
rlm@79 2067
rlm@79 2068 var removeEvent = document.removeEventListener ?
rlm@79 2069 function( elem, type, handle ) {
rlm@79 2070 elem.removeEventListener( type, handle, false );
rlm@79 2071 } :
rlm@79 2072 function( elem, type, handle ) {
rlm@79 2073 elem.detachEvent( "on" + type, handle );
rlm@79 2074 };
rlm@79 2075
rlm@79 2076 jQuery.Event = function( src ) {
rlm@79 2077 // Allow instantiation without the 'new' keyword
rlm@79 2078 if ( !this.preventDefault ) {
rlm@79 2079 return new jQuery.Event( src );
rlm@79 2080 }
rlm@79 2081
rlm@79 2082 // Event object
rlm@79 2083 if ( src && src.type ) {
rlm@79 2084 this.originalEvent = src;
rlm@79 2085 this.type = src.type;
rlm@79 2086 // Event type
rlm@79 2087 } else {
rlm@79 2088 this.type = src;
rlm@79 2089 }
rlm@79 2090
rlm@79 2091 // timeStamp is buggy for some events on Firefox(#3843)
rlm@79 2092 // So we won't rely on the native value
rlm@79 2093 this.timeStamp = now();
rlm@79 2094
rlm@79 2095 // Mark it as fixed
rlm@79 2096 this[ expando ] = true;
rlm@79 2097 };
rlm@79 2098
rlm@79 2099 function returnFalse() {
rlm@79 2100 return false;
rlm@79 2101 }
rlm@79 2102 function returnTrue() {
rlm@79 2103 return true;
rlm@79 2104 }
rlm@79 2105
rlm@79 2106 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
rlm@79 2107 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
rlm@79 2108 jQuery.Event.prototype = {
rlm@79 2109 preventDefault: function() {
rlm@79 2110 this.isDefaultPrevented = returnTrue;
rlm@79 2111
rlm@79 2112 var e = this.originalEvent;
rlm@79 2113 if ( !e ) {
rlm@79 2114 return;
rlm@79 2115 }
rlm@79 2116
rlm@79 2117 // if preventDefault exists run it on the original event
rlm@79 2118 if ( e.preventDefault ) {
rlm@79 2119 e.preventDefault();
rlm@79 2120 }
rlm@79 2121 // otherwise set the returnValue property of the original event to false (IE)
rlm@79 2122 e.returnValue = false;
rlm@79 2123 },
rlm@79 2124 stopPropagation: function() {
rlm@79 2125 this.isPropagationStopped = returnTrue;
rlm@79 2126
rlm@79 2127 var e = this.originalEvent;
rlm@79 2128 if ( !e ) {
rlm@79 2129 return;
rlm@79 2130 }
rlm@79 2131 // if stopPropagation exists run it on the original event
rlm@79 2132 if ( e.stopPropagation ) {
rlm@79 2133 e.stopPropagation();
rlm@79 2134 }
rlm@79 2135 // otherwise set the cancelBubble property of the original event to true (IE)
rlm@79 2136 e.cancelBubble = true;
rlm@79 2137 },
rlm@79 2138 stopImmediatePropagation: function() {
rlm@79 2139 this.isImmediatePropagationStopped = returnTrue;
rlm@79 2140 this.stopPropagation();
rlm@79 2141 },
rlm@79 2142 isDefaultPrevented: returnFalse,
rlm@79 2143 isPropagationStopped: returnFalse,
rlm@79 2144 isImmediatePropagationStopped: returnFalse
rlm@79 2145 };
rlm@79 2146
rlm@79 2147 // Checks if an event happened on an element within another element
rlm@79 2148 // Used in jQuery.event.special.mouseenter and mouseleave handlers
rlm@79 2149 var withinElement = function( event ) {
rlm@79 2150 // Check if mouse(over|out) are still within the same parent element
rlm@79 2151 var parent = event.relatedTarget;
rlm@79 2152
rlm@79 2153 // Firefox sometimes assigns relatedTarget a XUL element
rlm@79 2154 // which we cannot access the parentNode property of
rlm@79 2155 try {
rlm@79 2156 // Traverse up the tree
rlm@79 2157 while ( parent && parent !== this ) {
rlm@79 2158 parent = parent.parentNode;
rlm@79 2159 }
rlm@79 2160
rlm@79 2161 if ( parent !== this ) {
rlm@79 2162 // set the correct event type
rlm@79 2163 event.type = event.data;
rlm@79 2164
rlm@79 2165 // handle event if we actually just moused on to a non sub-element
rlm@79 2166 jQuery.event.handle.apply( this, arguments );
rlm@79 2167 }
rlm@79 2168
rlm@79 2169 // assuming we've left the element since we most likely mousedover a xul element
rlm@79 2170 } catch(e) { }
rlm@79 2171 },
rlm@79 2172
rlm@79 2173 // In case of event delegation, we only need to rename the event.type,
rlm@79 2174 // liveHandler will take care of the rest.
rlm@79 2175 delegate = function( event ) {
rlm@79 2176 event.type = event.data;
rlm@79 2177 jQuery.event.handle.apply( this, arguments );
rlm@79 2178 };
rlm@79 2179
rlm@79 2180 // Create mouseenter and mouseleave events
rlm@79 2181 jQuery.each({
rlm@79 2182 mouseenter: "mouseover",
rlm@79 2183 mouseleave: "mouseout"
rlm@79 2184 }, function( orig, fix ) {
rlm@79 2185 jQuery.event.special[ orig ] = {
rlm@79 2186 setup: function( data ) {
rlm@79 2187 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
rlm@79 2188 },
rlm@79 2189 teardown: function( data ) {
rlm@79 2190 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
rlm@79 2191 }
rlm@79 2192 };
rlm@79 2193 });
rlm@79 2194
rlm@79 2195 // submit delegation
rlm@79 2196 if ( !jQuery.support.submitBubbles ) {
rlm@79 2197
rlm@79 2198 jQuery.event.special.submit = {
rlm@79 2199 setup: function( data, namespaces ) {
rlm@79 2200 if ( this.nodeName.toLowerCase() !== "form" ) {
rlm@79 2201 jQuery.event.add(this, "click.specialSubmit", function( e ) {
rlm@79 2202 var elem = e.target, type = elem.type;
rlm@79 2203
rlm@79 2204 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
rlm@79 2205 return trigger( "submit", this, arguments );
rlm@79 2206 }
rlm@79 2207 });
rlm@79 2208
rlm@79 2209 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
rlm@79 2210 var elem = e.target, type = elem.type;
rlm@79 2211
rlm@79 2212 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
rlm@79 2213 return trigger( "submit", this, arguments );
rlm@79 2214 }
rlm@79 2215 });
rlm@79 2216
rlm@79 2217 } else {
rlm@79 2218 return false;
rlm@79 2219 }
rlm@79 2220 },
rlm@79 2221
rlm@79 2222 teardown: function( namespaces ) {
rlm@79 2223 jQuery.event.remove( this, ".specialSubmit" );
rlm@79 2224 }
rlm@79 2225 };
rlm@79 2226
rlm@79 2227 }
rlm@79 2228
rlm@79 2229 // change delegation, happens here so we have bind.
rlm@79 2230 if ( !jQuery.support.changeBubbles ) {
rlm@79 2231
rlm@79 2232 var formElems = /textarea|input|select/i,
rlm@79 2233
rlm@79 2234 changeFilters,
rlm@79 2235
rlm@79 2236 getVal = function( elem ) {
rlm@79 2237 var type = elem.type, val = elem.value;
rlm@79 2238
rlm@79 2239 if ( type === "radio" || type === "checkbox" ) {
rlm@79 2240 val = elem.checked;
rlm@79 2241
rlm@79 2242 } else if ( type === "select-multiple" ) {
rlm@79 2243 val = elem.selectedIndex > -1 ?
rlm@79 2244 jQuery.map( elem.options, function( elem ) {
rlm@79 2245 return elem.selected;
rlm@79 2246 }).join("-") :
rlm@79 2247 "";
rlm@79 2248
rlm@79 2249 } else if ( elem.nodeName.toLowerCase() === "select" ) {
rlm@79 2250 val = elem.selectedIndex;
rlm@79 2251 }
rlm@79 2252
rlm@79 2253 return val;
rlm@79 2254 },
rlm@79 2255
rlm@79 2256 testChange = function testChange( e ) {
rlm@79 2257 var elem = e.target, data, val;
rlm@79 2258
rlm@79 2259 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
rlm@79 2260 return;
rlm@79 2261 }
rlm@79 2262
rlm@79 2263 data = jQuery.data( elem, "_change_data" );
rlm@79 2264 val = getVal(elem);
rlm@79 2265
rlm@79 2266 // the current data will be also retrieved by beforeactivate
rlm@79 2267 if ( e.type !== "focusout" || elem.type !== "radio" ) {
rlm@79 2268 jQuery.data( elem, "_change_data", val );
rlm@79 2269 }
rlm@79 2270
rlm@79 2271 if ( data === undefined || val === data ) {
rlm@79 2272 return;
rlm@79 2273 }
rlm@79 2274
rlm@79 2275 if ( data != null || val ) {
rlm@79 2276 e.type = "change";
rlm@79 2277 return jQuery.event.trigger( e, arguments[1], elem );
rlm@79 2278 }
rlm@79 2279 };
rlm@79 2280
rlm@79 2281 jQuery.event.special.change = {
rlm@79 2282 filters: {
rlm@79 2283 focusout: testChange,
rlm@79 2284
rlm@79 2285 click: function( e ) {
rlm@79 2286 var elem = e.target, type = elem.type;
rlm@79 2287
rlm@79 2288 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
rlm@79 2289 return testChange.call( this, e );
rlm@79 2290 }
rlm@79 2291 },
rlm@79 2292
rlm@79 2293 // Change has to be called before submit
rlm@79 2294 // Keydown will be called before keypress, which is used in submit-event delegation
rlm@79 2295 keydown: function( e ) {
rlm@79 2296 var elem = e.target, type = elem.type;
rlm@79 2297
rlm@79 2298 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
rlm@79 2299 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
rlm@79 2300 type === "select-multiple" ) {
rlm@79 2301 return testChange.call( this, e );
rlm@79 2302 }
rlm@79 2303 },
rlm@79 2304
rlm@79 2305 // Beforeactivate happens also before the previous element is blurred
rlm@79 2306 // with this event you can't trigger a change event, but you can store
rlm@79 2307 // information/focus[in] is not needed anymore
rlm@79 2308 beforeactivate: function( e ) {
rlm@79 2309 var elem = e.target;
rlm@79 2310 jQuery.data( elem, "_change_data", getVal(elem) );
rlm@79 2311 }
rlm@79 2312 },
rlm@79 2313
rlm@79 2314 setup: function( data, namespaces ) {
rlm@79 2315 if ( this.type === "file" ) {
rlm@79 2316 return false;
rlm@79 2317 }
rlm@79 2318
rlm@79 2319 for ( var type in changeFilters ) {
rlm@79 2320 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
rlm@79 2321 }
rlm@79 2322
rlm@79 2323 return formElems.test( this.nodeName );
rlm@79 2324 },
rlm@79 2325
rlm@79 2326 teardown: function( namespaces ) {
rlm@79 2327 jQuery.event.remove( this, ".specialChange" );
rlm@79 2328
rlm@79 2329 return formElems.test( this.nodeName );
rlm@79 2330 }
rlm@79 2331 };
rlm@79 2332
rlm@79 2333 changeFilters = jQuery.event.special.change.filters;
rlm@79 2334 }
rlm@79 2335
rlm@79 2336 function trigger( type, elem, args ) {
rlm@79 2337 args[0].type = type;
rlm@79 2338 return jQuery.event.handle.apply( elem, args );
rlm@79 2339 }
rlm@79 2340
rlm@79 2341 // Create "bubbling" focus and blur events
rlm@79 2342 if ( document.addEventListener ) {
rlm@79 2343 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
rlm@79 2344 jQuery.event.special[ fix ] = {
rlm@79 2345 setup: function() {
rlm@79 2346 this.addEventListener( orig, handler, true );
rlm@79 2347 },
rlm@79 2348 teardown: function() {
rlm@79 2349 this.removeEventListener( orig, handler, true );
rlm@79 2350 }
rlm@79 2351 };
rlm@79 2352
rlm@79 2353 function handler( e ) {
rlm@79 2354 e = jQuery.event.fix( e );
rlm@79 2355 e.type = fix;
rlm@79 2356 return jQuery.event.handle.call( this, e );
rlm@79 2357 }
rlm@79 2358 });
rlm@79 2359 }
rlm@79 2360
rlm@79 2361 jQuery.each(["bind", "one"], function( i, name ) {
rlm@79 2362 jQuery.fn[ name ] = function( type, data, fn ) {
rlm@79 2363 // Handle object literals
rlm@79 2364 if ( typeof type === "object" ) {
rlm@79 2365 for ( var key in type ) {
rlm@79 2366 this[ name ](key, data, type[key], fn);
rlm@79 2367 }
rlm@79 2368 return this;
rlm@79 2369 }
rlm@79 2370
rlm@79 2371 if ( jQuery.isFunction( data ) ) {
rlm@79 2372 fn = data;
rlm@79 2373 data = undefined;
rlm@79 2374 }
rlm@79 2375
rlm@79 2376 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
rlm@79 2377 jQuery( this ).unbind( event, handler );
rlm@79 2378 return fn.apply( this, arguments );
rlm@79 2379 }) : fn;
rlm@79 2380
rlm@79 2381 if ( type === "unload" && name !== "one" ) {
rlm@79 2382 this.one( type, data, fn );
rlm@79 2383
rlm@79 2384 } else {
rlm@79 2385 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 2386 jQuery.event.add( this[i], type, handler, data );
rlm@79 2387 }
rlm@79 2388 }
rlm@79 2389
rlm@79 2390 return this;
rlm@79 2391 };
rlm@79 2392 });
rlm@79 2393
rlm@79 2394 jQuery.fn.extend({
rlm@79 2395 unbind: function( type, fn ) {
rlm@79 2396 // Handle object literals
rlm@79 2397 if ( typeof type === "object" && !type.preventDefault ) {
rlm@79 2398 for ( var key in type ) {
rlm@79 2399 this.unbind(key, type[key]);
rlm@79 2400 }
rlm@79 2401
rlm@79 2402 } else {
rlm@79 2403 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 2404 jQuery.event.remove( this[i], type, fn );
rlm@79 2405 }
rlm@79 2406 }
rlm@79 2407
rlm@79 2408 return this;
rlm@79 2409 },
rlm@79 2410
rlm@79 2411 delegate: function( selector, types, data, fn ) {
rlm@79 2412 return this.live( types, data, fn, selector );
rlm@79 2413 },
rlm@79 2414
rlm@79 2415 undelegate: function( selector, types, fn ) {
rlm@79 2416 if ( arguments.length === 0 ) {
rlm@79 2417 return this.unbind( "live" );
rlm@79 2418
rlm@79 2419 } else {
rlm@79 2420 return this.die( types, null, fn, selector );
rlm@79 2421 }
rlm@79 2422 },
rlm@79 2423
rlm@79 2424 trigger: function( type, data ) {
rlm@79 2425 return this.each(function() {
rlm@79 2426 jQuery.event.trigger( type, data, this );
rlm@79 2427 });
rlm@79 2428 },
rlm@79 2429
rlm@79 2430 triggerHandler: function( type, data ) {
rlm@79 2431 if ( this[0] ) {
rlm@79 2432 var event = jQuery.Event( type );
rlm@79 2433 event.preventDefault();
rlm@79 2434 event.stopPropagation();
rlm@79 2435 jQuery.event.trigger( event, data, this[0] );
rlm@79 2436 return event.result;
rlm@79 2437 }
rlm@79 2438 },
rlm@79 2439
rlm@79 2440 toggle: function( fn ) {
rlm@79 2441 // Save reference to arguments for access in closure
rlm@79 2442 var args = arguments, i = 1;
rlm@79 2443
rlm@79 2444 // link all the functions, so any of them can unbind this click handler
rlm@79 2445 while ( i < args.length ) {
rlm@79 2446 jQuery.proxy( fn, args[ i++ ] );
rlm@79 2447 }
rlm@79 2448
rlm@79 2449 return this.click( jQuery.proxy( fn, function( event ) {
rlm@79 2450 // Figure out which function to execute
rlm@79 2451 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
rlm@79 2452 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
rlm@79 2453
rlm@79 2454 // Make sure that clicks stop
rlm@79 2455 event.preventDefault();
rlm@79 2456
rlm@79 2457 // and execute the function
rlm@79 2458 return args[ lastToggle ].apply( this, arguments ) || false;
rlm@79 2459 }));
rlm@79 2460 },
rlm@79 2461
rlm@79 2462 hover: function( fnOver, fnOut ) {
rlm@79 2463 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
rlm@79 2464 }
rlm@79 2465 });
rlm@79 2466
rlm@79 2467 var liveMap = {
rlm@79 2468 focus: "focusin",
rlm@79 2469 blur: "focusout",
rlm@79 2470 mouseenter: "mouseover",
rlm@79 2471 mouseleave: "mouseout"
rlm@79 2472 };
rlm@79 2473
rlm@79 2474 jQuery.each(["live", "die"], function( i, name ) {
rlm@79 2475 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
rlm@79 2476 var type, i = 0, match, namespaces, preType,
rlm@79 2477 selector = origSelector || this.selector,
rlm@79 2478 context = origSelector ? this : jQuery( this.context );
rlm@79 2479
rlm@79 2480 if ( jQuery.isFunction( data ) ) {
rlm@79 2481 fn = data;
rlm@79 2482 data = undefined;
rlm@79 2483 }
rlm@79 2484
rlm@79 2485 types = (types || "").split(" ");
rlm@79 2486
rlm@79 2487 while ( (type = types[ i++ ]) != null ) {
rlm@79 2488 match = rnamespaces.exec( type );
rlm@79 2489 namespaces = "";
rlm@79 2490
rlm@79 2491 if ( match ) {
rlm@79 2492 namespaces = match[0];
rlm@79 2493 type = type.replace( rnamespaces, "" );
rlm@79 2494 }
rlm@79 2495
rlm@79 2496 if ( type === "hover" ) {
rlm@79 2497 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
rlm@79 2498 continue;
rlm@79 2499 }
rlm@79 2500
rlm@79 2501 preType = type;
rlm@79 2502
rlm@79 2503 if ( type === "focus" || type === "blur" ) {
rlm@79 2504 types.push( liveMap[ type ] + namespaces );
rlm@79 2505 type = type + namespaces;
rlm@79 2506
rlm@79 2507 } else {
rlm@79 2508 type = (liveMap[ type ] || type) + namespaces;
rlm@79 2509 }
rlm@79 2510
rlm@79 2511 if ( name === "live" ) {
rlm@79 2512 // bind live handler
rlm@79 2513 context.each(function(){
rlm@79 2514 jQuery.event.add( this, liveConvert( type, selector ),
rlm@79 2515 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
rlm@79 2516 });
rlm@79 2517
rlm@79 2518 } else {
rlm@79 2519 // unbind live handler
rlm@79 2520 context.unbind( liveConvert( type, selector ), fn );
rlm@79 2521 }
rlm@79 2522 }
rlm@79 2523
rlm@79 2524 return this;
rlm@79 2525 }
rlm@79 2526 });
rlm@79 2527
rlm@79 2528 function liveHandler( event ) {
rlm@79 2529 var stop, elems = [], selectors = [], args = arguments,
rlm@79 2530 related, match, handleObj, elem, j, i, l, data,
rlm@79 2531 events = jQuery.data( this, "events" );
rlm@79 2532
rlm@79 2533 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
rlm@79 2534 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
rlm@79 2535 return;
rlm@79 2536 }
rlm@79 2537
rlm@79 2538 event.liveFired = this;
rlm@79 2539
rlm@79 2540 var live = events.live.slice(0);
rlm@79 2541
rlm@79 2542 for ( j = 0; j < live.length; j++ ) {
rlm@79 2543 handleObj = live[j];
rlm@79 2544
rlm@79 2545 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
rlm@79 2546 selectors.push( handleObj.selector );
rlm@79 2547
rlm@79 2548 } else {
rlm@79 2549 live.splice( j--, 1 );
rlm@79 2550 }
rlm@79 2551 }
rlm@79 2552
rlm@79 2553 match = jQuery( event.target ).closest( selectors, event.currentTarget );
rlm@79 2554
rlm@79 2555 for ( i = 0, l = match.length; i < l; i++ ) {
rlm@79 2556 for ( j = 0; j < live.length; j++ ) {
rlm@79 2557 handleObj = live[j];
rlm@79 2558
rlm@79 2559 if ( match[i].selector === handleObj.selector ) {
rlm@79 2560 elem = match[i].elem;
rlm@79 2561 related = null;
rlm@79 2562
rlm@79 2563 // Those two events require additional checking
rlm@79 2564 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
rlm@79 2565 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
rlm@79 2566 }
rlm@79 2567
rlm@79 2568 if ( !related || related !== elem ) {
rlm@79 2569 elems.push({ elem: elem, handleObj: handleObj });
rlm@79 2570 }
rlm@79 2571 }
rlm@79 2572 }
rlm@79 2573 }
rlm@79 2574
rlm@79 2575 for ( i = 0, l = elems.length; i < l; i++ ) {
rlm@79 2576 match = elems[i];
rlm@79 2577 event.currentTarget = match.elem;
rlm@79 2578 event.data = match.handleObj.data;
rlm@79 2579 event.handleObj = match.handleObj;
rlm@79 2580
rlm@79 2581 if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
rlm@79 2582 stop = false;
rlm@79 2583 break;
rlm@79 2584 }
rlm@79 2585 }
rlm@79 2586
rlm@79 2587 return stop;
rlm@79 2588 }
rlm@79 2589
rlm@79 2590 function liveConvert( type, selector ) {
rlm@79 2591 return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
rlm@79 2592 }
rlm@79 2593
rlm@79 2594 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
rlm@79 2595 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
rlm@79 2596 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
rlm@79 2597
rlm@79 2598 // Handle event binding
rlm@79 2599 jQuery.fn[ name ] = function( fn ) {
rlm@79 2600 return fn ? this.bind( name, fn ) : this.trigger( name );
rlm@79 2601 };
rlm@79 2602
rlm@79 2603 if ( jQuery.attrFn ) {
rlm@79 2604 jQuery.attrFn[ name ] = true;
rlm@79 2605 }
rlm@79 2606 });
rlm@79 2607
rlm@79 2608 // Prevent memory leaks in IE
rlm@79 2609 // Window isn't included so as not to unbind existing unload events
rlm@79 2610 // More info:
rlm@79 2611 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
rlm@79 2612 if ( window.attachEvent && !window.addEventListener ) {
rlm@79 2613 window.attachEvent("onunload", function() {
rlm@79 2614 for ( var id in jQuery.cache ) {
rlm@79 2615 if ( jQuery.cache[ id ].handle ) {
rlm@79 2616 // Try/Catch is to handle iframes being unloaded, see #4280
rlm@79 2617 try {
rlm@79 2618 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
rlm@79 2619 } catch(e) {}
rlm@79 2620 }
rlm@79 2621 }
rlm@79 2622 });
rlm@79 2623 }
rlm@79 2624 /*!
rlm@79 2625 * Sizzle CSS Selector Engine - v1.0
rlm@79 2626 * Copyright 2009, The Dojo Foundation
rlm@79 2627 * Released under the MIT, BSD, and GPL Licenses.
rlm@79 2628 * More information: http://sizzlejs.com/
rlm@79 2629 */
rlm@79 2630 (function(){
rlm@79 2631
rlm@79 2632 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
rlm@79 2633 done = 0,
rlm@79 2634 toString = Object.prototype.toString,
rlm@79 2635 hasDuplicate = false,
rlm@79 2636 baseHasDuplicate = true;
rlm@79 2637
rlm@79 2638 // Here we check if the JavaScript engine is using some sort of
rlm@79 2639 // optimization where it does not always call our comparision
rlm@79 2640 // function. If that is the case, discard the hasDuplicate value.
rlm@79 2641 // Thus far that includes Google Chrome.
rlm@79 2642 [0, 0].sort(function(){
rlm@79 2643 baseHasDuplicate = false;
rlm@79 2644 return 0;
rlm@79 2645 });
rlm@79 2646
rlm@79 2647 var Sizzle = function(selector, context, results, seed) {
rlm@79 2648 results = results || [];
rlm@79 2649 var origContext = context = context || document;
rlm@79 2650
rlm@79 2651 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
rlm@79 2652 return [];
rlm@79 2653 }
rlm@79 2654
rlm@79 2655 if ( !selector || typeof selector !== "string" ) {
rlm@79 2656 return results;
rlm@79 2657 }
rlm@79 2658
rlm@79 2659 var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
rlm@79 2660 soFar = selector;
rlm@79 2661
rlm@79 2662 // Reset the position of the chunker regexp (start from head)
rlm@79 2663 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
rlm@79 2664 soFar = m[3];
rlm@79 2665
rlm@79 2666 parts.push( m[1] );
rlm@79 2667
rlm@79 2668 if ( m[2] ) {
rlm@79 2669 extra = m[3];
rlm@79 2670 break;
rlm@79 2671 }
rlm@79 2672 }
rlm@79 2673
rlm@79 2674 if ( parts.length > 1 && origPOS.exec( selector ) ) {
rlm@79 2675 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
rlm@79 2676 set = posProcess( parts[0] + parts[1], context );
rlm@79 2677 } else {
rlm@79 2678 set = Expr.relative[ parts[0] ] ?
rlm@79 2679 [ context ] :
rlm@79 2680 Sizzle( parts.shift(), context );
rlm@79 2681
rlm@79 2682 while ( parts.length ) {
rlm@79 2683 selector = parts.shift();
rlm@79 2684
rlm@79 2685 if ( Expr.relative[ selector ] ) {
rlm@79 2686 selector += parts.shift();
rlm@79 2687 }
rlm@79 2688
rlm@79 2689 set = posProcess( selector, set );
rlm@79 2690 }
rlm@79 2691 }
rlm@79 2692 } else {
rlm@79 2693 // Take a shortcut and set the context if the root selector is an ID
rlm@79 2694 // (but not if it'll be faster if the inner selector is an ID)
rlm@79 2695 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
rlm@79 2696 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
rlm@79 2697 var ret = Sizzle.find( parts.shift(), context, contextXML );
rlm@79 2698 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
rlm@79 2699 }
rlm@79 2700
rlm@79 2701 if ( context ) {
rlm@79 2702 var ret = seed ?
rlm@79 2703 { expr: parts.pop(), set: makeArray(seed) } :
rlm@79 2704 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
rlm@79 2705 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
rlm@79 2706
rlm@79 2707 if ( parts.length > 0 ) {
rlm@79 2708 checkSet = makeArray(set);
rlm@79 2709 } else {
rlm@79 2710 prune = false;
rlm@79 2711 }
rlm@79 2712
rlm@79 2713 while ( parts.length ) {
rlm@79 2714 var cur = parts.pop(), pop = cur;
rlm@79 2715
rlm@79 2716 if ( !Expr.relative[ cur ] ) {
rlm@79 2717 cur = "";
rlm@79 2718 } else {
rlm@79 2719 pop = parts.pop();
rlm@79 2720 }
rlm@79 2721
rlm@79 2722 if ( pop == null ) {
rlm@79 2723 pop = context;
rlm@79 2724 }
rlm@79 2725
rlm@79 2726 Expr.relative[ cur ]( checkSet, pop, contextXML );
rlm@79 2727 }
rlm@79 2728 } else {
rlm@79 2729 checkSet = parts = [];
rlm@79 2730 }
rlm@79 2731 }
rlm@79 2732
rlm@79 2733 if ( !checkSet ) {
rlm@79 2734 checkSet = set;
rlm@79 2735 }
rlm@79 2736
rlm@79 2737 if ( !checkSet ) {
rlm@79 2738 Sizzle.error( cur || selector );
rlm@79 2739 }
rlm@79 2740
rlm@79 2741 if ( toString.call(checkSet) === "[object Array]" ) {
rlm@79 2742 if ( !prune ) {
rlm@79 2743 results.push.apply( results, checkSet );
rlm@79 2744 } else if ( context && context.nodeType === 1 ) {
rlm@79 2745 for ( var i = 0; checkSet[i] != null; i++ ) {
rlm@79 2746 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
rlm@79 2747 results.push( set[i] );
rlm@79 2748 }
rlm@79 2749 }
rlm@79 2750 } else {
rlm@79 2751 for ( var i = 0; checkSet[i] != null; i++ ) {
rlm@79 2752 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
rlm@79 2753 results.push( set[i] );
rlm@79 2754 }
rlm@79 2755 }
rlm@79 2756 }
rlm@79 2757 } else {
rlm@79 2758 makeArray( checkSet, results );
rlm@79 2759 }
rlm@79 2760
rlm@79 2761 if ( extra ) {
rlm@79 2762 Sizzle( extra, origContext, results, seed );
rlm@79 2763 Sizzle.uniqueSort( results );
rlm@79 2764 }
rlm@79 2765
rlm@79 2766 return results;
rlm@79 2767 };
rlm@79 2768
rlm@79 2769 Sizzle.uniqueSort = function(results){
rlm@79 2770 if ( sortOrder ) {
rlm@79 2771 hasDuplicate = baseHasDuplicate;
rlm@79 2772 results.sort(sortOrder);
rlm@79 2773
rlm@79 2774 if ( hasDuplicate ) {
rlm@79 2775 for ( var i = 1; i < results.length; i++ ) {
rlm@79 2776 if ( results[i] === results[i-1] ) {
rlm@79 2777 results.splice(i--, 1);
rlm@79 2778 }
rlm@79 2779 }
rlm@79 2780 }
rlm@79 2781 }
rlm@79 2782
rlm@79 2783 return results;
rlm@79 2784 };
rlm@79 2785
rlm@79 2786 Sizzle.matches = function(expr, set){
rlm@79 2787 return Sizzle(expr, null, null, set);
rlm@79 2788 };
rlm@79 2789
rlm@79 2790 Sizzle.find = function(expr, context, isXML){
rlm@79 2791 var set, match;
rlm@79 2792
rlm@79 2793 if ( !expr ) {
rlm@79 2794 return [];
rlm@79 2795 }
rlm@79 2796
rlm@79 2797 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
rlm@79 2798 var type = Expr.order[i], match;
rlm@79 2799
rlm@79 2800 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
rlm@79 2801 var left = match[1];
rlm@79 2802 match.splice(1,1);
rlm@79 2803
rlm@79 2804 if ( left.substr( left.length - 1 ) !== "\\" ) {
rlm@79 2805 match[1] = (match[1] || "").replace(/\\/g, "");
rlm@79 2806 set = Expr.find[ type ]( match, context, isXML );
rlm@79 2807 if ( set != null ) {
rlm@79 2808 expr = expr.replace( Expr.match[ type ], "" );
rlm@79 2809 break;
rlm@79 2810 }
rlm@79 2811 }
rlm@79 2812 }
rlm@79 2813 }
rlm@79 2814
rlm@79 2815 if ( !set ) {
rlm@79 2816 set = context.getElementsByTagName("*");
rlm@79 2817 }
rlm@79 2818
rlm@79 2819 return {set: set, expr: expr};
rlm@79 2820 };
rlm@79 2821
rlm@79 2822 Sizzle.filter = function(expr, set, inplace, not){
rlm@79 2823 var old = expr, result = [], curLoop = set, match, anyFound,
rlm@79 2824 isXMLFilter = set && set[0] && isXML(set[0]);
rlm@79 2825
rlm@79 2826 while ( expr && set.length ) {
rlm@79 2827 for ( var type in Expr.filter ) {
rlm@79 2828 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
rlm@79 2829 var filter = Expr.filter[ type ], found, item, left = match[1];
rlm@79 2830 anyFound = false;
rlm@79 2831
rlm@79 2832 match.splice(1,1);
rlm@79 2833
rlm@79 2834 if ( left.substr( left.length - 1 ) === "\\" ) {
rlm@79 2835 continue;
rlm@79 2836 }
rlm@79 2837
rlm@79 2838 if ( curLoop === result ) {
rlm@79 2839 result = [];
rlm@79 2840 }
rlm@79 2841
rlm@79 2842 if ( Expr.preFilter[ type ] ) {
rlm@79 2843 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
rlm@79 2844
rlm@79 2845 if ( !match ) {
rlm@79 2846 anyFound = found = true;
rlm@79 2847 } else if ( match === true ) {
rlm@79 2848 continue;
rlm@79 2849 }
rlm@79 2850 }
rlm@79 2851
rlm@79 2852 if ( match ) {
rlm@79 2853 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
rlm@79 2854 if ( item ) {
rlm@79 2855 found = filter( item, match, i, curLoop );
rlm@79 2856 var pass = not ^ !!found;
rlm@79 2857
rlm@79 2858 if ( inplace && found != null ) {
rlm@79 2859 if ( pass ) {
rlm@79 2860 anyFound = true;
rlm@79 2861 } else {
rlm@79 2862 curLoop[i] = false;
rlm@79 2863 }
rlm@79 2864 } else if ( pass ) {
rlm@79 2865 result.push( item );
rlm@79 2866 anyFound = true;
rlm@79 2867 }
rlm@79 2868 }
rlm@79 2869 }
rlm@79 2870 }
rlm@79 2871
rlm@79 2872 if ( found !== undefined ) {
rlm@79 2873 if ( !inplace ) {
rlm@79 2874 curLoop = result;
rlm@79 2875 }
rlm@79 2876
rlm@79 2877 expr = expr.replace( Expr.match[ type ], "" );
rlm@79 2878
rlm@79 2879 if ( !anyFound ) {
rlm@79 2880 return [];
rlm@79 2881 }
rlm@79 2882
rlm@79 2883 break;
rlm@79 2884 }
rlm@79 2885 }
rlm@79 2886 }
rlm@79 2887
rlm@79 2888 // Improper expression
rlm@79 2889 if ( expr === old ) {
rlm@79 2890 if ( anyFound == null ) {
rlm@79 2891 Sizzle.error( expr );
rlm@79 2892 } else {
rlm@79 2893 break;
rlm@79 2894 }
rlm@79 2895 }
rlm@79 2896
rlm@79 2897 old = expr;
rlm@79 2898 }
rlm@79 2899
rlm@79 2900 return curLoop;
rlm@79 2901 };
rlm@79 2902
rlm@79 2903 Sizzle.error = function( msg ) {
rlm@79 2904 throw "Syntax error, unrecognized expression: " + msg;
rlm@79 2905 };
rlm@79 2906
rlm@79 2907 var Expr = Sizzle.selectors = {
rlm@79 2908 order: [ "ID", "NAME", "TAG" ],
rlm@79 2909 match: {
rlm@79 2910 ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
rlm@79 2911 CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
rlm@79 2912 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
rlm@79 2913 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
rlm@79 2914 TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
rlm@79 2915 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
rlm@79 2916 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
rlm@79 2917 PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
rlm@79 2918 },
rlm@79 2919 leftMatch: {},
rlm@79 2920 attrMap: {
rlm@79 2921 "class": "className",
rlm@79 2922 "for": "htmlFor"
rlm@79 2923 },
rlm@79 2924 attrHandle: {
rlm@79 2925 href: function(elem){
rlm@79 2926 return elem.getAttribute("href");
rlm@79 2927 }
rlm@79 2928 },
rlm@79 2929 relative: {
rlm@79 2930 "+": function(checkSet, part){
rlm@79 2931 var isPartStr = typeof part === "string",
rlm@79 2932 isTag = isPartStr && !/\W/.test(part),
rlm@79 2933 isPartStrNotTag = isPartStr && !isTag;
rlm@79 2934
rlm@79 2935 if ( isTag ) {
rlm@79 2936 part = part.toLowerCase();
rlm@79 2937 }
rlm@79 2938
rlm@79 2939 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
rlm@79 2940 if ( (elem = checkSet[i]) ) {
rlm@79 2941 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
rlm@79 2942
rlm@79 2943 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
rlm@79 2944 elem || false :
rlm@79 2945 elem === part;
rlm@79 2946 }
rlm@79 2947 }
rlm@79 2948
rlm@79 2949 if ( isPartStrNotTag ) {
rlm@79 2950 Sizzle.filter( part, checkSet, true );
rlm@79 2951 }
rlm@79 2952 },
rlm@79 2953 ">": function(checkSet, part){
rlm@79 2954 var isPartStr = typeof part === "string";
rlm@79 2955
rlm@79 2956 if ( isPartStr && !/\W/.test(part) ) {
rlm@79 2957 part = part.toLowerCase();
rlm@79 2958
rlm@79 2959 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
rlm@79 2960 var elem = checkSet[i];
rlm@79 2961 if ( elem ) {
rlm@79 2962 var parent = elem.parentNode;
rlm@79 2963 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
rlm@79 2964 }
rlm@79 2965 }
rlm@79 2966 } else {
rlm@79 2967 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
rlm@79 2968 var elem = checkSet[i];
rlm@79 2969 if ( elem ) {
rlm@79 2970 checkSet[i] = isPartStr ?
rlm@79 2971 elem.parentNode :
rlm@79 2972 elem.parentNode === part;
rlm@79 2973 }
rlm@79 2974 }
rlm@79 2975
rlm@79 2976 if ( isPartStr ) {
rlm@79 2977 Sizzle.filter( part, checkSet, true );
rlm@79 2978 }
rlm@79 2979 }
rlm@79 2980 },
rlm@79 2981 "": function(checkSet, part, isXML){
rlm@79 2982 var doneName = done++, checkFn = dirCheck;
rlm@79 2983
rlm@79 2984 if ( typeof part === "string" && !/\W/.test(part) ) {
rlm@79 2985 var nodeCheck = part = part.toLowerCase();
rlm@79 2986 checkFn = dirNodeCheck;
rlm@79 2987 }
rlm@79 2988
rlm@79 2989 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
rlm@79 2990 },
rlm@79 2991 "~": function(checkSet, part, isXML){
rlm@79 2992 var doneName = done++, checkFn = dirCheck;
rlm@79 2993
rlm@79 2994 if ( typeof part === "string" && !/\W/.test(part) ) {
rlm@79 2995 var nodeCheck = part = part.toLowerCase();
rlm@79 2996 checkFn = dirNodeCheck;
rlm@79 2997 }
rlm@79 2998
rlm@79 2999 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
rlm@79 3000 }
rlm@79 3001 },
rlm@79 3002 find: {
rlm@79 3003 ID: function(match, context, isXML){
rlm@79 3004 if ( typeof context.getElementById !== "undefined" && !isXML ) {
rlm@79 3005 var m = context.getElementById(match[1]);
rlm@79 3006 return m ? [m] : [];
rlm@79 3007 }
rlm@79 3008 },
rlm@79 3009 NAME: function(match, context){
rlm@79 3010 if ( typeof context.getElementsByName !== "undefined" ) {
rlm@79 3011 var ret = [], results = context.getElementsByName(match[1]);
rlm@79 3012
rlm@79 3013 for ( var i = 0, l = results.length; i < l; i++ ) {
rlm@79 3014 if ( results[i].getAttribute("name") === match[1] ) {
rlm@79 3015 ret.push( results[i] );
rlm@79 3016 }
rlm@79 3017 }
rlm@79 3018
rlm@79 3019 return ret.length === 0 ? null : ret;
rlm@79 3020 }
rlm@79 3021 },
rlm@79 3022 TAG: function(match, context){
rlm@79 3023 return context.getElementsByTagName(match[1]);
rlm@79 3024 }
rlm@79 3025 },
rlm@79 3026 preFilter: {
rlm@79 3027 CLASS: function(match, curLoop, inplace, result, not, isXML){
rlm@79 3028 match = " " + match[1].replace(/\\/g, "") + " ";
rlm@79 3029
rlm@79 3030 if ( isXML ) {
rlm@79 3031 return match;
rlm@79 3032 }
rlm@79 3033
rlm@79 3034 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
rlm@79 3035 if ( elem ) {
rlm@79 3036 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
rlm@79 3037 if ( !inplace ) {
rlm@79 3038 result.push( elem );
rlm@79 3039 }
rlm@79 3040 } else if ( inplace ) {
rlm@79 3041 curLoop[i] = false;
rlm@79 3042 }
rlm@79 3043 }
rlm@79 3044 }
rlm@79 3045
rlm@79 3046 return false;
rlm@79 3047 },
rlm@79 3048 ID: function(match){
rlm@79 3049 return match[1].replace(/\\/g, "");
rlm@79 3050 },
rlm@79 3051 TAG: function(match, curLoop){
rlm@79 3052 return match[1].toLowerCase();
rlm@79 3053 },
rlm@79 3054 CHILD: function(match){
rlm@79 3055 if ( match[1] === "nth" ) {
rlm@79 3056 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
rlm@79 3057 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
rlm@79 3058 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
rlm@79 3059 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
rlm@79 3060
rlm@79 3061 // calculate the numbers (first)n+(last) including if they are negative
rlm@79 3062 match[2] = (test[1] + (test[2] || 1)) - 0;
rlm@79 3063 match[3] = test[3] - 0;
rlm@79 3064 }
rlm@79 3065
rlm@79 3066 // TODO: Move to normal caching system
rlm@79 3067 match[0] = done++;
rlm@79 3068
rlm@79 3069 return match;
rlm@79 3070 },
rlm@79 3071 ATTR: function(match, curLoop, inplace, result, not, isXML){
rlm@79 3072 var name = match[1].replace(/\\/g, "");
rlm@79 3073
rlm@79 3074 if ( !isXML && Expr.attrMap[name] ) {
rlm@79 3075 match[1] = Expr.attrMap[name];
rlm@79 3076 }
rlm@79 3077
rlm@79 3078 if ( match[2] === "~=" ) {
rlm@79 3079 match[4] = " " + match[4] + " ";
rlm@79 3080 }
rlm@79 3081
rlm@79 3082 return match;
rlm@79 3083 },
rlm@79 3084 PSEUDO: function(match, curLoop, inplace, result, not){
rlm@79 3085 if ( match[1] === "not" ) {
rlm@79 3086 // If we're dealing with a complex expression, or a simple one
rlm@79 3087 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
rlm@79 3088 match[3] = Sizzle(match[3], null, null, curLoop);
rlm@79 3089 } else {
rlm@79 3090 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
rlm@79 3091 if ( !inplace ) {
rlm@79 3092 result.push.apply( result, ret );
rlm@79 3093 }
rlm@79 3094 return false;
rlm@79 3095 }
rlm@79 3096 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
rlm@79 3097 return true;
rlm@79 3098 }
rlm@79 3099
rlm@79 3100 return match;
rlm@79 3101 },
rlm@79 3102 POS: function(match){
rlm@79 3103 match.unshift( true );
rlm@79 3104 return match;
rlm@79 3105 }
rlm@79 3106 },
rlm@79 3107 filters: {
rlm@79 3108 enabled: function(elem){
rlm@79 3109 return elem.disabled === false && elem.type !== "hidden";
rlm@79 3110 },
rlm@79 3111 disabled: function(elem){
rlm@79 3112 return elem.disabled === true;
rlm@79 3113 },
rlm@79 3114 checked: function(elem){
rlm@79 3115 return elem.checked === true;
rlm@79 3116 },
rlm@79 3117 selected: function(elem){
rlm@79 3118 // Accessing this property makes selected-by-default
rlm@79 3119 // options in Safari work properly
rlm@79 3120 elem.parentNode.selectedIndex;
rlm@79 3121 return elem.selected === true;
rlm@79 3122 },
rlm@79 3123 parent: function(elem){
rlm@79 3124 return !!elem.firstChild;
rlm@79 3125 },
rlm@79 3126 empty: function(elem){
rlm@79 3127 return !elem.firstChild;
rlm@79 3128 },
rlm@79 3129 has: function(elem, i, match){
rlm@79 3130 return !!Sizzle( match[3], elem ).length;
rlm@79 3131 },
rlm@79 3132 header: function(elem){
rlm@79 3133 return /h\d/i.test( elem.nodeName );
rlm@79 3134 },
rlm@79 3135 text: function(elem){
rlm@79 3136 return "text" === elem.type;
rlm@79 3137 },
rlm@79 3138 radio: function(elem){
rlm@79 3139 return "radio" === elem.type;
rlm@79 3140 },
rlm@79 3141 checkbox: function(elem){
rlm@79 3142 return "checkbox" === elem.type;
rlm@79 3143 },
rlm@79 3144 file: function(elem){
rlm@79 3145 return "file" === elem.type;
rlm@79 3146 },
rlm@79 3147 password: function(elem){
rlm@79 3148 return "password" === elem.type;
rlm@79 3149 },
rlm@79 3150 submit: function(elem){
rlm@79 3151 return "submit" === elem.type;
rlm@79 3152 },
rlm@79 3153 image: function(elem){
rlm@79 3154 return "image" === elem.type;
rlm@79 3155 },
rlm@79 3156 reset: function(elem){
rlm@79 3157 return "reset" === elem.type;
rlm@79 3158 },
rlm@79 3159 button: function(elem){
rlm@79 3160 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
rlm@79 3161 },
rlm@79 3162 input: function(elem){
rlm@79 3163 return /input|select|textarea|button/i.test(elem.nodeName);
rlm@79 3164 }
rlm@79 3165 },
rlm@79 3166 setFilters: {
rlm@79 3167 first: function(elem, i){
rlm@79 3168 return i === 0;
rlm@79 3169 },
rlm@79 3170 last: function(elem, i, match, array){
rlm@79 3171 return i === array.length - 1;
rlm@79 3172 },
rlm@79 3173 even: function(elem, i){
rlm@79 3174 return i % 2 === 0;
rlm@79 3175 },
rlm@79 3176 odd: function(elem, i){
rlm@79 3177 return i % 2 === 1;
rlm@79 3178 },
rlm@79 3179 lt: function(elem, i, match){
rlm@79 3180 return i < match[3] - 0;
rlm@79 3181 },
rlm@79 3182 gt: function(elem, i, match){
rlm@79 3183 return i > match[3] - 0;
rlm@79 3184 },
rlm@79 3185 nth: function(elem, i, match){
rlm@79 3186 return match[3] - 0 === i;
rlm@79 3187 },
rlm@79 3188 eq: function(elem, i, match){
rlm@79 3189 return match[3] - 0 === i;
rlm@79 3190 }
rlm@79 3191 },
rlm@79 3192 filter: {
rlm@79 3193 PSEUDO: function(elem, match, i, array){
rlm@79 3194 var name = match[1], filter = Expr.filters[ name ];
rlm@79 3195
rlm@79 3196 if ( filter ) {
rlm@79 3197 return filter( elem, i, match, array );
rlm@79 3198 } else if ( name === "contains" ) {
rlm@79 3199 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
rlm@79 3200 } else if ( name === "not" ) {
rlm@79 3201 var not = match[3];
rlm@79 3202
rlm@79 3203 for ( var i = 0, l = not.length; i < l; i++ ) {
rlm@79 3204 if ( not[i] === elem ) {
rlm@79 3205 return false;
rlm@79 3206 }
rlm@79 3207 }
rlm@79 3208
rlm@79 3209 return true;
rlm@79 3210 } else {
rlm@79 3211 Sizzle.error( "Syntax error, unrecognized expression: " + name );
rlm@79 3212 }
rlm@79 3213 },
rlm@79 3214 CHILD: function(elem, match){
rlm@79 3215 var type = match[1], node = elem;
rlm@79 3216 switch (type) {
rlm@79 3217 case 'only':
rlm@79 3218 case 'first':
rlm@79 3219 while ( (node = node.previousSibling) ) {
rlm@79 3220 if ( node.nodeType === 1 ) {
rlm@79 3221 return false;
rlm@79 3222 }
rlm@79 3223 }
rlm@79 3224 if ( type === "first" ) {
rlm@79 3225 return true;
rlm@79 3226 }
rlm@79 3227 node = elem;
rlm@79 3228 case 'last':
rlm@79 3229 while ( (node = node.nextSibling) ) {
rlm@79 3230 if ( node.nodeType === 1 ) {
rlm@79 3231 return false;
rlm@79 3232 }
rlm@79 3233 }
rlm@79 3234 return true;
rlm@79 3235 case 'nth':
rlm@79 3236 var first = match[2], last = match[3];
rlm@79 3237
rlm@79 3238 if ( first === 1 && last === 0 ) {
rlm@79 3239 return true;
rlm@79 3240 }
rlm@79 3241
rlm@79 3242 var doneName = match[0],
rlm@79 3243 parent = elem.parentNode;
rlm@79 3244
rlm@79 3245 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
rlm@79 3246 var count = 0;
rlm@79 3247 for ( node = parent.firstChild; node; node = node.nextSibling ) {
rlm@79 3248 if ( node.nodeType === 1 ) {
rlm@79 3249 node.nodeIndex = ++count;
rlm@79 3250 }
rlm@79 3251 }
rlm@79 3252 parent.sizcache = doneName;
rlm@79 3253 }
rlm@79 3254
rlm@79 3255 var diff = elem.nodeIndex - last;
rlm@79 3256 if ( first === 0 ) {
rlm@79 3257 return diff === 0;
rlm@79 3258 } else {
rlm@79 3259 return ( diff % first === 0 && diff / first >= 0 );
rlm@79 3260 }
rlm@79 3261 }
rlm@79 3262 },
rlm@79 3263 ID: function(elem, match){
rlm@79 3264 return elem.nodeType === 1 && elem.getAttribute("id") === match;
rlm@79 3265 },
rlm@79 3266 TAG: function(elem, match){
rlm@79 3267 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
rlm@79 3268 },
rlm@79 3269 CLASS: function(elem, match){
rlm@79 3270 return (" " + (elem.className || elem.getAttribute("class")) + " ")
rlm@79 3271 .indexOf( match ) > -1;
rlm@79 3272 },
rlm@79 3273 ATTR: function(elem, match){
rlm@79 3274 var name = match[1],
rlm@79 3275 result = Expr.attrHandle[ name ] ?
rlm@79 3276 Expr.attrHandle[ name ]( elem ) :
rlm@79 3277 elem[ name ] != null ?
rlm@79 3278 elem[ name ] :
rlm@79 3279 elem.getAttribute( name ),
rlm@79 3280 value = result + "",
rlm@79 3281 type = match[2],
rlm@79 3282 check = match[4];
rlm@79 3283
rlm@79 3284 return result == null ?
rlm@79 3285 type === "!=" :
rlm@79 3286 type === "=" ?
rlm@79 3287 value === check :
rlm@79 3288 type === "*=" ?
rlm@79 3289 value.indexOf(check) >= 0 :
rlm@79 3290 type === "~=" ?
rlm@79 3291 (" " + value + " ").indexOf(check) >= 0 :
rlm@79 3292 !check ?
rlm@79 3293 value && result !== false :
rlm@79 3294 type === "!=" ?
rlm@79 3295 value !== check :
rlm@79 3296 type === "^=" ?
rlm@79 3297 value.indexOf(check) === 0 :
rlm@79 3298 type === "$=" ?
rlm@79 3299 value.substr(value.length - check.length) === check :
rlm@79 3300 type === "|=" ?
rlm@79 3301 value === check || value.substr(0, check.length + 1) === check + "-" :
rlm@79 3302 false;
rlm@79 3303 },
rlm@79 3304 POS: function(elem, match, i, array){
rlm@79 3305 var name = match[2], filter = Expr.setFilters[ name ];
rlm@79 3306
rlm@79 3307 if ( filter ) {
rlm@79 3308 return filter( elem, i, match, array );
rlm@79 3309 }
rlm@79 3310 }
rlm@79 3311 }
rlm@79 3312 };
rlm@79 3313
rlm@79 3314 var origPOS = Expr.match.POS;
rlm@79 3315
rlm@79 3316 for ( var type in Expr.match ) {
rlm@79 3317 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
rlm@79 3318 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
rlm@79 3319 return "\\" + (num - 0 + 1);
rlm@79 3320 }));
rlm@79 3321 }
rlm@79 3322
rlm@79 3323 var makeArray = function(array, results) {
rlm@79 3324 array = Array.prototype.slice.call( array, 0 );
rlm@79 3325
rlm@79 3326 if ( results ) {
rlm@79 3327 results.push.apply( results, array );
rlm@79 3328 return results;
rlm@79 3329 }
rlm@79 3330
rlm@79 3331 return array;
rlm@79 3332 };
rlm@79 3333
rlm@79 3334 // Perform a simple check to determine if the browser is capable of
rlm@79 3335 // converting a NodeList to an array using builtin methods.
rlm@79 3336 // Also verifies that the returned array holds DOM nodes
rlm@79 3337 // (which is not the case in the Blackberry browser)
rlm@79 3338 try {
rlm@79 3339 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
rlm@79 3340
rlm@79 3341 // Provide a fallback method if it does not work
rlm@79 3342 } catch(e){
rlm@79 3343 makeArray = function(array, results) {
rlm@79 3344 var ret = results || [];
rlm@79 3345
rlm@79 3346 if ( toString.call(array) === "[object Array]" ) {
rlm@79 3347 Array.prototype.push.apply( ret, array );
rlm@79 3348 } else {
rlm@79 3349 if ( typeof array.length === "number" ) {
rlm@79 3350 for ( var i = 0, l = array.length; i < l; i++ ) {
rlm@79 3351 ret.push( array[i] );
rlm@79 3352 }
rlm@79 3353 } else {
rlm@79 3354 for ( var i = 0; array[i]; i++ ) {
rlm@79 3355 ret.push( array[i] );
rlm@79 3356 }
rlm@79 3357 }
rlm@79 3358 }
rlm@79 3359
rlm@79 3360 return ret;
rlm@79 3361 };
rlm@79 3362 }
rlm@79 3363
rlm@79 3364 var sortOrder;
rlm@79 3365
rlm@79 3366 if ( document.documentElement.compareDocumentPosition ) {
rlm@79 3367 sortOrder = function( a, b ) {
rlm@79 3368 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
rlm@79 3369 if ( a == b ) {
rlm@79 3370 hasDuplicate = true;
rlm@79 3371 }
rlm@79 3372 return a.compareDocumentPosition ? -1 : 1;
rlm@79 3373 }
rlm@79 3374
rlm@79 3375 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
rlm@79 3376 if ( ret === 0 ) {
rlm@79 3377 hasDuplicate = true;
rlm@79 3378 }
rlm@79 3379 return ret;
rlm@79 3380 };
rlm@79 3381 } else if ( "sourceIndex" in document.documentElement ) {
rlm@79 3382 sortOrder = function( a, b ) {
rlm@79 3383 if ( !a.sourceIndex || !b.sourceIndex ) {
rlm@79 3384 if ( a == b ) {
rlm@79 3385 hasDuplicate = true;
rlm@79 3386 }
rlm@79 3387 return a.sourceIndex ? -1 : 1;
rlm@79 3388 }
rlm@79 3389
rlm@79 3390 var ret = a.sourceIndex - b.sourceIndex;
rlm@79 3391 if ( ret === 0 ) {
rlm@79 3392 hasDuplicate = true;
rlm@79 3393 }
rlm@79 3394 return ret;
rlm@79 3395 };
rlm@79 3396 } else if ( document.createRange ) {
rlm@79 3397 sortOrder = function( a, b ) {
rlm@79 3398 if ( !a.ownerDocument || !b.ownerDocument ) {
rlm@79 3399 if ( a == b ) {
rlm@79 3400 hasDuplicate = true;
rlm@79 3401 }
rlm@79 3402 return a.ownerDocument ? -1 : 1;
rlm@79 3403 }
rlm@79 3404
rlm@79 3405 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
rlm@79 3406 aRange.setStart(a, 0);
rlm@79 3407 aRange.setEnd(a, 0);
rlm@79 3408 bRange.setStart(b, 0);
rlm@79 3409 bRange.setEnd(b, 0);
rlm@79 3410 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
rlm@79 3411 if ( ret === 0 ) {
rlm@79 3412 hasDuplicate = true;
rlm@79 3413 }
rlm@79 3414 return ret;
rlm@79 3415 };
rlm@79 3416 }
rlm@79 3417
rlm@79 3418 // Utility function for retreiving the text value of an array of DOM nodes
rlm@79 3419 function getText( elems ) {
rlm@79 3420 var ret = "", elem;
rlm@79 3421
rlm@79 3422 for ( var i = 0; elems[i]; i++ ) {
rlm@79 3423 elem = elems[i];
rlm@79 3424
rlm@79 3425 // Get the text from text nodes and CDATA nodes
rlm@79 3426 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
rlm@79 3427 ret += elem.nodeValue;
rlm@79 3428
rlm@79 3429 // Traverse everything else, except comment nodes
rlm@79 3430 } else if ( elem.nodeType !== 8 ) {
rlm@79 3431 ret += getText( elem.childNodes );
rlm@79 3432 }
rlm@79 3433 }
rlm@79 3434
rlm@79 3435 return ret;
rlm@79 3436 }
rlm@79 3437
rlm@79 3438 // Check to see if the browser returns elements by name when
rlm@79 3439 // querying by getElementById (and provide a workaround)
rlm@79 3440 (function(){
rlm@79 3441 // We're going to inject a fake input element with a specified name
rlm@79 3442 var form = document.createElement("div"),
rlm@79 3443 id = "script" + (new Date).getTime();
rlm@79 3444 form.innerHTML = "<a name='" + id + "'/>";
rlm@79 3445
rlm@79 3446 // Inject it into the root element, check its status, and remove it quickly
rlm@79 3447 var root = document.documentElement;
rlm@79 3448 root.insertBefore( form, root.firstChild );
rlm@79 3449
rlm@79 3450 // The workaround has to do additional checks after a getElementById
rlm@79 3451 // Which slows things down for other browsers (hence the branching)
rlm@79 3452 if ( document.getElementById( id ) ) {
rlm@79 3453 Expr.find.ID = function(match, context, isXML){
rlm@79 3454 if ( typeof context.getElementById !== "undefined" && !isXML ) {
rlm@79 3455 var m = context.getElementById(match[1]);
rlm@79 3456 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
rlm@79 3457 }
rlm@79 3458 };
rlm@79 3459
rlm@79 3460 Expr.filter.ID = function(elem, match){
rlm@79 3461 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
rlm@79 3462 return elem.nodeType === 1 && node && node.nodeValue === match;
rlm@79 3463 };
rlm@79 3464 }
rlm@79 3465
rlm@79 3466 root.removeChild( form );
rlm@79 3467 root = form = null; // release memory in IE
rlm@79 3468 })();
rlm@79 3469
rlm@79 3470 (function(){
rlm@79 3471 // Check to see if the browser returns only elements
rlm@79 3472 // when doing getElementsByTagName("*")
rlm@79 3473
rlm@79 3474 // Create a fake element
rlm@79 3475 var div = document.createElement("div");
rlm@79 3476 div.appendChild( document.createComment("") );
rlm@79 3477
rlm@79 3478 // Make sure no comments are found
rlm@79 3479 if ( div.getElementsByTagName("*").length > 0 ) {
rlm@79 3480 Expr.find.TAG = function(match, context){
rlm@79 3481 var results = context.getElementsByTagName(match[1]);
rlm@79 3482
rlm@79 3483 // Filter out possible comments
rlm@79 3484 if ( match[1] === "*" ) {
rlm@79 3485 var tmp = [];
rlm@79 3486
rlm@79 3487 for ( var i = 0; results[i]; i++ ) {
rlm@79 3488 if ( results[i].nodeType === 1 ) {
rlm@79 3489 tmp.push( results[i] );
rlm@79 3490 }
rlm@79 3491 }
rlm@79 3492
rlm@79 3493 results = tmp;
rlm@79 3494 }
rlm@79 3495
rlm@79 3496 return results;
rlm@79 3497 };
rlm@79 3498 }
rlm@79 3499
rlm@79 3500 // Check to see if an attribute returns normalized href attributes
rlm@79 3501 div.innerHTML = "<a href='#'></a>";
rlm@79 3502 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
rlm@79 3503 div.firstChild.getAttribute("href") !== "#" ) {
rlm@79 3504 Expr.attrHandle.href = function(elem){
rlm@79 3505 return elem.getAttribute("href", 2);
rlm@79 3506 };
rlm@79 3507 }
rlm@79 3508
rlm@79 3509 div = null; // release memory in IE
rlm@79 3510 })();
rlm@79 3511
rlm@79 3512 if ( document.querySelectorAll ) {
rlm@79 3513 (function(){
rlm@79 3514 var oldSizzle = Sizzle, div = document.createElement("div");
rlm@79 3515 div.innerHTML = "<p class='TEST'></p>";
rlm@79 3516
rlm@79 3517 // Safari can't handle uppercase or unicode characters when
rlm@79 3518 // in quirks mode.
rlm@79 3519 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
rlm@79 3520 return;
rlm@79 3521 }
rlm@79 3522
rlm@79 3523 Sizzle = function(query, context, extra, seed){
rlm@79 3524 context = context || document;
rlm@79 3525
rlm@79 3526 // Only use querySelectorAll on non-XML documents
rlm@79 3527 // (ID selectors don't work in non-HTML documents)
rlm@79 3528 if ( !seed && context.nodeType === 9 && !isXML(context) ) {
rlm@79 3529 try {
rlm@79 3530 return makeArray( context.querySelectorAll(query), extra );
rlm@79 3531 } catch(e){}
rlm@79 3532 }
rlm@79 3533
rlm@79 3534 return oldSizzle(query, context, extra, seed);
rlm@79 3535 };
rlm@79 3536
rlm@79 3537 for ( var prop in oldSizzle ) {
rlm@79 3538 Sizzle[ prop ] = oldSizzle[ prop ];
rlm@79 3539 }
rlm@79 3540
rlm@79 3541 div = null; // release memory in IE
rlm@79 3542 })();
rlm@79 3543 }
rlm@79 3544
rlm@79 3545 (function(){
rlm@79 3546 var div = document.createElement("div");
rlm@79 3547
rlm@79 3548 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
rlm@79 3549
rlm@79 3550 // Opera can't find a second classname (in 9.6)
rlm@79 3551 // Also, make sure that getElementsByClassName actually exists
rlm@79 3552 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
rlm@79 3553 return;
rlm@79 3554 }
rlm@79 3555
rlm@79 3556 // Safari caches class attributes, doesn't catch changes (in 3.2)
rlm@79 3557 div.lastChild.className = "e";
rlm@79 3558
rlm@79 3559 if ( div.getElementsByClassName("e").length === 1 ) {
rlm@79 3560 return;
rlm@79 3561 }
rlm@79 3562
rlm@79 3563 Expr.order.splice(1, 0, "CLASS");
rlm@79 3564 Expr.find.CLASS = function(match, context, isXML) {
rlm@79 3565 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
rlm@79 3566 return context.getElementsByClassName(match[1]);
rlm@79 3567 }
rlm@79 3568 };
rlm@79 3569
rlm@79 3570 div = null; // release memory in IE
rlm@79 3571 })();
rlm@79 3572
rlm@79 3573 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
rlm@79 3574 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
rlm@79 3575 var elem = checkSet[i];
rlm@79 3576 if ( elem ) {
rlm@79 3577 elem = elem[dir];
rlm@79 3578 var match = false;
rlm@79 3579
rlm@79 3580 while ( elem ) {
rlm@79 3581 if ( elem.sizcache === doneName ) {
rlm@79 3582 match = checkSet[elem.sizset];
rlm@79 3583 break;
rlm@79 3584 }
rlm@79 3585
rlm@79 3586 if ( elem.nodeType === 1 && !isXML ){
rlm@79 3587 elem.sizcache = doneName;
rlm@79 3588 elem.sizset = i;
rlm@79 3589 }
rlm@79 3590
rlm@79 3591 if ( elem.nodeName.toLowerCase() === cur ) {
rlm@79 3592 match = elem;
rlm@79 3593 break;
rlm@79 3594 }
rlm@79 3595
rlm@79 3596 elem = elem[dir];
rlm@79 3597 }
rlm@79 3598
rlm@79 3599 checkSet[i] = match;
rlm@79 3600 }
rlm@79 3601 }
rlm@79 3602 }
rlm@79 3603
rlm@79 3604 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
rlm@79 3605 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
rlm@79 3606 var elem = checkSet[i];
rlm@79 3607 if ( elem ) {
rlm@79 3608 elem = elem[dir];
rlm@79 3609 var match = false;
rlm@79 3610
rlm@79 3611 while ( elem ) {
rlm@79 3612 if ( elem.sizcache === doneName ) {
rlm@79 3613 match = checkSet[elem.sizset];
rlm@79 3614 break;
rlm@79 3615 }
rlm@79 3616
rlm@79 3617 if ( elem.nodeType === 1 ) {
rlm@79 3618 if ( !isXML ) {
rlm@79 3619 elem.sizcache = doneName;
rlm@79 3620 elem.sizset = i;
rlm@79 3621 }
rlm@79 3622 if ( typeof cur !== "string" ) {
rlm@79 3623 if ( elem === cur ) {
rlm@79 3624 match = true;
rlm@79 3625 break;
rlm@79 3626 }
rlm@79 3627
rlm@79 3628 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
rlm@79 3629 match = elem;
rlm@79 3630 break;
rlm@79 3631 }
rlm@79 3632 }
rlm@79 3633
rlm@79 3634 elem = elem[dir];
rlm@79 3635 }
rlm@79 3636
rlm@79 3637 checkSet[i] = match;
rlm@79 3638 }
rlm@79 3639 }
rlm@79 3640 }
rlm@79 3641
rlm@79 3642 var contains = document.compareDocumentPosition ? function(a, b){
rlm@79 3643 return !!(a.compareDocumentPosition(b) & 16);
rlm@79 3644 } : function(a, b){
rlm@79 3645 return a !== b && (a.contains ? a.contains(b) : true);
rlm@79 3646 };
rlm@79 3647
rlm@79 3648 var isXML = function(elem){
rlm@79 3649 // documentElement is verified for cases where it doesn't yet exist
rlm@79 3650 // (such as loading iframes in IE - #4833)
rlm@79 3651 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
rlm@79 3652 return documentElement ? documentElement.nodeName !== "HTML" : false;
rlm@79 3653 };
rlm@79 3654
rlm@79 3655 var posProcess = function(selector, context){
rlm@79 3656 var tmpSet = [], later = "", match,
rlm@79 3657 root = context.nodeType ? [context] : context;
rlm@79 3658
rlm@79 3659 // Position selectors must be done after the filter
rlm@79 3660 // And so must :not(positional) so we move all PSEUDOs to the end
rlm@79 3661 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
rlm@79 3662 later += match[0];
rlm@79 3663 selector = selector.replace( Expr.match.PSEUDO, "" );
rlm@79 3664 }
rlm@79 3665
rlm@79 3666 selector = Expr.relative[selector] ? selector + "*" : selector;
rlm@79 3667
rlm@79 3668 for ( var i = 0, l = root.length; i < l; i++ ) {
rlm@79 3669 Sizzle( selector, root[i], tmpSet );
rlm@79 3670 }
rlm@79 3671
rlm@79 3672 return Sizzle.filter( later, tmpSet );
rlm@79 3673 };
rlm@79 3674
rlm@79 3675 // EXPOSE
rlm@79 3676 jQuery.find = Sizzle;
rlm@79 3677 jQuery.expr = Sizzle.selectors;
rlm@79 3678 jQuery.expr[":"] = jQuery.expr.filters;
rlm@79 3679 jQuery.unique = Sizzle.uniqueSort;
rlm@79 3680 jQuery.text = getText;
rlm@79 3681 jQuery.isXMLDoc = isXML;
rlm@79 3682 jQuery.contains = contains;
rlm@79 3683
rlm@79 3684 return;
rlm@79 3685
rlm@79 3686 window.Sizzle = Sizzle;
rlm@79 3687
rlm@79 3688 })();
rlm@79 3689 var runtil = /Until$/,
rlm@79 3690 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
rlm@79 3691 // Note: This RegExp should be improved, or likely pulled from Sizzle
rlm@79 3692 rmultiselector = /,/,
rlm@79 3693 slice = Array.prototype.slice;
rlm@79 3694
rlm@79 3695 // Implement the identical functionality for filter and not
rlm@79 3696 var winnow = function( elements, qualifier, keep ) {
rlm@79 3697 if ( jQuery.isFunction( qualifier ) ) {
rlm@79 3698 return jQuery.grep(elements, function( elem, i ) {
rlm@79 3699 return !!qualifier.call( elem, i, elem ) === keep;
rlm@79 3700 });
rlm@79 3701
rlm@79 3702 } else if ( qualifier.nodeType ) {
rlm@79 3703 return jQuery.grep(elements, function( elem, i ) {
rlm@79 3704 return (elem === qualifier) === keep;
rlm@79 3705 });
rlm@79 3706
rlm@79 3707 } else if ( typeof qualifier === "string" ) {
rlm@79 3708 var filtered = jQuery.grep(elements, function( elem ) {
rlm@79 3709 return elem.nodeType === 1;
rlm@79 3710 });
rlm@79 3711
rlm@79 3712 if ( isSimple.test( qualifier ) ) {
rlm@79 3713 return jQuery.filter(qualifier, filtered, !keep);
rlm@79 3714 } else {
rlm@79 3715 qualifier = jQuery.filter( qualifier, filtered );
rlm@79 3716 }
rlm@79 3717 }
rlm@79 3718
rlm@79 3719 return jQuery.grep(elements, function( elem, i ) {
rlm@79 3720 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
rlm@79 3721 });
rlm@79 3722 };
rlm@79 3723
rlm@79 3724 jQuery.fn.extend({
rlm@79 3725 find: function( selector ) {
rlm@79 3726 var ret = this.pushStack( "", "find", selector ), length = 0;
rlm@79 3727
rlm@79 3728 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 3729 length = ret.length;
rlm@79 3730 jQuery.find( selector, this[i], ret );
rlm@79 3731
rlm@79 3732 if ( i > 0 ) {
rlm@79 3733 // Make sure that the results are unique
rlm@79 3734 for ( var n = length; n < ret.length; n++ ) {
rlm@79 3735 for ( var r = 0; r < length; r++ ) {
rlm@79 3736 if ( ret[r] === ret[n] ) {
rlm@79 3737 ret.splice(n--, 1);
rlm@79 3738 break;
rlm@79 3739 }
rlm@79 3740 }
rlm@79 3741 }
rlm@79 3742 }
rlm@79 3743 }
rlm@79 3744
rlm@79 3745 return ret;
rlm@79 3746 },
rlm@79 3747
rlm@79 3748 has: function( target ) {
rlm@79 3749 var targets = jQuery( target );
rlm@79 3750 return this.filter(function() {
rlm@79 3751 for ( var i = 0, l = targets.length; i < l; i++ ) {
rlm@79 3752 if ( jQuery.contains( this, targets[i] ) ) {
rlm@79 3753 return true;
rlm@79 3754 }
rlm@79 3755 }
rlm@79 3756 });
rlm@79 3757 },
rlm@79 3758
rlm@79 3759 not: function( selector ) {
rlm@79 3760 return this.pushStack( winnow(this, selector, false), "not", selector);
rlm@79 3761 },
rlm@79 3762
rlm@79 3763 filter: function( selector ) {
rlm@79 3764 return this.pushStack( winnow(this, selector, true), "filter", selector );
rlm@79 3765 },
rlm@79 3766
rlm@79 3767 is: function( selector ) {
rlm@79 3768 return !!selector && jQuery.filter( selector, this ).length > 0;
rlm@79 3769 },
rlm@79 3770
rlm@79 3771 closest: function( selectors, context ) {
rlm@79 3772 if ( jQuery.isArray( selectors ) ) {
rlm@79 3773 var ret = [], cur = this[0], match, matches = {}, selector;
rlm@79 3774
rlm@79 3775 if ( cur && selectors.length ) {
rlm@79 3776 for ( var i = 0, l = selectors.length; i < l; i++ ) {
rlm@79 3777 selector = selectors[i];
rlm@79 3778
rlm@79 3779 if ( !matches[selector] ) {
rlm@79 3780 matches[selector] = jQuery.expr.match.POS.test( selector ) ?
rlm@79 3781 jQuery( selector, context || this.context ) :
rlm@79 3782 selector;
rlm@79 3783 }
rlm@79 3784 }
rlm@79 3785
rlm@79 3786 while ( cur && cur.ownerDocument && cur !== context ) {
rlm@79 3787 for ( selector in matches ) {
rlm@79 3788 match = matches[selector];
rlm@79 3789
rlm@79 3790 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
rlm@79 3791 ret.push({ selector: selector, elem: cur });
rlm@79 3792 delete matches[selector];
rlm@79 3793 }
rlm@79 3794 }
rlm@79 3795 cur = cur.parentNode;
rlm@79 3796 }
rlm@79 3797 }
rlm@79 3798
rlm@79 3799 return ret;
rlm@79 3800 }
rlm@79 3801
rlm@79 3802 var pos = jQuery.expr.match.POS.test( selectors ) ?
rlm@79 3803 jQuery( selectors, context || this.context ) : null;
rlm@79 3804
rlm@79 3805 return this.map(function( i, cur ) {
rlm@79 3806 while ( cur && cur.ownerDocument && cur !== context ) {
rlm@79 3807 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
rlm@79 3808 return cur;
rlm@79 3809 }
rlm@79 3810 cur = cur.parentNode;
rlm@79 3811 }
rlm@79 3812 return null;
rlm@79 3813 });
rlm@79 3814 },
rlm@79 3815
rlm@79 3816 // Determine the position of an element within
rlm@79 3817 // the matched set of elements
rlm@79 3818 index: function( elem ) {
rlm@79 3819 if ( !elem || typeof elem === "string" ) {
rlm@79 3820 return jQuery.inArray( this[0],
rlm@79 3821 // If it receives a string, the selector is used
rlm@79 3822 // If it receives nothing, the siblings are used
rlm@79 3823 elem ? jQuery( elem ) : this.parent().children() );
rlm@79 3824 }
rlm@79 3825 // Locate the position of the desired element
rlm@79 3826 return jQuery.inArray(
rlm@79 3827 // If it receives a jQuery object, the first element is used
rlm@79 3828 elem.jquery ? elem[0] : elem, this );
rlm@79 3829 },
rlm@79 3830
rlm@79 3831 add: function( selector, context ) {
rlm@79 3832 var set = typeof selector === "string" ?
rlm@79 3833 jQuery( selector, context || this.context ) :
rlm@79 3834 jQuery.makeArray( selector ),
rlm@79 3835 all = jQuery.merge( this.get(), set );
rlm@79 3836
rlm@79 3837 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
rlm@79 3838 all :
rlm@79 3839 jQuery.unique( all ) );
rlm@79 3840 },
rlm@79 3841
rlm@79 3842 andSelf: function() {
rlm@79 3843 return this.add( this.prevObject );
rlm@79 3844 }
rlm@79 3845 });
rlm@79 3846
rlm@79 3847 // A painfully simple check to see if an element is disconnected
rlm@79 3848 // from a document (should be improved, where feasible).
rlm@79 3849 function isDisconnected( node ) {
rlm@79 3850 return !node || !node.parentNode || node.parentNode.nodeType === 11;
rlm@79 3851 }
rlm@79 3852
rlm@79 3853 jQuery.each({
rlm@79 3854 parent: function( elem ) {
rlm@79 3855 var parent = elem.parentNode;
rlm@79 3856 return parent && parent.nodeType !== 11 ? parent : null;
rlm@79 3857 },
rlm@79 3858 parents: function( elem ) {
rlm@79 3859 return jQuery.dir( elem, "parentNode" );
rlm@79 3860 },
rlm@79 3861 parentsUntil: function( elem, i, until ) {
rlm@79 3862 return jQuery.dir( elem, "parentNode", until );
rlm@79 3863 },
rlm@79 3864 next: function( elem ) {
rlm@79 3865 return jQuery.nth( elem, 2, "nextSibling" );
rlm@79 3866 },
rlm@79 3867 prev: function( elem ) {
rlm@79 3868 return jQuery.nth( elem, 2, "previousSibling" );
rlm@79 3869 },
rlm@79 3870 nextAll: function( elem ) {
rlm@79 3871 return jQuery.dir( elem, "nextSibling" );
rlm@79 3872 },
rlm@79 3873 prevAll: function( elem ) {
rlm@79 3874 return jQuery.dir( elem, "previousSibling" );
rlm@79 3875 },
rlm@79 3876 nextUntil: function( elem, i, until ) {
rlm@79 3877 return jQuery.dir( elem, "nextSibling", until );
rlm@79 3878 },
rlm@79 3879 prevUntil: function( elem, i, until ) {
rlm@79 3880 return jQuery.dir( elem, "previousSibling", until );
rlm@79 3881 },
rlm@79 3882 siblings: function( elem ) {
rlm@79 3883 return jQuery.sibling( elem.parentNode.firstChild, elem );
rlm@79 3884 },
rlm@79 3885 children: function( elem ) {
rlm@79 3886 return jQuery.sibling( elem.firstChild );
rlm@79 3887 },
rlm@79 3888 contents: function( elem ) {
rlm@79 3889 return jQuery.nodeName( elem, "iframe" ) ?
rlm@79 3890 elem.contentDocument || elem.contentWindow.document :
rlm@79 3891 jQuery.makeArray( elem.childNodes );
rlm@79 3892 }
rlm@79 3893 }, function( name, fn ) {
rlm@79 3894 jQuery.fn[ name ] = function( until, selector ) {
rlm@79 3895 var ret = jQuery.map( this, fn, until );
rlm@79 3896
rlm@79 3897 if ( !runtil.test( name ) ) {
rlm@79 3898 selector = until;
rlm@79 3899 }
rlm@79 3900
rlm@79 3901 if ( selector && typeof selector === "string" ) {
rlm@79 3902 ret = jQuery.filter( selector, ret );
rlm@79 3903 }
rlm@79 3904
rlm@79 3905 ret = this.length > 1 ? jQuery.unique( ret ) : ret;
rlm@79 3906
rlm@79 3907 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
rlm@79 3908 ret = ret.reverse();
rlm@79 3909 }
rlm@79 3910
rlm@79 3911 return this.pushStack( ret, name, slice.call(arguments).join(",") );
rlm@79 3912 };
rlm@79 3913 });
rlm@79 3914
rlm@79 3915 jQuery.extend({
rlm@79 3916 filter: function( expr, elems, not ) {
rlm@79 3917 if ( not ) {
rlm@79 3918 expr = ":not(" + expr + ")";
rlm@79 3919 }
rlm@79 3920
rlm@79 3921 return jQuery.find.matches(expr, elems);
rlm@79 3922 },
rlm@79 3923
rlm@79 3924 dir: function( elem, dir, until ) {
rlm@79 3925 var matched = [], cur = elem[dir];
rlm@79 3926 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
rlm@79 3927 if ( cur.nodeType === 1 ) {
rlm@79 3928 matched.push( cur );
rlm@79 3929 }
rlm@79 3930 cur = cur[dir];
rlm@79 3931 }
rlm@79 3932 return matched;
rlm@79 3933 },
rlm@79 3934
rlm@79 3935 nth: function( cur, result, dir, elem ) {
rlm@79 3936 result = result || 1;
rlm@79 3937 var num = 0;
rlm@79 3938
rlm@79 3939 for ( ; cur; cur = cur[dir] ) {
rlm@79 3940 if ( cur.nodeType === 1 && ++num === result ) {
rlm@79 3941 break;
rlm@79 3942 }
rlm@79 3943 }
rlm@79 3944
rlm@79 3945 return cur;
rlm@79 3946 },
rlm@79 3947
rlm@79 3948 sibling: function( n, elem ) {
rlm@79 3949 var r = [];
rlm@79 3950
rlm@79 3951 for ( ; n; n = n.nextSibling ) {
rlm@79 3952 if ( n.nodeType === 1 && n !== elem ) {
rlm@79 3953 r.push( n );
rlm@79 3954 }
rlm@79 3955 }
rlm@79 3956
rlm@79 3957 return r;
rlm@79 3958 }
rlm@79 3959 });
rlm@79 3960 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
rlm@79 3961 rleadingWhitespace = /^\s+/,
rlm@79 3962 rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
rlm@79 3963 rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
rlm@79 3964 rtagName = /<([\w:]+)/,
rlm@79 3965 rtbody = /<tbody/i,
rlm@79 3966 rhtml = /<|&#?\w+;/,
rlm@79 3967 rnocache = /<script|<object|<embed|<option|<style/i,
rlm@79 3968 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
rlm@79 3969 fcloseTag = function( all, front, tag ) {
rlm@79 3970 return rselfClosing.test( tag ) ?
rlm@79 3971 all :
rlm@79 3972 front + "></" + tag + ">";
rlm@79 3973 },
rlm@79 3974 wrapMap = {
rlm@79 3975 option: [ 1, "<select multiple='multiple'>", "</select>" ],
rlm@79 3976 legend: [ 1, "<fieldset>", "</fieldset>" ],
rlm@79 3977 thead: [ 1, "<table>", "</table>" ],
rlm@79 3978 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
rlm@79 3979 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
rlm@79 3980 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
rlm@79 3981 area: [ 1, "<map>", "</map>" ],
rlm@79 3982 _default: [ 0, "", "" ]
rlm@79 3983 };
rlm@79 3984
rlm@79 3985 wrapMap.optgroup = wrapMap.option;
rlm@79 3986 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
rlm@79 3987 wrapMap.th = wrapMap.td;
rlm@79 3988
rlm@79 3989 // IE can't serialize <link> and <script> tags normally
rlm@79 3990 if ( !jQuery.support.htmlSerialize ) {
rlm@79 3991 wrapMap._default = [ 1, "div<div>", "</div>" ];
rlm@79 3992 }
rlm@79 3993
rlm@79 3994 jQuery.fn.extend({
rlm@79 3995 text: function( text ) {
rlm@79 3996 if ( jQuery.isFunction(text) ) {
rlm@79 3997 return this.each(function(i) {
rlm@79 3998 var self = jQuery(this);
rlm@79 3999 self.text( text.call(this, i, self.text()) );
rlm@79 4000 });
rlm@79 4001 }
rlm@79 4002
rlm@79 4003 if ( typeof text !== "object" && text !== undefined ) {
rlm@79 4004 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
rlm@79 4005 }
rlm@79 4006
rlm@79 4007 return jQuery.text( this );
rlm@79 4008 },
rlm@79 4009
rlm@79 4010 wrapAll: function( html ) {
rlm@79 4011 if ( jQuery.isFunction( html ) ) {
rlm@79 4012 return this.each(function(i) {
rlm@79 4013 jQuery(this).wrapAll( html.call(this, i) );
rlm@79 4014 });
rlm@79 4015 }
rlm@79 4016
rlm@79 4017 if ( this[0] ) {
rlm@79 4018 // The elements to wrap the target around
rlm@79 4019 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
rlm@79 4020
rlm@79 4021 if ( this[0].parentNode ) {
rlm@79 4022 wrap.insertBefore( this[0] );
rlm@79 4023 }
rlm@79 4024
rlm@79 4025 wrap.map(function() {
rlm@79 4026 var elem = this;
rlm@79 4027
rlm@79 4028 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
rlm@79 4029 elem = elem.firstChild;
rlm@79 4030 }
rlm@79 4031
rlm@79 4032 return elem;
rlm@79 4033 }).append(this);
rlm@79 4034 }
rlm@79 4035
rlm@79 4036 return this;
rlm@79 4037 },
rlm@79 4038
rlm@79 4039 wrapInner: function( html ) {
rlm@79 4040 if ( jQuery.isFunction( html ) ) {
rlm@79 4041 return this.each(function(i) {
rlm@79 4042 jQuery(this).wrapInner( html.call(this, i) );
rlm@79 4043 });
rlm@79 4044 }
rlm@79 4045
rlm@79 4046 return this.each(function() {
rlm@79 4047 var self = jQuery( this ), contents = self.contents();
rlm@79 4048
rlm@79 4049 if ( contents.length ) {
rlm@79 4050 contents.wrapAll( html );
rlm@79 4051
rlm@79 4052 } else {
rlm@79 4053 self.append( html );
rlm@79 4054 }
rlm@79 4055 });
rlm@79 4056 },
rlm@79 4057
rlm@79 4058 wrap: function( html ) {
rlm@79 4059 return this.each(function() {
rlm@79 4060 jQuery( this ).wrapAll( html );
rlm@79 4061 });
rlm@79 4062 },
rlm@79 4063
rlm@79 4064 unwrap: function() {
rlm@79 4065 return this.parent().each(function() {
rlm@79 4066 if ( !jQuery.nodeName( this, "body" ) ) {
rlm@79 4067 jQuery( this ).replaceWith( this.childNodes );
rlm@79 4068 }
rlm@79 4069 }).end();
rlm@79 4070 },
rlm@79 4071
rlm@79 4072 append: function() {
rlm@79 4073 return this.domManip(arguments, true, function( elem ) {
rlm@79 4074 if ( this.nodeType === 1 ) {
rlm@79 4075 this.appendChild( elem );
rlm@79 4076 }
rlm@79 4077 });
rlm@79 4078 },
rlm@79 4079
rlm@79 4080 prepend: function() {
rlm@79 4081 return this.domManip(arguments, true, function( elem ) {
rlm@79 4082 if ( this.nodeType === 1 ) {
rlm@79 4083 this.insertBefore( elem, this.firstChild );
rlm@79 4084 }
rlm@79 4085 });
rlm@79 4086 },
rlm@79 4087
rlm@79 4088 before: function() {
rlm@79 4089 if ( this[0] && this[0].parentNode ) {
rlm@79 4090 return this.domManip(arguments, false, function( elem ) {
rlm@79 4091 this.parentNode.insertBefore( elem, this );
rlm@79 4092 });
rlm@79 4093 } else if ( arguments.length ) {
rlm@79 4094 var set = jQuery(arguments[0]);
rlm@79 4095 set.push.apply( set, this.toArray() );
rlm@79 4096 return this.pushStack( set, "before", arguments );
rlm@79 4097 }
rlm@79 4098 },
rlm@79 4099
rlm@79 4100 after: function() {
rlm@79 4101 if ( this[0] && this[0].parentNode ) {
rlm@79 4102 return this.domManip(arguments, false, function( elem ) {
rlm@79 4103 this.parentNode.insertBefore( elem, this.nextSibling );
rlm@79 4104 });
rlm@79 4105 } else if ( arguments.length ) {
rlm@79 4106 var set = this.pushStack( this, "after", arguments );
rlm@79 4107 set.push.apply( set, jQuery(arguments[0]).toArray() );
rlm@79 4108 return set;
rlm@79 4109 }
rlm@79 4110 },
rlm@79 4111
rlm@79 4112 // keepData is for internal use only--do not document
rlm@79 4113 remove: function( selector, keepData ) {
rlm@79 4114 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
rlm@79 4115 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
rlm@79 4116 if ( !keepData && elem.nodeType === 1 ) {
rlm@79 4117 jQuery.cleanData( elem.getElementsByTagName("*") );
rlm@79 4118 jQuery.cleanData( [ elem ] );
rlm@79 4119 }
rlm@79 4120
rlm@79 4121 if ( elem.parentNode ) {
rlm@79 4122 elem.parentNode.removeChild( elem );
rlm@79 4123 }
rlm@79 4124 }
rlm@79 4125 }
rlm@79 4126
rlm@79 4127 return this;
rlm@79 4128 },
rlm@79 4129
rlm@79 4130 empty: function() {
rlm@79 4131 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
rlm@79 4132 // Remove element nodes and prevent memory leaks
rlm@79 4133 if ( elem.nodeType === 1 ) {
rlm@79 4134 jQuery.cleanData( elem.getElementsByTagName("*") );
rlm@79 4135 }
rlm@79 4136
rlm@79 4137 // Remove any remaining nodes
rlm@79 4138 while ( elem.firstChild ) {
rlm@79 4139 elem.removeChild( elem.firstChild );
rlm@79 4140 }
rlm@79 4141 }
rlm@79 4142
rlm@79 4143 return this;
rlm@79 4144 },
rlm@79 4145
rlm@79 4146 clone: function( events ) {
rlm@79 4147 // Do the clone
rlm@79 4148 var ret = this.map(function() {
rlm@79 4149 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
rlm@79 4150 // IE copies events bound via attachEvent when
rlm@79 4151 // using cloneNode. Calling detachEvent on the
rlm@79 4152 // clone will also remove the events from the orignal
rlm@79 4153 // In order to get around this, we use innerHTML.
rlm@79 4154 // Unfortunately, this means some modifications to
rlm@79 4155 // attributes in IE that are actually only stored
rlm@79 4156 // as properties will not be copied (such as the
rlm@79 4157 // the name attribute on an input).
rlm@79 4158 var html = this.outerHTML, ownerDocument = this.ownerDocument;
rlm@79 4159 if ( !html ) {
rlm@79 4160 var div = ownerDocument.createElement("div");
rlm@79 4161 div.appendChild( this.cloneNode(true) );
rlm@79 4162 html = div.innerHTML;
rlm@79 4163 }
rlm@79 4164
rlm@79 4165 return jQuery.clean([html.replace(rinlinejQuery, "")
rlm@79 4166 // Handle the case in IE 8 where action=/test/> self-closes a tag
rlm@79 4167 .replace(/=([^="'>\s]+\/)>/g, '="$1">')
rlm@79 4168 .replace(rleadingWhitespace, "")], ownerDocument)[0];
rlm@79 4169 } else {
rlm@79 4170 return this.cloneNode(true);
rlm@79 4171 }
rlm@79 4172 });
rlm@79 4173
rlm@79 4174 // Copy the events from the original to the clone
rlm@79 4175 if ( events === true ) {
rlm@79 4176 cloneCopyEvent( this, ret );
rlm@79 4177 cloneCopyEvent( this.find("*"), ret.find("*") );
rlm@79 4178 }
rlm@79 4179
rlm@79 4180 // Return the cloned set
rlm@79 4181 return ret;
rlm@79 4182 },
rlm@79 4183
rlm@79 4184 html: function( value ) {
rlm@79 4185 if ( value === undefined ) {
rlm@79 4186 return this[0] && this[0].nodeType === 1 ?
rlm@79 4187 this[0].innerHTML.replace(rinlinejQuery, "") :
rlm@79 4188 null;
rlm@79 4189
rlm@79 4190 // See if we can take a shortcut and just use innerHTML
rlm@79 4191 } else if ( typeof value === "string" && !rnocache.test( value ) &&
rlm@79 4192 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
rlm@79 4193 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
rlm@79 4194
rlm@79 4195 value = value.replace(rxhtmlTag, fcloseTag);
rlm@79 4196
rlm@79 4197 try {
rlm@79 4198 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 4199 // Remove element nodes and prevent memory leaks
rlm@79 4200 if ( this[i].nodeType === 1 ) {
rlm@79 4201 jQuery.cleanData( this[i].getElementsByTagName("*") );
rlm@79 4202 this[i].innerHTML = value;
rlm@79 4203 }
rlm@79 4204 }
rlm@79 4205
rlm@79 4206 // If using innerHTML throws an exception, use the fallback method
rlm@79 4207 } catch(e) {
rlm@79 4208 this.empty().append( value );
rlm@79 4209 }
rlm@79 4210
rlm@79 4211 } else if ( jQuery.isFunction( value ) ) {
rlm@79 4212 this.each(function(i){
rlm@79 4213 var self = jQuery(this), old = self.html();
rlm@79 4214 self.empty().append(function(){
rlm@79 4215 return value.call( this, i, old );
rlm@79 4216 });
rlm@79 4217 });
rlm@79 4218
rlm@79 4219 } else {
rlm@79 4220 this.empty().append( value );
rlm@79 4221 }
rlm@79 4222
rlm@79 4223 return this;
rlm@79 4224 },
rlm@79 4225
rlm@79 4226 replaceWith: function( value ) {
rlm@79 4227 if ( this[0] && this[0].parentNode ) {
rlm@79 4228 // Make sure that the elements are removed from the DOM before they are inserted
rlm@79 4229 // this can help fix replacing a parent with child elements
rlm@79 4230 if ( jQuery.isFunction( value ) ) {
rlm@79 4231 return this.each(function(i) {
rlm@79 4232 var self = jQuery(this), old = self.html();
rlm@79 4233 self.replaceWith( value.call( this, i, old ) );
rlm@79 4234 });
rlm@79 4235 }
rlm@79 4236
rlm@79 4237 if ( typeof value !== "string" ) {
rlm@79 4238 value = jQuery(value).detach();
rlm@79 4239 }
rlm@79 4240
rlm@79 4241 return this.each(function() {
rlm@79 4242 var next = this.nextSibling, parent = this.parentNode;
rlm@79 4243
rlm@79 4244 jQuery(this).remove();
rlm@79 4245
rlm@79 4246 if ( next ) {
rlm@79 4247 jQuery(next).before( value );
rlm@79 4248 } else {
rlm@79 4249 jQuery(parent).append( value );
rlm@79 4250 }
rlm@79 4251 });
rlm@79 4252 } else {
rlm@79 4253 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
rlm@79 4254 }
rlm@79 4255 },
rlm@79 4256
rlm@79 4257 detach: function( selector ) {
rlm@79 4258 return this.remove( selector, true );
rlm@79 4259 },
rlm@79 4260
rlm@79 4261 domManip: function( args, table, callback ) {
rlm@79 4262 var results, first, value = args[0], scripts = [], fragment, parent;
rlm@79 4263
rlm@79 4264 // We can't cloneNode fragments that contain checked, in WebKit
rlm@79 4265 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
rlm@79 4266 return this.each(function() {
rlm@79 4267 jQuery(this).domManip( args, table, callback, true );
rlm@79 4268 });
rlm@79 4269 }
rlm@79 4270
rlm@79 4271 if ( jQuery.isFunction(value) ) {
rlm@79 4272 return this.each(function(i) {
rlm@79 4273 var self = jQuery(this);
rlm@79 4274 args[0] = value.call(this, i, table ? self.html() : undefined);
rlm@79 4275 self.domManip( args, table, callback );
rlm@79 4276 });
rlm@79 4277 }
rlm@79 4278
rlm@79 4279 if ( this[0] ) {
rlm@79 4280 parent = value && value.parentNode;
rlm@79 4281
rlm@79 4282 // If we're in a fragment, just use that instead of building a new one
rlm@79 4283 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
rlm@79 4284 results = { fragment: parent };
rlm@79 4285
rlm@79 4286 } else {
rlm@79 4287 results = buildFragment( args, this, scripts );
rlm@79 4288 }
rlm@79 4289
rlm@79 4290 fragment = results.fragment;
rlm@79 4291
rlm@79 4292 if ( fragment.childNodes.length === 1 ) {
rlm@79 4293 first = fragment = fragment.firstChild;
rlm@79 4294 } else {
rlm@79 4295 first = fragment.firstChild;
rlm@79 4296 }
rlm@79 4297
rlm@79 4298 if ( first ) {
rlm@79 4299 table = table && jQuery.nodeName( first, "tr" );
rlm@79 4300
rlm@79 4301 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 4302 callback.call(
rlm@79 4303 table ?
rlm@79 4304 root(this[i], first) :
rlm@79 4305 this[i],
rlm@79 4306 i > 0 || results.cacheable || this.length > 1 ?
rlm@79 4307 fragment.cloneNode(true) :
rlm@79 4308 fragment
rlm@79 4309 );
rlm@79 4310 }
rlm@79 4311 }
rlm@79 4312
rlm@79 4313 if ( scripts.length ) {
rlm@79 4314 jQuery.each( scripts, evalScript );
rlm@79 4315 }
rlm@79 4316 }
rlm@79 4317
rlm@79 4318 return this;
rlm@79 4319
rlm@79 4320 function root( elem, cur ) {
rlm@79 4321 return jQuery.nodeName(elem, "table") ?
rlm@79 4322 (elem.getElementsByTagName("tbody")[0] ||
rlm@79 4323 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
rlm@79 4324 elem;
rlm@79 4325 }
rlm@79 4326 }
rlm@79 4327 });
rlm@79 4328
rlm@79 4329 function cloneCopyEvent(orig, ret) {
rlm@79 4330 var i = 0;
rlm@79 4331
rlm@79 4332 ret.each(function() {
rlm@79 4333 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
rlm@79 4334 return;
rlm@79 4335 }
rlm@79 4336
rlm@79 4337 var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
rlm@79 4338
rlm@79 4339 if ( events ) {
rlm@79 4340 delete curData.handle;
rlm@79 4341 curData.events = {};
rlm@79 4342
rlm@79 4343 for ( var type in events ) {
rlm@79 4344 for ( var handler in events[ type ] ) {
rlm@79 4345 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
rlm@79 4346 }
rlm@79 4347 }
rlm@79 4348 }
rlm@79 4349 });
rlm@79 4350 }
rlm@79 4351
rlm@79 4352 function buildFragment( args, nodes, scripts ) {
rlm@79 4353 var fragment, cacheable, cacheresults,
rlm@79 4354 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
rlm@79 4355
rlm@79 4356 // Only cache "small" (1/2 KB) strings that are associated with the main document
rlm@79 4357 // Cloning options loses the selected state, so don't cache them
rlm@79 4358 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
rlm@79 4359 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
rlm@79 4360 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
rlm@79 4361 !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
rlm@79 4362
rlm@79 4363 cacheable = true;
rlm@79 4364 cacheresults = jQuery.fragments[ args[0] ];
rlm@79 4365 if ( cacheresults ) {
rlm@79 4366 if ( cacheresults !== 1 ) {
rlm@79 4367 fragment = cacheresults;
rlm@79 4368 }
rlm@79 4369 }
rlm@79 4370 }
rlm@79 4371
rlm@79 4372 if ( !fragment ) {
rlm@79 4373 fragment = doc.createDocumentFragment();
rlm@79 4374 jQuery.clean( args, doc, fragment, scripts );
rlm@79 4375 }
rlm@79 4376
rlm@79 4377 if ( cacheable ) {
rlm@79 4378 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
rlm@79 4379 }
rlm@79 4380
rlm@79 4381 return { fragment: fragment, cacheable: cacheable };
rlm@79 4382 }
rlm@79 4383
rlm@79 4384 jQuery.fragments = {};
rlm@79 4385
rlm@79 4386 jQuery.each({
rlm@79 4387 appendTo: "append",
rlm@79 4388 prependTo: "prepend",
rlm@79 4389 insertBefore: "before",
rlm@79 4390 insertAfter: "after",
rlm@79 4391 replaceAll: "replaceWith"
rlm@79 4392 }, function( name, original ) {
rlm@79 4393 jQuery.fn[ name ] = function( selector ) {
rlm@79 4394 var ret = [], insert = jQuery( selector ),
rlm@79 4395 parent = this.length === 1 && this[0].parentNode;
rlm@79 4396
rlm@79 4397 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
rlm@79 4398 insert[ original ]( this[0] );
rlm@79 4399 return this;
rlm@79 4400
rlm@79 4401 } else {
rlm@79 4402 for ( var i = 0, l = insert.length; i < l; i++ ) {
rlm@79 4403 var elems = (i > 0 ? this.clone(true) : this).get();
rlm@79 4404 jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
rlm@79 4405 ret = ret.concat( elems );
rlm@79 4406 }
rlm@79 4407
rlm@79 4408 return this.pushStack( ret, name, insert.selector );
rlm@79 4409 }
rlm@79 4410 };
rlm@79 4411 });
rlm@79 4412
rlm@79 4413 jQuery.extend({
rlm@79 4414 clean: function( elems, context, fragment, scripts ) {
rlm@79 4415 context = context || document;
rlm@79 4416
rlm@79 4417 // !context.createElement fails in IE with an error but returns typeof 'object'
rlm@79 4418 if ( typeof context.createElement === "undefined" ) {
rlm@79 4419 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
rlm@79 4420 }
rlm@79 4421
rlm@79 4422 var ret = [];
rlm@79 4423
rlm@79 4424 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
rlm@79 4425 if ( typeof elem === "number" ) {
rlm@79 4426 elem += "";
rlm@79 4427 }
rlm@79 4428
rlm@79 4429 if ( !elem ) {
rlm@79 4430 continue;
rlm@79 4431 }
rlm@79 4432
rlm@79 4433 // Convert html string into DOM nodes
rlm@79 4434 if ( typeof elem === "string" && !rhtml.test( elem ) ) {
rlm@79 4435 elem = context.createTextNode( elem );
rlm@79 4436
rlm@79 4437 } else if ( typeof elem === "string" ) {
rlm@79 4438 // Fix "XHTML"-style tags in all browsers
rlm@79 4439 elem = elem.replace(rxhtmlTag, fcloseTag);
rlm@79 4440
rlm@79 4441 // Trim whitespace, otherwise indexOf won't work as expected
rlm@79 4442 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
rlm@79 4443 wrap = wrapMap[ tag ] || wrapMap._default,
rlm@79 4444 depth = wrap[0],
rlm@79 4445 div = context.createElement("div");
rlm@79 4446
rlm@79 4447 // Go to html and back, then peel off extra wrappers
rlm@79 4448 div.innerHTML = wrap[1] + elem + wrap[2];
rlm@79 4449
rlm@79 4450 // Move to the right depth
rlm@79 4451 while ( depth-- ) {
rlm@79 4452 div = div.lastChild;
rlm@79 4453 }
rlm@79 4454
rlm@79 4455 // Remove IE's autoinserted <tbody> from table fragments
rlm@79 4456 if ( !jQuery.support.tbody ) {
rlm@79 4457
rlm@79 4458 // String was a <table>, *may* have spurious <tbody>
rlm@79 4459 var hasBody = rtbody.test(elem),
rlm@79 4460 tbody = tag === "table" && !hasBody ?
rlm@79 4461 div.firstChild && div.firstChild.childNodes :
rlm@79 4462
rlm@79 4463 // String was a bare <thead> or <tfoot>
rlm@79 4464 wrap[1] === "<table>" && !hasBody ?
rlm@79 4465 div.childNodes :
rlm@79 4466 [];
rlm@79 4467
rlm@79 4468 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
rlm@79 4469 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
rlm@79 4470 tbody[ j ].parentNode.removeChild( tbody[ j ] );
rlm@79 4471 }
rlm@79 4472 }
rlm@79 4473
rlm@79 4474 }
rlm@79 4475
rlm@79 4476 // IE completely kills leading whitespace when innerHTML is used
rlm@79 4477 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
rlm@79 4478 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
rlm@79 4479 }
rlm@79 4480
rlm@79 4481 elem = div.childNodes;
rlm@79 4482 }
rlm@79 4483
rlm@79 4484 if ( elem.nodeType ) {
rlm@79 4485 ret.push( elem );
rlm@79 4486 } else {
rlm@79 4487 ret = jQuery.merge( ret, elem );
rlm@79 4488 }
rlm@79 4489 }
rlm@79 4490
rlm@79 4491 if ( fragment ) {
rlm@79 4492 for ( var i = 0; ret[i]; i++ ) {
rlm@79 4493 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
rlm@79 4494 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
rlm@79 4495
rlm@79 4496 } else {
rlm@79 4497 if ( ret[i].nodeType === 1 ) {
rlm@79 4498 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
rlm@79 4499 }
rlm@79 4500 fragment.appendChild( ret[i] );
rlm@79 4501 }
rlm@79 4502 }
rlm@79 4503 }
rlm@79 4504
rlm@79 4505 return ret;
rlm@79 4506 },
rlm@79 4507
rlm@79 4508 cleanData: function( elems ) {
rlm@79 4509 var data, id, cache = jQuery.cache,
rlm@79 4510 special = jQuery.event.special,
rlm@79 4511 deleteExpando = jQuery.support.deleteExpando;
rlm@79 4512
rlm@79 4513 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
rlm@79 4514 id = elem[ jQuery.expando ];
rlm@79 4515
rlm@79 4516 if ( id ) {
rlm@79 4517 data = cache[ id ];
rlm@79 4518
rlm@79 4519 if ( data.events ) {
rlm@79 4520 for ( var type in data.events ) {
rlm@79 4521 if ( special[ type ] ) {
rlm@79 4522 jQuery.event.remove( elem, type );
rlm@79 4523
rlm@79 4524 } else {
rlm@79 4525 removeEvent( elem, type, data.handle );
rlm@79 4526 }
rlm@79 4527 }
rlm@79 4528 }
rlm@79 4529
rlm@79 4530 if ( deleteExpando ) {
rlm@79 4531 delete elem[ jQuery.expando ];
rlm@79 4532
rlm@79 4533 } else if ( elem.removeAttribute ) {
rlm@79 4534 elem.removeAttribute( jQuery.expando );
rlm@79 4535 }
rlm@79 4536
rlm@79 4537 delete cache[ id ];
rlm@79 4538 }
rlm@79 4539 }
rlm@79 4540 }
rlm@79 4541 });
rlm@79 4542 // exclude the following css properties to add px
rlm@79 4543 var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
rlm@79 4544 ralpha = /alpha\([^)]*\)/,
rlm@79 4545 ropacity = /opacity=([^)]*)/,
rlm@79 4546 rfloat = /float/i,
rlm@79 4547 rdashAlpha = /-([a-z])/ig,
rlm@79 4548 rupper = /([A-Z])/g,
rlm@79 4549 rnumpx = /^-?\d+(?:px)?$/i,
rlm@79 4550 rnum = /^-?\d/,
rlm@79 4551
rlm@79 4552 cssShow = { position: "absolute", visibility: "hidden", display:"block" },
rlm@79 4553 cssWidth = [ "Left", "Right" ],
rlm@79 4554 cssHeight = [ "Top", "Bottom" ],
rlm@79 4555
rlm@79 4556 // cache check for defaultView.getComputedStyle
rlm@79 4557 getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
rlm@79 4558 // normalize float css property
rlm@79 4559 styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
rlm@79 4560 fcamelCase = function( all, letter ) {
rlm@79 4561 return letter.toUpperCase();
rlm@79 4562 };
rlm@79 4563
rlm@79 4564 jQuery.fn.css = function( name, value ) {
rlm@79 4565 return access( this, name, value, true, function( elem, name, value ) {
rlm@79 4566 if ( value === undefined ) {
rlm@79 4567 return jQuery.curCSS( elem, name );
rlm@79 4568 }
rlm@79 4569
rlm@79 4570 if ( typeof value === "number" && !rexclude.test(name) ) {
rlm@79 4571 value += "px";
rlm@79 4572 }
rlm@79 4573
rlm@79 4574 jQuery.style( elem, name, value );
rlm@79 4575 });
rlm@79 4576 };
rlm@79 4577
rlm@79 4578 jQuery.extend({
rlm@79 4579 style: function( elem, name, value ) {
rlm@79 4580 // don't set styles on text and comment nodes
rlm@79 4581 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
rlm@79 4582 return undefined;
rlm@79 4583 }
rlm@79 4584
rlm@79 4585 // ignore negative width and height values #1599
rlm@79 4586 if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
rlm@79 4587 value = undefined;
rlm@79 4588 }
rlm@79 4589
rlm@79 4590 var style = elem.style || elem, set = value !== undefined;
rlm@79 4591
rlm@79 4592 // IE uses filters for opacity
rlm@79 4593 if ( !jQuery.support.opacity && name === "opacity" ) {
rlm@79 4594 if ( set ) {
rlm@79 4595 // IE has trouble with opacity if it does not have layout
rlm@79 4596 // Force it by setting the zoom level
rlm@79 4597 style.zoom = 1;
rlm@79 4598
rlm@79 4599 // Set the alpha filter to set the opacity
rlm@79 4600 var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
rlm@79 4601 var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
rlm@79 4602 style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
rlm@79 4603 }
rlm@79 4604
rlm@79 4605 return style.filter && style.filter.indexOf("opacity=") >= 0 ?
rlm@79 4606 (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
rlm@79 4607 "";
rlm@79 4608 }
rlm@79 4609
rlm@79 4610 // Make sure we're using the right name for getting the float value
rlm@79 4611 if ( rfloat.test( name ) ) {
rlm@79 4612 name = styleFloat;
rlm@79 4613 }
rlm@79 4614
rlm@79 4615 name = name.replace(rdashAlpha, fcamelCase);
rlm@79 4616
rlm@79 4617 if ( set ) {
rlm@79 4618 style[ name ] = value;
rlm@79 4619 }
rlm@79 4620
rlm@79 4621 return style[ name ];
rlm@79 4622 },
rlm@79 4623
rlm@79 4624 css: function( elem, name, force, extra ) {
rlm@79 4625 if ( name === "width" || name === "height" ) {
rlm@79 4626 var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
rlm@79 4627
rlm@79 4628 function getWH() {
rlm@79 4629 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
rlm@79 4630
rlm@79 4631 if ( extra === "border" ) {
rlm@79 4632 return;
rlm@79 4633 }
rlm@79 4634
rlm@79 4635 jQuery.each( which, function() {
rlm@79 4636 if ( !extra ) {
rlm@79 4637 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
rlm@79 4638 }
rlm@79 4639
rlm@79 4640 if ( extra === "margin" ) {
rlm@79 4641 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
rlm@79 4642 } else {
rlm@79 4643 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
rlm@79 4644 }
rlm@79 4645 });
rlm@79 4646 }
rlm@79 4647
rlm@79 4648 if ( elem.offsetWidth !== 0 ) {
rlm@79 4649 getWH();
rlm@79 4650 } else {
rlm@79 4651 jQuery.swap( elem, props, getWH );
rlm@79 4652 }
rlm@79 4653
rlm@79 4654 return Math.max(0, Math.round(val));
rlm@79 4655 }
rlm@79 4656
rlm@79 4657 return jQuery.curCSS( elem, name, force );
rlm@79 4658 },
rlm@79 4659
rlm@79 4660 curCSS: function( elem, name, force ) {
rlm@79 4661 var ret, style = elem.style, filter;
rlm@79 4662
rlm@79 4663 // IE uses filters for opacity
rlm@79 4664 if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
rlm@79 4665 ret = ropacity.test(elem.currentStyle.filter || "") ?
rlm@79 4666 (parseFloat(RegExp.$1) / 100) + "" :
rlm@79 4667 "";
rlm@79 4668
rlm@79 4669 return ret === "" ?
rlm@79 4670 "1" :
rlm@79 4671 ret;
rlm@79 4672 }
rlm@79 4673
rlm@79 4674 // Make sure we're using the right name for getting the float value
rlm@79 4675 if ( rfloat.test( name ) ) {
rlm@79 4676 name = styleFloat;
rlm@79 4677 }
rlm@79 4678
rlm@79 4679 if ( !force && style && style[ name ] ) {
rlm@79 4680 ret = style[ name ];
rlm@79 4681
rlm@79 4682 } else if ( getComputedStyle ) {
rlm@79 4683
rlm@79 4684 // Only "float" is needed here
rlm@79 4685 if ( rfloat.test( name ) ) {
rlm@79 4686 name = "float";
rlm@79 4687 }
rlm@79 4688
rlm@79 4689 name = name.replace( rupper, "-$1" ).toLowerCase();
rlm@79 4690
rlm@79 4691 var defaultView = elem.ownerDocument.defaultView;
rlm@79 4692
rlm@79 4693 if ( !defaultView ) {
rlm@79 4694 return null;
rlm@79 4695 }
rlm@79 4696
rlm@79 4697 var computedStyle = defaultView.getComputedStyle( elem, null );
rlm@79 4698
rlm@79 4699 if ( computedStyle ) {
rlm@79 4700 ret = computedStyle.getPropertyValue( name );
rlm@79 4701 }
rlm@79 4702
rlm@79 4703 // We should always get a number back from opacity
rlm@79 4704 if ( name === "opacity" && ret === "" ) {
rlm@79 4705 ret = "1";
rlm@79 4706 }
rlm@79 4707
rlm@79 4708 } else if ( elem.currentStyle ) {
rlm@79 4709 var camelCase = name.replace(rdashAlpha, fcamelCase);
rlm@79 4710
rlm@79 4711 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
rlm@79 4712
rlm@79 4713 // From the awesome hack by Dean Edwards
rlm@79 4714 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
rlm@79 4715
rlm@79 4716 // If we're not dealing with a regular pixel number
rlm@79 4717 // but a number that has a weird ending, we need to convert it to pixels
rlm@79 4718 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
rlm@79 4719 // Remember the original values
rlm@79 4720 var left = style.left, rsLeft = elem.runtimeStyle.left;
rlm@79 4721
rlm@79 4722 // Put in the new values to get a computed value out
rlm@79 4723 elem.runtimeStyle.left = elem.currentStyle.left;
rlm@79 4724 style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
rlm@79 4725 ret = style.pixelLeft + "px";
rlm@79 4726
rlm@79 4727 // Revert the changed values
rlm@79 4728 style.left = left;
rlm@79 4729 elem.runtimeStyle.left = rsLeft;
rlm@79 4730 }
rlm@79 4731 }
rlm@79 4732
rlm@79 4733 return ret;
rlm@79 4734 },
rlm@79 4735
rlm@79 4736 // A method for quickly swapping in/out CSS properties to get correct calculations
rlm@79 4737 swap: function( elem, options, callback ) {
rlm@79 4738 var old = {};
rlm@79 4739
rlm@79 4740 // Remember the old values, and insert the new ones
rlm@79 4741 for ( var name in options ) {
rlm@79 4742 old[ name ] = elem.style[ name ];
rlm@79 4743 elem.style[ name ] = options[ name ];
rlm@79 4744 }
rlm@79 4745
rlm@79 4746 callback.call( elem );
rlm@79 4747
rlm@79 4748 // Revert the old values
rlm@79 4749 for ( var name in options ) {
rlm@79 4750 elem.style[ name ] = old[ name ];
rlm@79 4751 }
rlm@79 4752 }
rlm@79 4753 });
rlm@79 4754
rlm@79 4755 if ( jQuery.expr && jQuery.expr.filters ) {
rlm@79 4756 jQuery.expr.filters.hidden = function( elem ) {
rlm@79 4757 var width = elem.offsetWidth, height = elem.offsetHeight,
rlm@79 4758 skip = elem.nodeName.toLowerCase() === "tr";
rlm@79 4759
rlm@79 4760 return width === 0 && height === 0 && !skip ?
rlm@79 4761 true :
rlm@79 4762 width > 0 && height > 0 && !skip ?
rlm@79 4763 false :
rlm@79 4764 jQuery.curCSS(elem, "display") === "none";
rlm@79 4765 };
rlm@79 4766
rlm@79 4767 jQuery.expr.filters.visible = function( elem ) {
rlm@79 4768 return !jQuery.expr.filters.hidden( elem );
rlm@79 4769 };
rlm@79 4770 }
rlm@79 4771 var jsc = now(),
rlm@79 4772 rscript = /<script(.|\s)*?\/script>/gi,
rlm@79 4773 rselectTextarea = /select|textarea/i,
rlm@79 4774 rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
rlm@79 4775 jsre = /=\?(&|$)/,
rlm@79 4776 rquery = /\?/,
rlm@79 4777 rts = /(\?|&)_=.*?(&|$)/,
rlm@79 4778 rurl = /^(\w+:)?\/\/([^\/?#]+)/,
rlm@79 4779 r20 = /%20/g,
rlm@79 4780
rlm@79 4781 // Keep a copy of the old load method
rlm@79 4782 _load = jQuery.fn.load;
rlm@79 4783
rlm@79 4784 jQuery.fn.extend({
rlm@79 4785 load: function( url, params, callback ) {
rlm@79 4786 if ( typeof url !== "string" ) {
rlm@79 4787 return _load.call( this, url );
rlm@79 4788
rlm@79 4789 // Don't do a request if no elements are being requested
rlm@79 4790 } else if ( !this.length ) {
rlm@79 4791 return this;
rlm@79 4792 }
rlm@79 4793
rlm@79 4794 var off = url.indexOf(" ");
rlm@79 4795 if ( off >= 0 ) {
rlm@79 4796 var selector = url.slice(off, url.length);
rlm@79 4797 url = url.slice(0, off);
rlm@79 4798 }
rlm@79 4799
rlm@79 4800 // Default to a GET request
rlm@79 4801 var type = "GET";
rlm@79 4802
rlm@79 4803 // If the second parameter was provided
rlm@79 4804 if ( params ) {
rlm@79 4805 // If it's a function
rlm@79 4806 if ( jQuery.isFunction( params ) ) {
rlm@79 4807 // We assume that it's the callback
rlm@79 4808 callback = params;
rlm@79 4809 params = null;
rlm@79 4810
rlm@79 4811 // Otherwise, build a param string
rlm@79 4812 } else if ( typeof params === "object" ) {
rlm@79 4813 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
rlm@79 4814 type = "POST";
rlm@79 4815 }
rlm@79 4816 }
rlm@79 4817
rlm@79 4818 var self = this;
rlm@79 4819
rlm@79 4820 // Request the remote document
rlm@79 4821 jQuery.ajax({
rlm@79 4822 url: url,
rlm@79 4823 type: type,
rlm@79 4824 dataType: "html",
rlm@79 4825 data: params,
rlm@79 4826 complete: function( res, status ) {
rlm@79 4827 // If successful, inject the HTML into all the matched elements
rlm@79 4828 if ( status === "success" || status === "notmodified" ) {
rlm@79 4829 // See if a selector was specified
rlm@79 4830 self.html( selector ?
rlm@79 4831 // Create a dummy div to hold the results
rlm@79 4832 jQuery("<div />")
rlm@79 4833 // inject the contents of the document in, removing the scripts
rlm@79 4834 // to avoid any 'Permission Denied' errors in IE
rlm@79 4835 .append(res.responseText.replace(rscript, ""))
rlm@79 4836
rlm@79 4837 // Locate the specified elements
rlm@79 4838 .find(selector) :
rlm@79 4839
rlm@79 4840 // If not, just inject the full result
rlm@79 4841 res.responseText );
rlm@79 4842 }
rlm@79 4843
rlm@79 4844 if ( callback ) {
rlm@79 4845 self.each( callback, [res.responseText, status, res] );
rlm@79 4846 }
rlm@79 4847 }
rlm@79 4848 });
rlm@79 4849
rlm@79 4850 return this;
rlm@79 4851 },
rlm@79 4852
rlm@79 4853 serialize: function() {
rlm@79 4854 return jQuery.param(this.serializeArray());
rlm@79 4855 },
rlm@79 4856 serializeArray: function() {
rlm@79 4857 return this.map(function() {
rlm@79 4858 return this.elements ? jQuery.makeArray(this.elements) : this;
rlm@79 4859 })
rlm@79 4860 .filter(function() {
rlm@79 4861 return this.name && !this.disabled &&
rlm@79 4862 (this.checked || rselectTextarea.test(this.nodeName) ||
rlm@79 4863 rinput.test(this.type));
rlm@79 4864 })
rlm@79 4865 .map(function( i, elem ) {
rlm@79 4866 var val = jQuery(this).val();
rlm@79 4867
rlm@79 4868 return val == null ?
rlm@79 4869 null :
rlm@79 4870 jQuery.isArray(val) ?
rlm@79 4871 jQuery.map( val, function( val, i ) {
rlm@79 4872 return { name: elem.name, value: val };
rlm@79 4873 }) :
rlm@79 4874 { name: elem.name, value: val };
rlm@79 4875 }).get();
rlm@79 4876 }
rlm@79 4877 });
rlm@79 4878
rlm@79 4879 // Attach a bunch of functions for handling common AJAX events
rlm@79 4880 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
rlm@79 4881 jQuery.fn[o] = function( f ) {
rlm@79 4882 return this.bind(o, f);
rlm@79 4883 };
rlm@79 4884 });
rlm@79 4885
rlm@79 4886 jQuery.extend({
rlm@79 4887
rlm@79 4888 get: function( url, data, callback, type ) {
rlm@79 4889 // shift arguments if data argument was omited
rlm@79 4890 if ( jQuery.isFunction( data ) ) {
rlm@79 4891 type = type || callback;
rlm@79 4892 callback = data;
rlm@79 4893 data = null;
rlm@79 4894 }
rlm@79 4895
rlm@79 4896 return jQuery.ajax({
rlm@79 4897 type: "GET",
rlm@79 4898 url: url,
rlm@79 4899 data: data,
rlm@79 4900 success: callback,
rlm@79 4901 dataType: type
rlm@79 4902 });
rlm@79 4903 },
rlm@79 4904
rlm@79 4905 getScript: function( url, callback ) {
rlm@79 4906 return jQuery.get(url, null, callback, "script");
rlm@79 4907 },
rlm@79 4908
rlm@79 4909 getJSON: function( url, data, callback ) {
rlm@79 4910 return jQuery.get(url, data, callback, "json");
rlm@79 4911 },
rlm@79 4912
rlm@79 4913 post: function( url, data, callback, type ) {
rlm@79 4914 // shift arguments if data argument was omited
rlm@79 4915 if ( jQuery.isFunction( data ) ) {
rlm@79 4916 type = type || callback;
rlm@79 4917 callback = data;
rlm@79 4918 data = {};
rlm@79 4919 }
rlm@79 4920
rlm@79 4921 return jQuery.ajax({
rlm@79 4922 type: "POST",
rlm@79 4923 url: url,
rlm@79 4924 data: data,
rlm@79 4925 success: callback,
rlm@79 4926 dataType: type
rlm@79 4927 });
rlm@79 4928 },
rlm@79 4929
rlm@79 4930 ajaxSetup: function( settings ) {
rlm@79 4931 jQuery.extend( jQuery.ajaxSettings, settings );
rlm@79 4932 },
rlm@79 4933
rlm@79 4934 ajaxSettings: {
rlm@79 4935 url: location.href,
rlm@79 4936 global: true,
rlm@79 4937 type: "GET",
rlm@79 4938 contentType: "application/x-www-form-urlencoded",
rlm@79 4939 processData: true,
rlm@79 4940 async: true,
rlm@79 4941 /*
rlm@79 4942 timeout: 0,
rlm@79 4943 data: null,
rlm@79 4944 username: null,
rlm@79 4945 password: null,
rlm@79 4946 traditional: false,
rlm@79 4947 */
rlm@79 4948 // Create the request object; Microsoft failed to properly
rlm@79 4949 // implement the XMLHttpRequest in IE7 (can't request local files),
rlm@79 4950 // so we use the ActiveXObject when it is available
rlm@79 4951 // This function can be overriden by calling jQuery.ajaxSetup
rlm@79 4952 xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
rlm@79 4953 function() {
rlm@79 4954 return new window.XMLHttpRequest();
rlm@79 4955 } :
rlm@79 4956 function() {
rlm@79 4957 try {
rlm@79 4958 return new window.ActiveXObject("Microsoft.XMLHTTP");
rlm@79 4959 } catch(e) {}
rlm@79 4960 },
rlm@79 4961 accepts: {
rlm@79 4962 xml: "application/xml, text/xml",
rlm@79 4963 html: "text/html",
rlm@79 4964 script: "text/javascript, application/javascript",
rlm@79 4965 json: "application/json, text/javascript",
rlm@79 4966 text: "text/plain",
rlm@79 4967 _default: "*/*"
rlm@79 4968 }
rlm@79 4969 },
rlm@79 4970
rlm@79 4971 // Last-Modified header cache for next request
rlm@79 4972 lastModified: {},
rlm@79 4973 etag: {},
rlm@79 4974
rlm@79 4975 ajax: function( origSettings ) {
rlm@79 4976 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
rlm@79 4977
rlm@79 4978 var jsonp, status, data,
rlm@79 4979 callbackContext = origSettings && origSettings.context || s,
rlm@79 4980 type = s.type.toUpperCase();
rlm@79 4981
rlm@79 4982 // convert data if not already a string
rlm@79 4983 if ( s.data && s.processData && typeof s.data !== "string" ) {
rlm@79 4984 s.data = jQuery.param( s.data, s.traditional );
rlm@79 4985 }
rlm@79 4986
rlm@79 4987 // Handle JSONP Parameter Callbacks
rlm@79 4988 if ( s.dataType === "jsonp" ) {
rlm@79 4989 if ( type === "GET" ) {
rlm@79 4990 if ( !jsre.test( s.url ) ) {
rlm@79 4991 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
rlm@79 4992 }
rlm@79 4993 } else if ( !s.data || !jsre.test(s.data) ) {
rlm@79 4994 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
rlm@79 4995 }
rlm@79 4996 s.dataType = "json";
rlm@79 4997 }
rlm@79 4998
rlm@79 4999 // Build temporary JSONP function
rlm@79 5000 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
rlm@79 5001 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
rlm@79 5002
rlm@79 5003 // Replace the =? sequence both in the query string and the data
rlm@79 5004 if ( s.data ) {
rlm@79 5005 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
rlm@79 5006 }
rlm@79 5007
rlm@79 5008 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
rlm@79 5009
rlm@79 5010 // We need to make sure
rlm@79 5011 // that a JSONP style response is executed properly
rlm@79 5012 s.dataType = "script";
rlm@79 5013
rlm@79 5014 // Handle JSONP-style loading
rlm@79 5015 window[ jsonp ] = window[ jsonp ] || function( tmp ) {
rlm@79 5016 data = tmp;
rlm@79 5017 success();
rlm@79 5018 complete();
rlm@79 5019 // Garbage collect
rlm@79 5020 window[ jsonp ] = undefined;
rlm@79 5021
rlm@79 5022 try {
rlm@79 5023 delete window[ jsonp ];
rlm@79 5024 } catch(e) {}
rlm@79 5025
rlm@79 5026 if ( head ) {
rlm@79 5027 head.removeChild( script );
rlm@79 5028 }
rlm@79 5029 };
rlm@79 5030 }
rlm@79 5031
rlm@79 5032 if ( s.dataType === "script" && s.cache === null ) {
rlm@79 5033 s.cache = false;
rlm@79 5034 }
rlm@79 5035
rlm@79 5036 if ( s.cache === false && type === "GET" ) {
rlm@79 5037 var ts = now();
rlm@79 5038
rlm@79 5039 // try replacing _= if it is there
rlm@79 5040 var ret = s.url.replace(rts, "$1_=" + ts + "$2");
rlm@79 5041
rlm@79 5042 // if nothing was replaced, add timestamp to the end
rlm@79 5043 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
rlm@79 5044 }
rlm@79 5045
rlm@79 5046 // If data is available, append data to url for get requests
rlm@79 5047 if ( s.data && type === "GET" ) {
rlm@79 5048 s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
rlm@79 5049 }
rlm@79 5050
rlm@79 5051 // Watch for a new set of requests
rlm@79 5052 if ( s.global && ! jQuery.active++ ) {
rlm@79 5053 jQuery.event.trigger( "ajaxStart" );
rlm@79 5054 }
rlm@79 5055
rlm@79 5056 // Matches an absolute URL, and saves the domain
rlm@79 5057 var parts = rurl.exec( s.url ),
rlm@79 5058 remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
rlm@79 5059
rlm@79 5060 // If we're requesting a remote document
rlm@79 5061 // and trying to load JSON or Script with a GET
rlm@79 5062 if ( s.dataType === "script" && type === "GET" && remote ) {
rlm@79 5063 var head = document.getElementsByTagName("head")[0] || document.documentElement;
rlm@79 5064 var script = document.createElement("script");
rlm@79 5065 script.src = s.url;
rlm@79 5066 if ( s.scriptCharset ) {
rlm@79 5067 script.charset = s.scriptCharset;
rlm@79 5068 }
rlm@79 5069
rlm@79 5070 // Handle Script loading
rlm@79 5071 if ( !jsonp ) {
rlm@79 5072 var done = false;
rlm@79 5073
rlm@79 5074 // Attach handlers for all browsers
rlm@79 5075 script.onload = script.onreadystatechange = function() {
rlm@79 5076 if ( !done && (!this.readyState ||
rlm@79 5077 this.readyState === "loaded" || this.readyState === "complete") ) {
rlm@79 5078 done = true;
rlm@79 5079 success();
rlm@79 5080 complete();
rlm@79 5081
rlm@79 5082 // Handle memory leak in IE
rlm@79 5083 script.onload = script.onreadystatechange = null;
rlm@79 5084 if ( head && script.parentNode ) {
rlm@79 5085 head.removeChild( script );
rlm@79 5086 }
rlm@79 5087 }
rlm@79 5088 };
rlm@79 5089 }
rlm@79 5090
rlm@79 5091 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
rlm@79 5092 // This arises when a base node is used (#2709 and #4378).
rlm@79 5093 head.insertBefore( script, head.firstChild );
rlm@79 5094
rlm@79 5095 // We handle everything using the script element injection
rlm@79 5096 return undefined;
rlm@79 5097 }
rlm@79 5098
rlm@79 5099 var requestDone = false;
rlm@79 5100
rlm@79 5101 // Create the request object
rlm@79 5102 var xhr = s.xhr();
rlm@79 5103
rlm@79 5104 if ( !xhr ) {
rlm@79 5105 return;
rlm@79 5106 }
rlm@79 5107
rlm@79 5108 // Open the socket
rlm@79 5109 // Passing null username, generates a login popup on Opera (#2865)
rlm@79 5110 if ( s.username ) {
rlm@79 5111 xhr.open(type, s.url, s.async, s.username, s.password);
rlm@79 5112 } else {
rlm@79 5113 xhr.open(type, s.url, s.async);
rlm@79 5114 }
rlm@79 5115
rlm@79 5116 // Need an extra try/catch for cross domain requests in Firefox 3
rlm@79 5117 try {
rlm@79 5118 // Set the correct header, if data is being sent
rlm@79 5119 if ( s.data || origSettings && origSettings.contentType ) {
rlm@79 5120 xhr.setRequestHeader("Content-Type", s.contentType);
rlm@79 5121 }
rlm@79 5122
rlm@79 5123 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
rlm@79 5124 if ( s.ifModified ) {
rlm@79 5125 if ( jQuery.lastModified[s.url] ) {
rlm@79 5126 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
rlm@79 5127 }
rlm@79 5128
rlm@79 5129 if ( jQuery.etag[s.url] ) {
rlm@79 5130 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
rlm@79 5131 }
rlm@79 5132 }
rlm@79 5133
rlm@79 5134 // Set header so the called script knows that it's an XMLHttpRequest
rlm@79 5135 // Only send the header if it's not a remote XHR
rlm@79 5136 if ( !remote ) {
rlm@79 5137 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
rlm@79 5138 }
rlm@79 5139
rlm@79 5140 // Set the Accepts header for the server, depending on the dataType
rlm@79 5141 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
rlm@79 5142 s.accepts[ s.dataType ] + ", */*" :
rlm@79 5143 s.accepts._default );
rlm@79 5144 } catch(e) {}
rlm@79 5145
rlm@79 5146 // Allow custom headers/mimetypes and early abort
rlm@79 5147 if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
rlm@79 5148 // Handle the global AJAX counter
rlm@79 5149 if ( s.global && ! --jQuery.active ) {
rlm@79 5150 jQuery.event.trigger( "ajaxStop" );
rlm@79 5151 }
rlm@79 5152
rlm@79 5153 // close opended socket
rlm@79 5154 xhr.abort();
rlm@79 5155 return false;
rlm@79 5156 }
rlm@79 5157
rlm@79 5158 if ( s.global ) {
rlm@79 5159 trigger("ajaxSend", [xhr, s]);
rlm@79 5160 }
rlm@79 5161
rlm@79 5162 // Wait for a response to come back
rlm@79 5163 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
rlm@79 5164 // The request was aborted
rlm@79 5165 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
rlm@79 5166 // Opera doesn't call onreadystatechange before this point
rlm@79 5167 // so we simulate the call
rlm@79 5168 if ( !requestDone ) {
rlm@79 5169 complete();
rlm@79 5170 }
rlm@79 5171
rlm@79 5172 requestDone = true;
rlm@79 5173 if ( xhr ) {
rlm@79 5174 xhr.onreadystatechange = jQuery.noop;
rlm@79 5175 }
rlm@79 5176
rlm@79 5177 // The transfer is complete and the data is available, or the request timed out
rlm@79 5178 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
rlm@79 5179 requestDone = true;
rlm@79 5180 xhr.onreadystatechange = jQuery.noop;
rlm@79 5181
rlm@79 5182 status = isTimeout === "timeout" ?
rlm@79 5183 "timeout" :
rlm@79 5184 !jQuery.httpSuccess( xhr ) ?
rlm@79 5185 "error" :
rlm@79 5186 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
rlm@79 5187 "notmodified" :
rlm@79 5188 "success";
rlm@79 5189
rlm@79 5190 var errMsg;
rlm@79 5191
rlm@79 5192 if ( status === "success" ) {
rlm@79 5193 // Watch for, and catch, XML document parse errors
rlm@79 5194 try {
rlm@79 5195 // process the data (runs the xml through httpData regardless of callback)
rlm@79 5196 data = jQuery.httpData( xhr, s.dataType, s );
rlm@79 5197 } catch(err) {
rlm@79 5198 status = "parsererror";
rlm@79 5199 errMsg = err;
rlm@79 5200 }
rlm@79 5201 }
rlm@79 5202
rlm@79 5203 // Make sure that the request was successful or notmodified
rlm@79 5204 if ( status === "success" || status === "notmodified" ) {
rlm@79 5205 // JSONP handles its own success callback
rlm@79 5206 if ( !jsonp ) {
rlm@79 5207 success();
rlm@79 5208 }
rlm@79 5209 } else {
rlm@79 5210 jQuery.handleError(s, xhr, status, errMsg);
rlm@79 5211 }
rlm@79 5212
rlm@79 5213 // Fire the complete handlers
rlm@79 5214 complete();
rlm@79 5215
rlm@79 5216 if ( isTimeout === "timeout" ) {
rlm@79 5217 xhr.abort();
rlm@79 5218 }
rlm@79 5219
rlm@79 5220 // Stop memory leaks
rlm@79 5221 if ( s.async ) {
rlm@79 5222 xhr = null;
rlm@79 5223 }
rlm@79 5224 }
rlm@79 5225 };
rlm@79 5226
rlm@79 5227 // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
rlm@79 5228 // Opera doesn't fire onreadystatechange at all on abort
rlm@79 5229 try {
rlm@79 5230 var oldAbort = xhr.abort;
rlm@79 5231 xhr.abort = function() {
rlm@79 5232 if ( xhr ) {
rlm@79 5233 oldAbort.call( xhr );
rlm@79 5234 }
rlm@79 5235
rlm@79 5236 onreadystatechange( "abort" );
rlm@79 5237 };
rlm@79 5238 } catch(e) { }
rlm@79 5239
rlm@79 5240 // Timeout checker
rlm@79 5241 if ( s.async && s.timeout > 0 ) {
rlm@79 5242 setTimeout(function() {
rlm@79 5243 // Check to see if the request is still happening
rlm@79 5244 if ( xhr && !requestDone ) {
rlm@79 5245 onreadystatechange( "timeout" );
rlm@79 5246 }
rlm@79 5247 }, s.timeout);
rlm@79 5248 }
rlm@79 5249
rlm@79 5250 // Send the data
rlm@79 5251 try {
rlm@79 5252 xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
rlm@79 5253 } catch(e) {
rlm@79 5254 jQuery.handleError(s, xhr, null, e);
rlm@79 5255 // Fire the complete handlers
rlm@79 5256 complete();
rlm@79 5257 }
rlm@79 5258
rlm@79 5259 // firefox 1.5 doesn't fire statechange for sync requests
rlm@79 5260 if ( !s.async ) {
rlm@79 5261 onreadystatechange();
rlm@79 5262 }
rlm@79 5263
rlm@79 5264 function success() {
rlm@79 5265 // If a local callback was specified, fire it and pass it the data
rlm@79 5266 if ( s.success ) {
rlm@79 5267 s.success.call( callbackContext, data, status, xhr );
rlm@79 5268 }
rlm@79 5269
rlm@79 5270 // Fire the global callback
rlm@79 5271 if ( s.global ) {
rlm@79 5272 trigger( "ajaxSuccess", [xhr, s] );
rlm@79 5273 }
rlm@79 5274 }
rlm@79 5275
rlm@79 5276 function complete() {
rlm@79 5277 // Process result
rlm@79 5278 if ( s.complete ) {
rlm@79 5279 s.complete.call( callbackContext, xhr, status);
rlm@79 5280 }
rlm@79 5281
rlm@79 5282 // The request was completed
rlm@79 5283 if ( s.global ) {
rlm@79 5284 trigger( "ajaxComplete", [xhr, s] );
rlm@79 5285 }
rlm@79 5286
rlm@79 5287 // Handle the global AJAX counter
rlm@79 5288 if ( s.global && ! --jQuery.active ) {
rlm@79 5289 jQuery.event.trigger( "ajaxStop" );
rlm@79 5290 }
rlm@79 5291 }
rlm@79 5292
rlm@79 5293 function trigger(type, args) {
rlm@79 5294 (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
rlm@79 5295 }
rlm@79 5296
rlm@79 5297 // return XMLHttpRequest to allow aborting the request etc.
rlm@79 5298 return xhr;
rlm@79 5299 },
rlm@79 5300
rlm@79 5301 handleError: function( s, xhr, status, e ) {
rlm@79 5302 // If a local callback was specified, fire it
rlm@79 5303 if ( s.error ) {
rlm@79 5304 s.error.call( s.context || s, xhr, status, e );
rlm@79 5305 }
rlm@79 5306
rlm@79 5307 // Fire the global callback
rlm@79 5308 if ( s.global ) {
rlm@79 5309 (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
rlm@79 5310 }
rlm@79 5311 },
rlm@79 5312
rlm@79 5313 // Counter for holding the number of active queries
rlm@79 5314 active: 0,
rlm@79 5315
rlm@79 5316 // Determines if an XMLHttpRequest was successful or not
rlm@79 5317 httpSuccess: function( xhr ) {
rlm@79 5318 try {
rlm@79 5319 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
rlm@79 5320 return !xhr.status && location.protocol === "file:" ||
rlm@79 5321 // Opera returns 0 when status is 304
rlm@79 5322 ( xhr.status >= 200 && xhr.status < 300 ) ||
rlm@79 5323 xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
rlm@79 5324 } catch(e) {}
rlm@79 5325
rlm@79 5326 return false;
rlm@79 5327 },
rlm@79 5328
rlm@79 5329 // Determines if an XMLHttpRequest returns NotModified
rlm@79 5330 httpNotModified: function( xhr, url ) {
rlm@79 5331 var lastModified = xhr.getResponseHeader("Last-Modified"),
rlm@79 5332 etag = xhr.getResponseHeader("Etag");
rlm@79 5333
rlm@79 5334 if ( lastModified ) {
rlm@79 5335 jQuery.lastModified[url] = lastModified;
rlm@79 5336 }
rlm@79 5337
rlm@79 5338 if ( etag ) {
rlm@79 5339 jQuery.etag[url] = etag;
rlm@79 5340 }
rlm@79 5341
rlm@79 5342 // Opera returns 0 when status is 304
rlm@79 5343 return xhr.status === 304 || xhr.status === 0;
rlm@79 5344 },
rlm@79 5345
rlm@79 5346 httpData: function( xhr, type, s ) {
rlm@79 5347 var ct = xhr.getResponseHeader("content-type") || "",
rlm@79 5348 xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
rlm@79 5349 data = xml ? xhr.responseXML : xhr.responseText;
rlm@79 5350
rlm@79 5351 if ( xml && data.documentElement.nodeName === "parsererror" ) {
rlm@79 5352 jQuery.error( "parsererror" );
rlm@79 5353 }
rlm@79 5354
rlm@79 5355 // Allow a pre-filtering function to sanitize the response
rlm@79 5356 // s is checked to keep backwards compatibility
rlm@79 5357 if ( s && s.dataFilter ) {
rlm@79 5358 data = s.dataFilter( data, type );
rlm@79 5359 }
rlm@79 5360
rlm@79 5361 // The filter can actually parse the response
rlm@79 5362 if ( typeof data === "string" ) {
rlm@79 5363 // Get the JavaScript object, if JSON is used.
rlm@79 5364 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
rlm@79 5365 data = jQuery.parseJSON( data );
rlm@79 5366
rlm@79 5367 // If the type is "script", eval it in global context
rlm@79 5368 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
rlm@79 5369 jQuery.globalEval( data );
rlm@79 5370 }
rlm@79 5371 }
rlm@79 5372
rlm@79 5373 return data;
rlm@79 5374 },
rlm@79 5375
rlm@79 5376 // Serialize an array of form elements or a set of
rlm@79 5377 // key/values into a query string
rlm@79 5378 param: function( a, traditional ) {
rlm@79 5379 var s = [];
rlm@79 5380
rlm@79 5381 // Set traditional to true for jQuery <= 1.3.2 behavior.
rlm@79 5382 if ( traditional === undefined ) {
rlm@79 5383 traditional = jQuery.ajaxSettings.traditional;
rlm@79 5384 }
rlm@79 5385
rlm@79 5386 // If an array was passed in, assume that it is an array of form elements.
rlm@79 5387 if ( jQuery.isArray(a) || a.jquery ) {
rlm@79 5388 // Serialize the form elements
rlm@79 5389 jQuery.each( a, function() {
rlm@79 5390 add( this.name, this.value );
rlm@79 5391 });
rlm@79 5392
rlm@79 5393 } else {
rlm@79 5394 // If traditional, encode the "old" way (the way 1.3.2 or older
rlm@79 5395 // did it), otherwise encode params recursively.
rlm@79 5396 for ( var prefix in a ) {
rlm@79 5397 buildParams( prefix, a[prefix] );
rlm@79 5398 }
rlm@79 5399 }
rlm@79 5400
rlm@79 5401 // Return the resulting serialization
rlm@79 5402 return s.join("&").replace(r20, "+");
rlm@79 5403
rlm@79 5404 function buildParams( prefix, obj ) {
rlm@79 5405 if ( jQuery.isArray(obj) ) {
rlm@79 5406 // Serialize array item.
rlm@79 5407 jQuery.each( obj, function( i, v ) {
rlm@79 5408 if ( traditional || /\[\]$/.test( prefix ) ) {
rlm@79 5409 // Treat each array item as a scalar.
rlm@79 5410 add( prefix, v );
rlm@79 5411 } else {
rlm@79 5412 // If array item is non-scalar (array or object), encode its
rlm@79 5413 // numeric index to resolve deserialization ambiguity issues.
rlm@79 5414 // Note that rack (as of 1.0.0) can't currently deserialize
rlm@79 5415 // nested arrays properly, and attempting to do so may cause
rlm@79 5416 // a server error. Possible fixes are to modify rack's
rlm@79 5417 // deserialization algorithm or to provide an option or flag
rlm@79 5418 // to force array serialization to be shallow.
rlm@79 5419 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
rlm@79 5420 }
rlm@79 5421 });
rlm@79 5422
rlm@79 5423 } else if ( !traditional && obj != null && typeof obj === "object" ) {
rlm@79 5424 // Serialize object item.
rlm@79 5425 jQuery.each( obj, function( k, v ) {
rlm@79 5426 buildParams( prefix + "[" + k + "]", v );
rlm@79 5427 });
rlm@79 5428
rlm@79 5429 } else {
rlm@79 5430 // Serialize scalar item.
rlm@79 5431 add( prefix, obj );
rlm@79 5432 }
rlm@79 5433 }
rlm@79 5434
rlm@79 5435 function add( key, value ) {
rlm@79 5436 // If value is a function, invoke it and return its value
rlm@79 5437 value = jQuery.isFunction(value) ? value() : value;
rlm@79 5438 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
rlm@79 5439 }
rlm@79 5440 }
rlm@79 5441 });
rlm@79 5442 var elemdisplay = {},
rlm@79 5443 rfxtypes = /toggle|show|hide/,
rlm@79 5444 rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
rlm@79 5445 timerId,
rlm@79 5446 fxAttrs = [
rlm@79 5447 // height animations
rlm@79 5448 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
rlm@79 5449 // width animations
rlm@79 5450 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
rlm@79 5451 // opacity animations
rlm@79 5452 [ "opacity" ]
rlm@79 5453 ];
rlm@79 5454
rlm@79 5455 jQuery.fn.extend({
rlm@79 5456 show: function( speed, callback ) {
rlm@79 5457 if ( speed || speed === 0) {
rlm@79 5458 return this.animate( genFx("show", 3), speed, callback);
rlm@79 5459
rlm@79 5460 } else {
rlm@79 5461 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 5462 var old = jQuery.data(this[i], "olddisplay");
rlm@79 5463
rlm@79 5464 this[i].style.display = old || "";
rlm@79 5465
rlm@79 5466 if ( jQuery.css(this[i], "display") === "none" ) {
rlm@79 5467 var nodeName = this[i].nodeName, display;
rlm@79 5468
rlm@79 5469 if ( elemdisplay[ nodeName ] ) {
rlm@79 5470 display = elemdisplay[ nodeName ];
rlm@79 5471
rlm@79 5472 } else {
rlm@79 5473 var elem = jQuery("<" + nodeName + " />").appendTo("body");
rlm@79 5474
rlm@79 5475 display = elem.css("display");
rlm@79 5476
rlm@79 5477 if ( display === "none" ) {
rlm@79 5478 display = "block";
rlm@79 5479 }
rlm@79 5480
rlm@79 5481 elem.remove();
rlm@79 5482
rlm@79 5483 elemdisplay[ nodeName ] = display;
rlm@79 5484 }
rlm@79 5485
rlm@79 5486 jQuery.data(this[i], "olddisplay", display);
rlm@79 5487 }
rlm@79 5488 }
rlm@79 5489
rlm@79 5490 // Set the display of the elements in a second loop
rlm@79 5491 // to avoid the constant reflow
rlm@79 5492 for ( var j = 0, k = this.length; j < k; j++ ) {
rlm@79 5493 this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
rlm@79 5494 }
rlm@79 5495
rlm@79 5496 return this;
rlm@79 5497 }
rlm@79 5498 },
rlm@79 5499
rlm@79 5500 hide: function( speed, callback ) {
rlm@79 5501 if ( speed || speed === 0 ) {
rlm@79 5502 return this.animate( genFx("hide", 3), speed, callback);
rlm@79 5503
rlm@79 5504 } else {
rlm@79 5505 for ( var i = 0, l = this.length; i < l; i++ ) {
rlm@79 5506 var old = jQuery.data(this[i], "olddisplay");
rlm@79 5507 if ( !old && old !== "none" ) {
rlm@79 5508 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
rlm@79 5509 }
rlm@79 5510 }
rlm@79 5511
rlm@79 5512 // Set the display of the elements in a second loop
rlm@79 5513 // to avoid the constant reflow
rlm@79 5514 for ( var j = 0, k = this.length; j < k; j++ ) {
rlm@79 5515 this[j].style.display = "none";
rlm@79 5516 }
rlm@79 5517
rlm@79 5518 return this;
rlm@79 5519 }
rlm@79 5520 },
rlm@79 5521
rlm@79 5522 // Save the old toggle function
rlm@79 5523 _toggle: jQuery.fn.toggle,
rlm@79 5524
rlm@79 5525 toggle: function( fn, fn2 ) {
rlm@79 5526 var bool = typeof fn === "boolean";
rlm@79 5527
rlm@79 5528 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
rlm@79 5529 this._toggle.apply( this, arguments );
rlm@79 5530
rlm@79 5531 } else if ( fn == null || bool ) {
rlm@79 5532 this.each(function() {
rlm@79 5533 var state = bool ? fn : jQuery(this).is(":hidden");
rlm@79 5534 jQuery(this)[ state ? "show" : "hide" ]();
rlm@79 5535 });
rlm@79 5536
rlm@79 5537 } else {
rlm@79 5538 this.animate(genFx("toggle", 3), fn, fn2);
rlm@79 5539 }
rlm@79 5540
rlm@79 5541 return this;
rlm@79 5542 },
rlm@79 5543
rlm@79 5544 fadeTo: function( speed, to, callback ) {
rlm@79 5545 return this.filter(":hidden").css("opacity", 0).show().end()
rlm@79 5546 .animate({opacity: to}, speed, callback);
rlm@79 5547 },
rlm@79 5548
rlm@79 5549 animate: function( prop, speed, easing, callback ) {
rlm@79 5550 var optall = jQuery.speed(speed, easing, callback);
rlm@79 5551
rlm@79 5552 if ( jQuery.isEmptyObject( prop ) ) {
rlm@79 5553 return this.each( optall.complete );
rlm@79 5554 }
rlm@79 5555
rlm@79 5556 return this[ optall.queue === false ? "each" : "queue" ](function() {
rlm@79 5557 var opt = jQuery.extend({}, optall), p,
rlm@79 5558 hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
rlm@79 5559 self = this;
rlm@79 5560
rlm@79 5561 for ( p in prop ) {
rlm@79 5562 var name = p.replace(rdashAlpha, fcamelCase);
rlm@79 5563
rlm@79 5564 if ( p !== name ) {
rlm@79 5565 prop[ name ] = prop[ p ];
rlm@79 5566 delete prop[ p ];
rlm@79 5567 p = name;
rlm@79 5568 }
rlm@79 5569
rlm@79 5570 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
rlm@79 5571 return opt.complete.call(this);
rlm@79 5572 }
rlm@79 5573
rlm@79 5574 if ( ( p === "height" || p === "width" ) && this.style ) {
rlm@79 5575 // Store display property
rlm@79 5576 opt.display = jQuery.css(this, "display");
rlm@79 5577
rlm@79 5578 // Make sure that nothing sneaks out
rlm@79 5579 opt.overflow = this.style.overflow;
rlm@79 5580 }
rlm@79 5581
rlm@79 5582 if ( jQuery.isArray( prop[p] ) ) {
rlm@79 5583 // Create (if needed) and add to specialEasing
rlm@79 5584 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
rlm@79 5585 prop[p] = prop[p][0];
rlm@79 5586 }
rlm@79 5587 }
rlm@79 5588
rlm@79 5589 if ( opt.overflow != null ) {
rlm@79 5590 this.style.overflow = "hidden";
rlm@79 5591 }
rlm@79 5592
rlm@79 5593 opt.curAnim = jQuery.extend({}, prop);
rlm@79 5594
rlm@79 5595 jQuery.each( prop, function( name, val ) {
rlm@79 5596 var e = new jQuery.fx( self, opt, name );
rlm@79 5597
rlm@79 5598 if ( rfxtypes.test(val) ) {
rlm@79 5599 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
rlm@79 5600
rlm@79 5601 } else {
rlm@79 5602 var parts = rfxnum.exec(val),
rlm@79 5603 start = e.cur(true) || 0;
rlm@79 5604
rlm@79 5605 if ( parts ) {
rlm@79 5606 var end = parseFloat( parts[2] ),
rlm@79 5607 unit = parts[3] || "px";
rlm@79 5608
rlm@79 5609 // We need to compute starting value
rlm@79 5610 if ( unit !== "px" ) {
rlm@79 5611 self.style[ name ] = (end || 1) + unit;
rlm@79 5612 start = ((end || 1) / e.cur(true)) * start;
rlm@79 5613 self.style[ name ] = start + unit;
rlm@79 5614 }
rlm@79 5615
rlm@79 5616 // If a +=/-= token was provided, we're doing a relative animation
rlm@79 5617 if ( parts[1] ) {
rlm@79 5618 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
rlm@79 5619 }
rlm@79 5620
rlm@79 5621 e.custom( start, end, unit );
rlm@79 5622
rlm@79 5623 } else {
rlm@79 5624 e.custom( start, val, "" );
rlm@79 5625 }
rlm@79 5626 }
rlm@79 5627 });
rlm@79 5628
rlm@79 5629 // For JS strict compliance
rlm@79 5630 return true;
rlm@79 5631 });
rlm@79 5632 },
rlm@79 5633
rlm@79 5634 stop: function( clearQueue, gotoEnd ) {
rlm@79 5635 var timers = jQuery.timers;
rlm@79 5636
rlm@79 5637 if ( clearQueue ) {
rlm@79 5638 this.queue([]);
rlm@79 5639 }
rlm@79 5640
rlm@79 5641 this.each(function() {
rlm@79 5642 // go in reverse order so anything added to the queue during the loop is ignored
rlm@79 5643 for ( var i = timers.length - 1; i >= 0; i-- ) {
rlm@79 5644 if ( timers[i].elem === this ) {
rlm@79 5645 if (gotoEnd) {
rlm@79 5646 // force the next step to be the last
rlm@79 5647 timers[i](true);
rlm@79 5648 }
rlm@79 5649
rlm@79 5650 timers.splice(i, 1);
rlm@79 5651 }
rlm@79 5652 }
rlm@79 5653 });
rlm@79 5654
rlm@79 5655 // start the next in the queue if the last step wasn't forced
rlm@79 5656 if ( !gotoEnd ) {
rlm@79 5657 this.dequeue();
rlm@79 5658 }
rlm@79 5659
rlm@79 5660 return this;
rlm@79 5661 }
rlm@79 5662
rlm@79 5663 });
rlm@79 5664
rlm@79 5665 // Generate shortcuts for custom animations
rlm@79 5666 jQuery.each({
rlm@79 5667 slideDown: genFx("show", 1),
rlm@79 5668 slideUp: genFx("hide", 1),
rlm@79 5669 slideToggle: genFx("toggle", 1),
rlm@79 5670 fadeIn: { opacity: "show" },
rlm@79 5671 fadeOut: { opacity: "hide" }
rlm@79 5672 }, function( name, props ) {
rlm@79 5673 jQuery.fn[ name ] = function( speed, callback ) {
rlm@79 5674 return this.animate( props, speed, callback );
rlm@79 5675 };
rlm@79 5676 });
rlm@79 5677
rlm@79 5678 jQuery.extend({
rlm@79 5679 speed: function( speed, easing, fn ) {
rlm@79 5680 var opt = speed && typeof speed === "object" ? speed : {
rlm@79 5681 complete: fn || !fn && easing ||
rlm@79 5682 jQuery.isFunction( speed ) && speed,
rlm@79 5683 duration: speed,
rlm@79 5684 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
rlm@79 5685 };
rlm@79 5686
rlm@79 5687 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
rlm@79 5688 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
rlm@79 5689
rlm@79 5690 // Queueing
rlm@79 5691 opt.old = opt.complete;
rlm@79 5692 opt.complete = function() {
rlm@79 5693 if ( opt.queue !== false ) {
rlm@79 5694 jQuery(this).dequeue();
rlm@79 5695 }
rlm@79 5696 if ( jQuery.isFunction( opt.old ) ) {
rlm@79 5697 opt.old.call( this );
rlm@79 5698 }
rlm@79 5699 };
rlm@79 5700
rlm@79 5701 return opt;
rlm@79 5702 },
rlm@79 5703
rlm@79 5704 easing: {
rlm@79 5705 linear: function( p, n, firstNum, diff ) {
rlm@79 5706 return firstNum + diff * p;
rlm@79 5707 },
rlm@79 5708 swing: function( p, n, firstNum, diff ) {
rlm@79 5709 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
rlm@79 5710 }
rlm@79 5711 },
rlm@79 5712
rlm@79 5713 timers: [],
rlm@79 5714
rlm@79 5715 fx: function( elem, options, prop ) {
rlm@79 5716 this.options = options;
rlm@79 5717 this.elem = elem;
rlm@79 5718 this.prop = prop;
rlm@79 5719
rlm@79 5720 if ( !options.orig ) {
rlm@79 5721 options.orig = {};
rlm@79 5722 }
rlm@79 5723 }
rlm@79 5724
rlm@79 5725 });
rlm@79 5726
rlm@79 5727 jQuery.fx.prototype = {
rlm@79 5728 // Simple function for setting a style value
rlm@79 5729 update: function() {
rlm@79 5730 if ( this.options.step ) {
rlm@79 5731 this.options.step.call( this.elem, this.now, this );
rlm@79 5732 }
rlm@79 5733
rlm@79 5734 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
rlm@79 5735
rlm@79 5736 // Set display property to block for height/width animations
rlm@79 5737 if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
rlm@79 5738 this.elem.style.display = "block";
rlm@79 5739 }
rlm@79 5740 },
rlm@79 5741
rlm@79 5742 // Get the current size
rlm@79 5743 cur: function( force ) {
rlm@79 5744 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
rlm@79 5745 return this.elem[ this.prop ];
rlm@79 5746 }
rlm@79 5747
rlm@79 5748 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
rlm@79 5749 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
rlm@79 5750 },
rlm@79 5751
rlm@79 5752 // Start an animation from one number to another
rlm@79 5753 custom: function( from, to, unit ) {
rlm@79 5754 this.startTime = now();
rlm@79 5755 this.start = from;
rlm@79 5756 this.end = to;
rlm@79 5757 this.unit = unit || this.unit || "px";
rlm@79 5758 this.now = this.start;
rlm@79 5759 this.pos = this.state = 0;
rlm@79 5760
rlm@79 5761 var self = this;
rlm@79 5762 function t( gotoEnd ) {
rlm@79 5763 return self.step(gotoEnd);
rlm@79 5764 }
rlm@79 5765
rlm@79 5766 t.elem = this.elem;
rlm@79 5767
rlm@79 5768 if ( t() && jQuery.timers.push(t) && !timerId ) {
rlm@79 5769 timerId = setInterval(jQuery.fx.tick, 13);
rlm@79 5770 }
rlm@79 5771 },
rlm@79 5772
rlm@79 5773 // Simple 'show' function
rlm@79 5774 show: function() {
rlm@79 5775 // Remember where we started, so that we can go back to it later
rlm@79 5776 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
rlm@79 5777 this.options.show = true;
rlm@79 5778
rlm@79 5779 // Begin the animation
rlm@79 5780 // Make sure that we start at a small width/height to avoid any
rlm@79 5781 // flash of content
rlm@79 5782 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
rlm@79 5783
rlm@79 5784 // Start by showing the element
rlm@79 5785 jQuery( this.elem ).show();
rlm@79 5786 },
rlm@79 5787
rlm@79 5788 // Simple 'hide' function
rlm@79 5789 hide: function() {
rlm@79 5790 // Remember where we started, so that we can go back to it later
rlm@79 5791 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
rlm@79 5792 this.options.hide = true;
rlm@79 5793
rlm@79 5794 // Begin the animation
rlm@79 5795 this.custom(this.cur(), 0);
rlm@79 5796 },
rlm@79 5797
rlm@79 5798 // Each step of an animation
rlm@79 5799 step: function( gotoEnd ) {
rlm@79 5800 var t = now(), done = true;
rlm@79 5801
rlm@79 5802 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
rlm@79 5803 this.now = this.end;
rlm@79 5804 this.pos = this.state = 1;
rlm@79 5805 this.update();
rlm@79 5806
rlm@79 5807 this.options.curAnim[ this.prop ] = true;
rlm@79 5808
rlm@79 5809 for ( var i in this.options.curAnim ) {
rlm@79 5810 if ( this.options.curAnim[i] !== true ) {
rlm@79 5811 done = false;
rlm@79 5812 }
rlm@79 5813 }
rlm@79 5814
rlm@79 5815 if ( done ) {
rlm@79 5816 if ( this.options.display != null ) {
rlm@79 5817 // Reset the overflow
rlm@79 5818 this.elem.style.overflow = this.options.overflow;
rlm@79 5819
rlm@79 5820 // Reset the display
rlm@79 5821 var old = jQuery.data(this.elem, "olddisplay");
rlm@79 5822 this.elem.style.display = old ? old : this.options.display;
rlm@79 5823
rlm@79 5824 if ( jQuery.css(this.elem, "display") === "none" ) {
rlm@79 5825 this.elem.style.display = "block";
rlm@79 5826 }
rlm@79 5827 }
rlm@79 5828
rlm@79 5829 // Hide the element if the "hide" operation was done
rlm@79 5830 if ( this.options.hide ) {
rlm@79 5831 jQuery(this.elem).hide();
rlm@79 5832 }
rlm@79 5833
rlm@79 5834 // Reset the properties, if the item has been hidden or shown
rlm@79 5835 if ( this.options.hide || this.options.show ) {
rlm@79 5836 for ( var p in this.options.curAnim ) {
rlm@79 5837 jQuery.style(this.elem, p, this.options.orig[p]);
rlm@79 5838 }
rlm@79 5839 }
rlm@79 5840
rlm@79 5841 // Execute the complete function
rlm@79 5842 this.options.complete.call( this.elem );
rlm@79 5843 }
rlm@79 5844
rlm@79 5845 return false;
rlm@79 5846
rlm@79 5847 } else {
rlm@79 5848 var n = t - this.startTime;
rlm@79 5849 this.state = n / this.options.duration;
rlm@79 5850
rlm@79 5851 // Perform the easing function, defaults to swing
rlm@79 5852 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
rlm@79 5853 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
rlm@79 5854 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
rlm@79 5855 this.now = this.start + ((this.end - this.start) * this.pos);
rlm@79 5856
rlm@79 5857 // Perform the next step of the animation
rlm@79 5858 this.update();
rlm@79 5859 }
rlm@79 5860
rlm@79 5861 return true;
rlm@79 5862 }
rlm@79 5863 };
rlm@79 5864
rlm@79 5865 jQuery.extend( jQuery.fx, {
rlm@79 5866 tick: function() {
rlm@79 5867 var timers = jQuery.timers;
rlm@79 5868
rlm@79 5869 for ( var i = 0; i < timers.length; i++ ) {
rlm@79 5870 if ( !timers[i]() ) {
rlm@79 5871 timers.splice(i--, 1);
rlm@79 5872 }
rlm@79 5873 }
rlm@79 5874
rlm@79 5875 if ( !timers.length ) {
rlm@79 5876 jQuery.fx.stop();
rlm@79 5877 }
rlm@79 5878 },
rlm@79 5879
rlm@79 5880 stop: function() {
rlm@79 5881 clearInterval( timerId );
rlm@79 5882 timerId = null;
rlm@79 5883 },
rlm@79 5884
rlm@79 5885 speeds: {
rlm@79 5886 slow: 600,
rlm@79 5887 fast: 200,
rlm@79 5888 // Default speed
rlm@79 5889 _default: 400
rlm@79 5890 },
rlm@79 5891
rlm@79 5892 step: {
rlm@79 5893 opacity: function( fx ) {
rlm@79 5894 jQuery.style(fx.elem, "opacity", fx.now);
rlm@79 5895 },
rlm@79 5896
rlm@79 5897 _default: function( fx ) {
rlm@79 5898 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
rlm@79 5899 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
rlm@79 5900 } else {
rlm@79 5901 fx.elem[ fx.prop ] = fx.now;
rlm@79 5902 }
rlm@79 5903 }
rlm@79 5904 }
rlm@79 5905 });
rlm@79 5906
rlm@79 5907 if ( jQuery.expr && jQuery.expr.filters ) {
rlm@79 5908 jQuery.expr.filters.animated = function( elem ) {
rlm@79 5909 return jQuery.grep(jQuery.timers, function( fn ) {
rlm@79 5910 return elem === fn.elem;
rlm@79 5911 }).length;
rlm@79 5912 };
rlm@79 5913 }
rlm@79 5914
rlm@79 5915 function genFx( type, num ) {
rlm@79 5916 var obj = {};
rlm@79 5917
rlm@79 5918 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
rlm@79 5919 obj[ this ] = type;
rlm@79 5920 });
rlm@79 5921
rlm@79 5922 return obj;
rlm@79 5923 }
rlm@79 5924 if ( "getBoundingClientRect" in document.documentElement ) {
rlm@79 5925 jQuery.fn.offset = function( options ) {
rlm@79 5926 var elem = this[0];
rlm@79 5927
rlm@79 5928 if ( options ) {
rlm@79 5929 return this.each(function( i ) {
rlm@79 5930 jQuery.offset.setOffset( this, options, i );
rlm@79 5931 });
rlm@79 5932 }
rlm@79 5933
rlm@79 5934 if ( !elem || !elem.ownerDocument ) {
rlm@79 5935 return null;
rlm@79 5936 }
rlm@79 5937
rlm@79 5938 if ( elem === elem.ownerDocument.body ) {
rlm@79 5939 return jQuery.offset.bodyOffset( elem );
rlm@79 5940 }
rlm@79 5941
rlm@79 5942 var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
rlm@79 5943 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
rlm@79 5944 top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
rlm@79 5945 left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
rlm@79 5946
rlm@79 5947 return { top: top, left: left };
rlm@79 5948 };
rlm@79 5949
rlm@79 5950 } else {
rlm@79 5951 jQuery.fn.offset = function( options ) {
rlm@79 5952 var elem = this[0];
rlm@79 5953
rlm@79 5954 if ( options ) {
rlm@79 5955 return this.each(function( i ) {
rlm@79 5956 jQuery.offset.setOffset( this, options, i );
rlm@79 5957 });
rlm@79 5958 }
rlm@79 5959
rlm@79 5960 if ( !elem || !elem.ownerDocument ) {
rlm@79 5961 return null;
rlm@79 5962 }
rlm@79 5963
rlm@79 5964 if ( elem === elem.ownerDocument.body ) {
rlm@79 5965 return jQuery.offset.bodyOffset( elem );
rlm@79 5966 }
rlm@79 5967
rlm@79 5968 jQuery.offset.initialize();
rlm@79 5969
rlm@79 5970 var offsetParent = elem.offsetParent, prevOffsetParent = elem,
rlm@79 5971 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
rlm@79 5972 body = doc.body, defaultView = doc.defaultView,
rlm@79 5973 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
rlm@79 5974 top = elem.offsetTop, left = elem.offsetLeft;
rlm@79 5975
rlm@79 5976 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
rlm@79 5977 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
rlm@79 5978 break;
rlm@79 5979 }
rlm@79 5980
rlm@79 5981 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
rlm@79 5982 top -= elem.scrollTop;
rlm@79 5983 left -= elem.scrollLeft;
rlm@79 5984
rlm@79 5985 if ( elem === offsetParent ) {
rlm@79 5986 top += elem.offsetTop;
rlm@79 5987 left += elem.offsetLeft;
rlm@79 5988
rlm@79 5989 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
rlm@79 5990 top += parseFloat( computedStyle.borderTopWidth ) || 0;
rlm@79 5991 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
rlm@79 5992 }
rlm@79 5993
rlm@79 5994 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
rlm@79 5995 }
rlm@79 5996
rlm@79 5997 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
rlm@79 5998 top += parseFloat( computedStyle.borderTopWidth ) || 0;
rlm@79 5999 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
rlm@79 6000 }
rlm@79 6001
rlm@79 6002 prevComputedStyle = computedStyle;
rlm@79 6003 }
rlm@79 6004
rlm@79 6005 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
rlm@79 6006 top += body.offsetTop;
rlm@79 6007 left += body.offsetLeft;
rlm@79 6008 }
rlm@79 6009
rlm@79 6010 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
rlm@79 6011 top += Math.max( docElem.scrollTop, body.scrollTop );
rlm@79 6012 left += Math.max( docElem.scrollLeft, body.scrollLeft );
rlm@79 6013 }
rlm@79 6014
rlm@79 6015 return { top: top, left: left };
rlm@79 6016 };
rlm@79 6017 }
rlm@79 6018
rlm@79 6019 jQuery.offset = {
rlm@79 6020 initialize: function() {
rlm@79 6021 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
rlm@79 6022 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
rlm@79 6023
rlm@79 6024 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
rlm@79 6025
rlm@79 6026 container.innerHTML = html;
rlm@79 6027 body.insertBefore( container, body.firstChild );
rlm@79 6028 innerDiv = container.firstChild;
rlm@79 6029 checkDiv = innerDiv.firstChild;
rlm@79 6030 td = innerDiv.nextSibling.firstChild.firstChild;
rlm@79 6031
rlm@79 6032 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
rlm@79 6033 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
rlm@79 6034
rlm@79 6035 checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
rlm@79 6036 // safari subtracts parent border width here which is 5px
rlm@79 6037 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
rlm@79 6038 checkDiv.style.position = checkDiv.style.top = "";
rlm@79 6039
rlm@79 6040 innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
rlm@79 6041 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
rlm@79 6042
rlm@79 6043 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
rlm@79 6044
rlm@79 6045 body.removeChild( container );
rlm@79 6046 body = container = innerDiv = checkDiv = table = td = null;
rlm@79 6047 jQuery.offset.initialize = jQuery.noop;
rlm@79 6048 },
rlm@79 6049
rlm@79 6050 bodyOffset: function( body ) {
rlm@79 6051 var top = body.offsetTop, left = body.offsetLeft;
rlm@79 6052
rlm@79 6053 jQuery.offset.initialize();
rlm@79 6054
rlm@79 6055 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
rlm@79 6056 top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
rlm@79 6057 left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
rlm@79 6058 }
rlm@79 6059
rlm@79 6060 return { top: top, left: left };
rlm@79 6061 },
rlm@79 6062
rlm@79 6063 setOffset: function( elem, options, i ) {
rlm@79 6064 // set position first, in-case top/left are set even on static elem
rlm@79 6065 if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
rlm@79 6066 elem.style.position = "relative";
rlm@79 6067 }
rlm@79 6068 var curElem = jQuery( elem ),
rlm@79 6069 curOffset = curElem.offset(),
rlm@79 6070 curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
rlm@79 6071 curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
rlm@79 6072
rlm@79 6073 if ( jQuery.isFunction( options ) ) {
rlm@79 6074 options = options.call( elem, i, curOffset );
rlm@79 6075 }
rlm@79 6076
rlm@79 6077 var props = {
rlm@79 6078 top: (options.top - curOffset.top) + curTop,
rlm@79 6079 left: (options.left - curOffset.left) + curLeft
rlm@79 6080 };
rlm@79 6081
rlm@79 6082 if ( "using" in options ) {
rlm@79 6083 options.using.call( elem, props );
rlm@79 6084 } else {
rlm@79 6085 curElem.css( props );
rlm@79 6086 }
rlm@79 6087 }
rlm@79 6088 };
rlm@79 6089
rlm@79 6090
rlm@79 6091 jQuery.fn.extend({
rlm@79 6092 position: function() {
rlm@79 6093 if ( !this[0] ) {
rlm@79 6094 return null;
rlm@79 6095 }
rlm@79 6096
rlm@79 6097 var elem = this[0],
rlm@79 6098
rlm@79 6099 // Get *real* offsetParent
rlm@79 6100 offsetParent = this.offsetParent(),
rlm@79 6101
rlm@79 6102 // Get correct offsets
rlm@79 6103 offset = this.offset(),
rlm@79 6104 parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
rlm@79 6105
rlm@79 6106 // Subtract element margins
rlm@79 6107 // note: when an element has margin: auto the offsetLeft and marginLeft
rlm@79 6108 // are the same in Safari causing offset.left to incorrectly be 0
rlm@79 6109 offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
rlm@79 6110 offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
rlm@79 6111
rlm@79 6112 // Add offsetParent borders
rlm@79 6113 parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
rlm@79 6114 parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
rlm@79 6115
rlm@79 6116 // Subtract the two offsets
rlm@79 6117 return {
rlm@79 6118 top: offset.top - parentOffset.top,
rlm@79 6119 left: offset.left - parentOffset.left
rlm@79 6120 };
rlm@79 6121 },
rlm@79 6122
rlm@79 6123 offsetParent: function() {
rlm@79 6124 return this.map(function() {
rlm@79 6125 var offsetParent = this.offsetParent || document.body;
rlm@79 6126 while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
rlm@79 6127 offsetParent = offsetParent.offsetParent;
rlm@79 6128 }
rlm@79 6129 return offsetParent;
rlm@79 6130 });
rlm@79 6131 }
rlm@79 6132 });
rlm@79 6133
rlm@79 6134
rlm@79 6135 // Create scrollLeft and scrollTop methods
rlm@79 6136 jQuery.each( ["Left", "Top"], function( i, name ) {
rlm@79 6137 var method = "scroll" + name;
rlm@79 6138
rlm@79 6139 jQuery.fn[ method ] = function(val) {
rlm@79 6140 var elem = this[0], win;
rlm@79 6141
rlm@79 6142 if ( !elem ) {
rlm@79 6143 return null;
rlm@79 6144 }
rlm@79 6145
rlm@79 6146 if ( val !== undefined ) {
rlm@79 6147 // Set the scroll offset
rlm@79 6148 return this.each(function() {
rlm@79 6149 win = getWindow( this );
rlm@79 6150
rlm@79 6151 if ( win ) {
rlm@79 6152 win.scrollTo(
rlm@79 6153 !i ? val : jQuery(win).scrollLeft(),
rlm@79 6154 i ? val : jQuery(win).scrollTop()
rlm@79 6155 );
rlm@79 6156
rlm@79 6157 } else {
rlm@79 6158 this[ method ] = val;
rlm@79 6159 }
rlm@79 6160 });
rlm@79 6161 } else {
rlm@79 6162 win = getWindow( elem );
rlm@79 6163
rlm@79 6164 // Return the scroll offset
rlm@79 6165 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
rlm@79 6166 jQuery.support.boxModel && win.document.documentElement[ method ] ||
rlm@79 6167 win.document.body[ method ] :
rlm@79 6168 elem[ method ];
rlm@79 6169 }
rlm@79 6170 };
rlm@79 6171 });
rlm@79 6172
rlm@79 6173 function getWindow( elem ) {
rlm@79 6174 return ("scrollTo" in elem && elem.document) ?
rlm@79 6175 elem :
rlm@79 6176 elem.nodeType === 9 ?
rlm@79 6177 elem.defaultView || elem.parentWindow :
rlm@79 6178 false;
rlm@79 6179 }
rlm@79 6180 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
rlm@79 6181 jQuery.each([ "Height", "Width" ], function( i, name ) {
rlm@79 6182
rlm@79 6183 var type = name.toLowerCase();
rlm@79 6184
rlm@79 6185 // innerHeight and innerWidth
rlm@79 6186 jQuery.fn["inner" + name] = function() {
rlm@79 6187 return this[0] ?
rlm@79 6188 jQuery.css( this[0], type, false, "padding" ) :
rlm@79 6189 null;
rlm@79 6190 };
rlm@79 6191
rlm@79 6192 // outerHeight and outerWidth
rlm@79 6193 jQuery.fn["outer" + name] = function( margin ) {
rlm@79 6194 return this[0] ?
rlm@79 6195 jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
rlm@79 6196 null;
rlm@79 6197 };
rlm@79 6198
rlm@79 6199 jQuery.fn[ type ] = function( size ) {
rlm@79 6200 // Get window width or height
rlm@79 6201 var elem = this[0];
rlm@79 6202 if ( !elem ) {
rlm@79 6203 return size == null ? null : this;
rlm@79 6204 }
rlm@79 6205
rlm@79 6206 if ( jQuery.isFunction( size ) ) {
rlm@79 6207 return this.each(function( i ) {
rlm@79 6208 var self = jQuery( this );
rlm@79 6209 self[ type ]( size.call( this, i, self[ type ]() ) );
rlm@79 6210 });
rlm@79 6211 }
rlm@79 6212
rlm@79 6213 return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
rlm@79 6214 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
rlm@79 6215 elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
rlm@79 6216 elem.document.body[ "client" + name ] :
rlm@79 6217
rlm@79 6218 // Get document width or height
rlm@79 6219 (elem.nodeType === 9) ? // is it a document
rlm@79 6220 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
rlm@79 6221 Math.max(
rlm@79 6222 elem.documentElement["client" + name],
rlm@79 6223 elem.body["scroll" + name], elem.documentElement["scroll" + name],
rlm@79 6224 elem.body["offset" + name], elem.documentElement["offset" + name]
rlm@79 6225 ) :
rlm@79 6226
rlm@79 6227 // Get or set width or height on the element
rlm@79 6228 size === undefined ?
rlm@79 6229 // Get width or height on the element
rlm@79 6230 jQuery.css( elem, type ) :
rlm@79 6231
rlm@79 6232 // Set the width or height on the element (default to pixels if value is unitless)
rlm@79 6233 this.css( type, typeof size === "string" ? size : size + "px" );
rlm@79 6234 };
rlm@79 6235
rlm@79 6236 });
rlm@79 6237 // Expose jQuery to the global object
rlm@79 6238 window.jQuery = window.$ = jQuery;
rlm@79 6239
rlm@79 6240 })(window);