Thu, 04 Jun 2015 14:50:33 +0200
Genesis of lecture sources for Droidcon Berlin 2015 in Postbahnhof.
michael@0 | 1 | /*! |
michael@0 | 2 | * jQuery JavaScript Library v2.1.1 |
michael@0 | 3 | * http://jquery.com/ |
michael@0 | 4 | * |
michael@0 | 5 | * Includes Sizzle.js |
michael@0 | 6 | * http://sizzlejs.com/ |
michael@0 | 7 | * |
michael@0 | 8 | * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors |
michael@0 | 9 | * Released under the MIT license |
michael@0 | 10 | * http://jquery.org/license |
michael@0 | 11 | * |
michael@0 | 12 | * Date: 2014-05-01T17:11Z |
michael@0 | 13 | */ |
michael@0 | 14 | |
michael@0 | 15 | (function( global, factory ) { |
michael@0 | 16 | |
michael@0 | 17 | if ( typeof module === "object" && typeof module.exports === "object" ) { |
michael@0 | 18 | // For CommonJS and CommonJS-like environments where a proper window is present, |
michael@0 | 19 | // execute the factory and get jQuery |
michael@0 | 20 | // For environments that do not inherently posses a window with a document |
michael@0 | 21 | // (such as Node.js), expose a jQuery-making factory as module.exports |
michael@0 | 22 | // This accentuates the need for the creation of a real window |
michael@0 | 23 | // e.g. var jQuery = require("jquery")(window); |
michael@0 | 24 | // See ticket #14549 for more info |
michael@0 | 25 | module.exports = global.document ? |
michael@0 | 26 | factory( global, true ) : |
michael@0 | 27 | function( w ) { |
michael@0 | 28 | if ( !w.document ) { |
michael@0 | 29 | throw new Error( "jQuery requires a window with a document" ); |
michael@0 | 30 | } |
michael@0 | 31 | return factory( w ); |
michael@0 | 32 | }; |
michael@0 | 33 | } else { |
michael@0 | 34 | factory( global ); |
michael@0 | 35 | } |
michael@0 | 36 | |
michael@0 | 37 | // Pass this if window is not defined yet |
michael@0 | 38 | }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { |
michael@0 | 39 | |
michael@0 | 40 | // Can't do this because several apps including ASP.NET trace |
michael@0 | 41 | // the stack via arguments.caller.callee and Firefox dies if |
michael@0 | 42 | // you try to trace through "use strict" call chains. (#13335) |
michael@0 | 43 | // Support: Firefox 18+ |
michael@0 | 44 | // |
michael@0 | 45 | |
michael@0 | 46 | var arr = []; |
michael@0 | 47 | |
michael@0 | 48 | var slice = arr.slice; |
michael@0 | 49 | |
michael@0 | 50 | var concat = arr.concat; |
michael@0 | 51 | |
michael@0 | 52 | var push = arr.push; |
michael@0 | 53 | |
michael@0 | 54 | var indexOf = arr.indexOf; |
michael@0 | 55 | |
michael@0 | 56 | var class2type = {}; |
michael@0 | 57 | |
michael@0 | 58 | var toString = class2type.toString; |
michael@0 | 59 | |
michael@0 | 60 | var hasOwn = class2type.hasOwnProperty; |
michael@0 | 61 | |
michael@0 | 62 | var support = {}; |
michael@0 | 63 | |
michael@0 | 64 | |
michael@0 | 65 | |
michael@0 | 66 | var |
michael@0 | 67 | // Use the correct document accordingly with window argument (sandbox) |
michael@0 | 68 | document = window.document, |
michael@0 | 69 | |
michael@0 | 70 | version = "2.1.1", |
michael@0 | 71 | |
michael@0 | 72 | // Define a local copy of jQuery |
michael@0 | 73 | jQuery = function( selector, context ) { |
michael@0 | 74 | // The jQuery object is actually just the init constructor 'enhanced' |
michael@0 | 75 | // Need init if jQuery is called (just allow error to be thrown if not included) |
michael@0 | 76 | return new jQuery.fn.init( selector, context ); |
michael@0 | 77 | }, |
michael@0 | 78 | |
michael@0 | 79 | // Support: Android<4.1 |
michael@0 | 80 | // Make sure we trim BOM and NBSP |
michael@0 | 81 | rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, |
michael@0 | 82 | |
michael@0 | 83 | // Matches dashed string for camelizing |
michael@0 | 84 | rmsPrefix = /^-ms-/, |
michael@0 | 85 | rdashAlpha = /-([\da-z])/gi, |
michael@0 | 86 | |
michael@0 | 87 | // Used by jQuery.camelCase as callback to replace() |
michael@0 | 88 | fcamelCase = function( all, letter ) { |
michael@0 | 89 | return letter.toUpperCase(); |
michael@0 | 90 | }; |
michael@0 | 91 | |
michael@0 | 92 | jQuery.fn = jQuery.prototype = { |
michael@0 | 93 | // The current version of jQuery being used |
michael@0 | 94 | jquery: version, |
michael@0 | 95 | |
michael@0 | 96 | constructor: jQuery, |
michael@0 | 97 | |
michael@0 | 98 | // Start with an empty selector |
michael@0 | 99 | selector: "", |
michael@0 | 100 | |
michael@0 | 101 | // The default length of a jQuery object is 0 |
michael@0 | 102 | length: 0, |
michael@0 | 103 | |
michael@0 | 104 | toArray: function() { |
michael@0 | 105 | return slice.call( this ); |
michael@0 | 106 | }, |
michael@0 | 107 | |
michael@0 | 108 | // Get the Nth element in the matched element set OR |
michael@0 | 109 | // Get the whole matched element set as a clean array |
michael@0 | 110 | get: function( num ) { |
michael@0 | 111 | return num != null ? |
michael@0 | 112 | |
michael@0 | 113 | // Return just the one element from the set |
michael@0 | 114 | ( num < 0 ? this[ num + this.length ] : this[ num ] ) : |
michael@0 | 115 | |
michael@0 | 116 | // Return all the elements in a clean array |
michael@0 | 117 | slice.call( this ); |
michael@0 | 118 | }, |
michael@0 | 119 | |
michael@0 | 120 | // Take an array of elements and push it onto the stack |
michael@0 | 121 | // (returning the new matched element set) |
michael@0 | 122 | pushStack: function( elems ) { |
michael@0 | 123 | |
michael@0 | 124 | // Build a new jQuery matched element set |
michael@0 | 125 | var ret = jQuery.merge( this.constructor(), elems ); |
michael@0 | 126 | |
michael@0 | 127 | // Add the old object onto the stack (as a reference) |
michael@0 | 128 | ret.prevObject = this; |
michael@0 | 129 | ret.context = this.context; |
michael@0 | 130 | |
michael@0 | 131 | // Return the newly-formed element set |
michael@0 | 132 | return ret; |
michael@0 | 133 | }, |
michael@0 | 134 | |
michael@0 | 135 | // Execute a callback for every element in the matched set. |
michael@0 | 136 | // (You can seed the arguments with an array of args, but this is |
michael@0 | 137 | // only used internally.) |
michael@0 | 138 | each: function( callback, args ) { |
michael@0 | 139 | return jQuery.each( this, callback, args ); |
michael@0 | 140 | }, |
michael@0 | 141 | |
michael@0 | 142 | map: function( callback ) { |
michael@0 | 143 | return this.pushStack( jQuery.map(this, function( elem, i ) { |
michael@0 | 144 | return callback.call( elem, i, elem ); |
michael@0 | 145 | })); |
michael@0 | 146 | }, |
michael@0 | 147 | |
michael@0 | 148 | slice: function() { |
michael@0 | 149 | return this.pushStack( slice.apply( this, arguments ) ); |
michael@0 | 150 | }, |
michael@0 | 151 | |
michael@0 | 152 | first: function() { |
michael@0 | 153 | return this.eq( 0 ); |
michael@0 | 154 | }, |
michael@0 | 155 | |
michael@0 | 156 | last: function() { |
michael@0 | 157 | return this.eq( -1 ); |
michael@0 | 158 | }, |
michael@0 | 159 | |
michael@0 | 160 | eq: function( i ) { |
michael@0 | 161 | var len = this.length, |
michael@0 | 162 | j = +i + ( i < 0 ? len : 0 ); |
michael@0 | 163 | return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); |
michael@0 | 164 | }, |
michael@0 | 165 | |
michael@0 | 166 | end: function() { |
michael@0 | 167 | return this.prevObject || this.constructor(null); |
michael@0 | 168 | }, |
michael@0 | 169 | |
michael@0 | 170 | // For internal use only. |
michael@0 | 171 | // Behaves like an Array's method, not like a jQuery method. |
michael@0 | 172 | push: push, |
michael@0 | 173 | sort: arr.sort, |
michael@0 | 174 | splice: arr.splice |
michael@0 | 175 | }; |
michael@0 | 176 | |
michael@0 | 177 | jQuery.extend = jQuery.fn.extend = function() { |
michael@0 | 178 | var options, name, src, copy, copyIsArray, clone, |
michael@0 | 179 | target = arguments[0] || {}, |
michael@0 | 180 | i = 1, |
michael@0 | 181 | length = arguments.length, |
michael@0 | 182 | deep = false; |
michael@0 | 183 | |
michael@0 | 184 | // Handle a deep copy situation |
michael@0 | 185 | if ( typeof target === "boolean" ) { |
michael@0 | 186 | deep = target; |
michael@0 | 187 | |
michael@0 | 188 | // skip the boolean and the target |
michael@0 | 189 | target = arguments[ i ] || {}; |
michael@0 | 190 | i++; |
michael@0 | 191 | } |
michael@0 | 192 | |
michael@0 | 193 | // Handle case when target is a string or something (possible in deep copy) |
michael@0 | 194 | if ( typeof target !== "object" && !jQuery.isFunction(target) ) { |
michael@0 | 195 | target = {}; |
michael@0 | 196 | } |
michael@0 | 197 | |
michael@0 | 198 | // extend jQuery itself if only one argument is passed |
michael@0 | 199 | if ( i === length ) { |
michael@0 | 200 | target = this; |
michael@0 | 201 | i--; |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | for ( ; i < length; i++ ) { |
michael@0 | 205 | // Only deal with non-null/undefined values |
michael@0 | 206 | if ( (options = arguments[ i ]) != null ) { |
michael@0 | 207 | // Extend the base object |
michael@0 | 208 | for ( name in options ) { |
michael@0 | 209 | src = target[ name ]; |
michael@0 | 210 | copy = options[ name ]; |
michael@0 | 211 | |
michael@0 | 212 | // Prevent never-ending loop |
michael@0 | 213 | if ( target === copy ) { |
michael@0 | 214 | continue; |
michael@0 | 215 | } |
michael@0 | 216 | |
michael@0 | 217 | // Recurse if we're merging plain objects or arrays |
michael@0 | 218 | if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { |
michael@0 | 219 | if ( copyIsArray ) { |
michael@0 | 220 | copyIsArray = false; |
michael@0 | 221 | clone = src && jQuery.isArray(src) ? src : []; |
michael@0 | 222 | |
michael@0 | 223 | } else { |
michael@0 | 224 | clone = src && jQuery.isPlainObject(src) ? src : {}; |
michael@0 | 225 | } |
michael@0 | 226 | |
michael@0 | 227 | // Never move original objects, clone them |
michael@0 | 228 | target[ name ] = jQuery.extend( deep, clone, copy ); |
michael@0 | 229 | |
michael@0 | 230 | // Don't bring in undefined values |
michael@0 | 231 | } else if ( copy !== undefined ) { |
michael@0 | 232 | target[ name ] = copy; |
michael@0 | 233 | } |
michael@0 | 234 | } |
michael@0 | 235 | } |
michael@0 | 236 | } |
michael@0 | 237 | |
michael@0 | 238 | // Return the modified object |
michael@0 | 239 | return target; |
michael@0 | 240 | }; |
michael@0 | 241 | |
michael@0 | 242 | jQuery.extend({ |
michael@0 | 243 | // Unique for each copy of jQuery on the page |
michael@0 | 244 | expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), |
michael@0 | 245 | |
michael@0 | 246 | // Assume jQuery is ready without the ready module |
michael@0 | 247 | isReady: true, |
michael@0 | 248 | |
michael@0 | 249 | error: function( msg ) { |
michael@0 | 250 | throw new Error( msg ); |
michael@0 | 251 | }, |
michael@0 | 252 | |
michael@0 | 253 | noop: function() {}, |
michael@0 | 254 | |
michael@0 | 255 | // See test/unit/core.js for details concerning isFunction. |
michael@0 | 256 | // Since version 1.3, DOM methods and functions like alert |
michael@0 | 257 | // aren't supported. They return false on IE (#2968). |
michael@0 | 258 | isFunction: function( obj ) { |
michael@0 | 259 | return jQuery.type(obj) === "function"; |
michael@0 | 260 | }, |
michael@0 | 261 | |
michael@0 | 262 | isArray: Array.isArray, |
michael@0 | 263 | |
michael@0 | 264 | isWindow: function( obj ) { |
michael@0 | 265 | return obj != null && obj === obj.window; |
michael@0 | 266 | }, |
michael@0 | 267 | |
michael@0 | 268 | isNumeric: function( obj ) { |
michael@0 | 269 | // parseFloat NaNs numeric-cast false positives (null|true|false|"") |
michael@0 | 270 | // ...but misinterprets leading-number strings, particularly hex literals ("0x...") |
michael@0 | 271 | // subtraction forces infinities to NaN |
michael@0 | 272 | return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; |
michael@0 | 273 | }, |
michael@0 | 274 | |
michael@0 | 275 | isPlainObject: function( obj ) { |
michael@0 | 276 | // Not plain objects: |
michael@0 | 277 | // - Any object or value whose internal [[Class]] property is not "[object Object]" |
michael@0 | 278 | // - DOM nodes |
michael@0 | 279 | // - window |
michael@0 | 280 | if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { |
michael@0 | 281 | return false; |
michael@0 | 282 | } |
michael@0 | 283 | |
michael@0 | 284 | if ( obj.constructor && |
michael@0 | 285 | !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { |
michael@0 | 286 | return false; |
michael@0 | 287 | } |
michael@0 | 288 | |
michael@0 | 289 | // If the function hasn't returned already, we're confident that |
michael@0 | 290 | // |obj| is a plain object, created by {} or constructed with new Object |
michael@0 | 291 | return true; |
michael@0 | 292 | }, |
michael@0 | 293 | |
michael@0 | 294 | isEmptyObject: function( obj ) { |
michael@0 | 295 | var name; |
michael@0 | 296 | for ( name in obj ) { |
michael@0 | 297 | return false; |
michael@0 | 298 | } |
michael@0 | 299 | return true; |
michael@0 | 300 | }, |
michael@0 | 301 | |
michael@0 | 302 | type: function( obj ) { |
michael@0 | 303 | if ( obj == null ) { |
michael@0 | 304 | return obj + ""; |
michael@0 | 305 | } |
michael@0 | 306 | // Support: Android < 4.0, iOS < 6 (functionish RegExp) |
michael@0 | 307 | return typeof obj === "object" || typeof obj === "function" ? |
michael@0 | 308 | class2type[ toString.call(obj) ] || "object" : |
michael@0 | 309 | typeof obj; |
michael@0 | 310 | }, |
michael@0 | 311 | |
michael@0 | 312 | // Evaluates a script in a global context |
michael@0 | 313 | globalEval: function( code ) { |
michael@0 | 314 | var script, |
michael@0 | 315 | indirect = eval; |
michael@0 | 316 | |
michael@0 | 317 | code = jQuery.trim( code ); |
michael@0 | 318 | |
michael@0 | 319 | if ( code ) { |
michael@0 | 320 | // If the code includes a valid, prologue position |
michael@0 | 321 | // strict mode pragma, execute code by injecting a |
michael@0 | 322 | // script tag into the document. |
michael@0 | 323 | if ( code.indexOf("use strict") === 1 ) { |
michael@0 | 324 | script = document.createElement("script"); |
michael@0 | 325 | script.text = code; |
michael@0 | 326 | document.head.appendChild( script ).parentNode.removeChild( script ); |
michael@0 | 327 | } else { |
michael@0 | 328 | // Otherwise, avoid the DOM node creation, insertion |
michael@0 | 329 | // and removal by using an indirect global eval |
michael@0 | 330 | indirect( code ); |
michael@0 | 331 | } |
michael@0 | 332 | } |
michael@0 | 333 | }, |
michael@0 | 334 | |
michael@0 | 335 | // Convert dashed to camelCase; used by the css and data modules |
michael@0 | 336 | // Microsoft forgot to hump their vendor prefix (#9572) |
michael@0 | 337 | camelCase: function( string ) { |
michael@0 | 338 | return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); |
michael@0 | 339 | }, |
michael@0 | 340 | |
michael@0 | 341 | nodeName: function( elem, name ) { |
michael@0 | 342 | return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); |
michael@0 | 343 | }, |
michael@0 | 344 | |
michael@0 | 345 | // args is for internal usage only |
michael@0 | 346 | each: function( obj, callback, args ) { |
michael@0 | 347 | var value, |
michael@0 | 348 | i = 0, |
michael@0 | 349 | length = obj.length, |
michael@0 | 350 | isArray = isArraylike( obj ); |
michael@0 | 351 | |
michael@0 | 352 | if ( args ) { |
michael@0 | 353 | if ( isArray ) { |
michael@0 | 354 | for ( ; i < length; i++ ) { |
michael@0 | 355 | value = callback.apply( obj[ i ], args ); |
michael@0 | 356 | |
michael@0 | 357 | if ( value === false ) { |
michael@0 | 358 | break; |
michael@0 | 359 | } |
michael@0 | 360 | } |
michael@0 | 361 | } else { |
michael@0 | 362 | for ( i in obj ) { |
michael@0 | 363 | value = callback.apply( obj[ i ], args ); |
michael@0 | 364 | |
michael@0 | 365 | if ( value === false ) { |
michael@0 | 366 | break; |
michael@0 | 367 | } |
michael@0 | 368 | } |
michael@0 | 369 | } |
michael@0 | 370 | |
michael@0 | 371 | // A special, fast, case for the most common use of each |
michael@0 | 372 | } else { |
michael@0 | 373 | if ( isArray ) { |
michael@0 | 374 | for ( ; i < length; i++ ) { |
michael@0 | 375 | value = callback.call( obj[ i ], i, obj[ i ] ); |
michael@0 | 376 | |
michael@0 | 377 | if ( value === false ) { |
michael@0 | 378 | break; |
michael@0 | 379 | } |
michael@0 | 380 | } |
michael@0 | 381 | } else { |
michael@0 | 382 | for ( i in obj ) { |
michael@0 | 383 | value = callback.call( obj[ i ], i, obj[ i ] ); |
michael@0 | 384 | |
michael@0 | 385 | if ( value === false ) { |
michael@0 | 386 | break; |
michael@0 | 387 | } |
michael@0 | 388 | } |
michael@0 | 389 | } |
michael@0 | 390 | } |
michael@0 | 391 | |
michael@0 | 392 | return obj; |
michael@0 | 393 | }, |
michael@0 | 394 | |
michael@0 | 395 | // Support: Android<4.1 |
michael@0 | 396 | trim: function( text ) { |
michael@0 | 397 | return text == null ? |
michael@0 | 398 | "" : |
michael@0 | 399 | ( text + "" ).replace( rtrim, "" ); |
michael@0 | 400 | }, |
michael@0 | 401 | |
michael@0 | 402 | // results is for internal usage only |
michael@0 | 403 | makeArray: function( arr, results ) { |
michael@0 | 404 | var ret = results || []; |
michael@0 | 405 | |
michael@0 | 406 | if ( arr != null ) { |
michael@0 | 407 | if ( isArraylike( Object(arr) ) ) { |
michael@0 | 408 | jQuery.merge( ret, |
michael@0 | 409 | typeof arr === "string" ? |
michael@0 | 410 | [ arr ] : arr |
michael@0 | 411 | ); |
michael@0 | 412 | } else { |
michael@0 | 413 | push.call( ret, arr ); |
michael@0 | 414 | } |
michael@0 | 415 | } |
michael@0 | 416 | |
michael@0 | 417 | return ret; |
michael@0 | 418 | }, |
michael@0 | 419 | |
michael@0 | 420 | inArray: function( elem, arr, i ) { |
michael@0 | 421 | return arr == null ? -1 : indexOf.call( arr, elem, i ); |
michael@0 | 422 | }, |
michael@0 | 423 | |
michael@0 | 424 | merge: function( first, second ) { |
michael@0 | 425 | var len = +second.length, |
michael@0 | 426 | j = 0, |
michael@0 | 427 | i = first.length; |
michael@0 | 428 | |
michael@0 | 429 | for ( ; j < len; j++ ) { |
michael@0 | 430 | first[ i++ ] = second[ j ]; |
michael@0 | 431 | } |
michael@0 | 432 | |
michael@0 | 433 | first.length = i; |
michael@0 | 434 | |
michael@0 | 435 | return first; |
michael@0 | 436 | }, |
michael@0 | 437 | |
michael@0 | 438 | grep: function( elems, callback, invert ) { |
michael@0 | 439 | var callbackInverse, |
michael@0 | 440 | matches = [], |
michael@0 | 441 | i = 0, |
michael@0 | 442 | length = elems.length, |
michael@0 | 443 | callbackExpect = !invert; |
michael@0 | 444 | |
michael@0 | 445 | // Go through the array, only saving the items |
michael@0 | 446 | // that pass the validator function |
michael@0 | 447 | for ( ; i < length; i++ ) { |
michael@0 | 448 | callbackInverse = !callback( elems[ i ], i ); |
michael@0 | 449 | if ( callbackInverse !== callbackExpect ) { |
michael@0 | 450 | matches.push( elems[ i ] ); |
michael@0 | 451 | } |
michael@0 | 452 | } |
michael@0 | 453 | |
michael@0 | 454 | return matches; |
michael@0 | 455 | }, |
michael@0 | 456 | |
michael@0 | 457 | // arg is for internal usage only |
michael@0 | 458 | map: function( elems, callback, arg ) { |
michael@0 | 459 | var value, |
michael@0 | 460 | i = 0, |
michael@0 | 461 | length = elems.length, |
michael@0 | 462 | isArray = isArraylike( elems ), |
michael@0 | 463 | ret = []; |
michael@0 | 464 | |
michael@0 | 465 | // Go through the array, translating each of the items to their new values |
michael@0 | 466 | if ( isArray ) { |
michael@0 | 467 | for ( ; i < length; i++ ) { |
michael@0 | 468 | value = callback( elems[ i ], i, arg ); |
michael@0 | 469 | |
michael@0 | 470 | if ( value != null ) { |
michael@0 | 471 | ret.push( value ); |
michael@0 | 472 | } |
michael@0 | 473 | } |
michael@0 | 474 | |
michael@0 | 475 | // Go through every key on the object, |
michael@0 | 476 | } else { |
michael@0 | 477 | for ( i in elems ) { |
michael@0 | 478 | value = callback( elems[ i ], i, arg ); |
michael@0 | 479 | |
michael@0 | 480 | if ( value != null ) { |
michael@0 | 481 | ret.push( value ); |
michael@0 | 482 | } |
michael@0 | 483 | } |
michael@0 | 484 | } |
michael@0 | 485 | |
michael@0 | 486 | // Flatten any nested arrays |
michael@0 | 487 | return concat.apply( [], ret ); |
michael@0 | 488 | }, |
michael@0 | 489 | |
michael@0 | 490 | // A global GUID counter for objects |
michael@0 | 491 | guid: 1, |
michael@0 | 492 | |
michael@0 | 493 | // Bind a function to a context, optionally partially applying any |
michael@0 | 494 | // arguments. |
michael@0 | 495 | proxy: function( fn, context ) { |
michael@0 | 496 | var tmp, args, proxy; |
michael@0 | 497 | |
michael@0 | 498 | if ( typeof context === "string" ) { |
michael@0 | 499 | tmp = fn[ context ]; |
michael@0 | 500 | context = fn; |
michael@0 | 501 | fn = tmp; |
michael@0 | 502 | } |
michael@0 | 503 | |
michael@0 | 504 | // Quick check to determine if target is callable, in the spec |
michael@0 | 505 | // this throws a TypeError, but we will just return undefined. |
michael@0 | 506 | if ( !jQuery.isFunction( fn ) ) { |
michael@0 | 507 | return undefined; |
michael@0 | 508 | } |
michael@0 | 509 | |
michael@0 | 510 | // Simulated bind |
michael@0 | 511 | args = slice.call( arguments, 2 ); |
michael@0 | 512 | proxy = function() { |
michael@0 | 513 | return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); |
michael@0 | 514 | }; |
michael@0 | 515 | |
michael@0 | 516 | // Set the guid of unique handler to the same of original handler, so it can be removed |
michael@0 | 517 | proxy.guid = fn.guid = fn.guid || jQuery.guid++; |
michael@0 | 518 | |
michael@0 | 519 | return proxy; |
michael@0 | 520 | }, |
michael@0 | 521 | |
michael@0 | 522 | now: Date.now, |
michael@0 | 523 | |
michael@0 | 524 | // jQuery.support is not used in Core but other projects attach their |
michael@0 | 525 | // properties to it so it needs to exist. |
michael@0 | 526 | support: support |
michael@0 | 527 | }); |
michael@0 | 528 | |
michael@0 | 529 | // Populate the class2type map |
michael@0 | 530 | jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { |
michael@0 | 531 | class2type[ "[object " + name + "]" ] = name.toLowerCase(); |
michael@0 | 532 | }); |
michael@0 | 533 | |
michael@0 | 534 | function isArraylike( obj ) { |
michael@0 | 535 | var length = obj.length, |
michael@0 | 536 | type = jQuery.type( obj ); |
michael@0 | 537 | |
michael@0 | 538 | if ( type === "function" || jQuery.isWindow( obj ) ) { |
michael@0 | 539 | return false; |
michael@0 | 540 | } |
michael@0 | 541 | |
michael@0 | 542 | if ( obj.nodeType === 1 && length ) { |
michael@0 | 543 | return true; |
michael@0 | 544 | } |
michael@0 | 545 | |
michael@0 | 546 | return type === "array" || length === 0 || |
michael@0 | 547 | typeof length === "number" && length > 0 && ( length - 1 ) in obj; |
michael@0 | 548 | } |
michael@0 | 549 | var Sizzle = |
michael@0 | 550 | /*! |
michael@0 | 551 | * Sizzle CSS Selector Engine v1.10.19 |
michael@0 | 552 | * http://sizzlejs.com/ |
michael@0 | 553 | * |
michael@0 | 554 | * Copyright 2013 jQuery Foundation, Inc. and other contributors |
michael@0 | 555 | * Released under the MIT license |
michael@0 | 556 | * http://jquery.org/license |
michael@0 | 557 | * |
michael@0 | 558 | * Date: 2014-04-18 |
michael@0 | 559 | */ |
michael@0 | 560 | (function( window ) { |
michael@0 | 561 | |
michael@0 | 562 | var i, |
michael@0 | 563 | support, |
michael@0 | 564 | Expr, |
michael@0 | 565 | getText, |
michael@0 | 566 | isXML, |
michael@0 | 567 | tokenize, |
michael@0 | 568 | compile, |
michael@0 | 569 | select, |
michael@0 | 570 | outermostContext, |
michael@0 | 571 | sortInput, |
michael@0 | 572 | hasDuplicate, |
michael@0 | 573 | |
michael@0 | 574 | // Local document vars |
michael@0 | 575 | setDocument, |
michael@0 | 576 | document, |
michael@0 | 577 | docElem, |
michael@0 | 578 | documentIsHTML, |
michael@0 | 579 | rbuggyQSA, |
michael@0 | 580 | rbuggyMatches, |
michael@0 | 581 | matches, |
michael@0 | 582 | contains, |
michael@0 | 583 | |
michael@0 | 584 | // Instance-specific data |
michael@0 | 585 | expando = "sizzle" + -(new Date()), |
michael@0 | 586 | preferredDoc = window.document, |
michael@0 | 587 | dirruns = 0, |
michael@0 | 588 | done = 0, |
michael@0 | 589 | classCache = createCache(), |
michael@0 | 590 | tokenCache = createCache(), |
michael@0 | 591 | compilerCache = createCache(), |
michael@0 | 592 | sortOrder = function( a, b ) { |
michael@0 | 593 | if ( a === b ) { |
michael@0 | 594 | hasDuplicate = true; |
michael@0 | 595 | } |
michael@0 | 596 | return 0; |
michael@0 | 597 | }, |
michael@0 | 598 | |
michael@0 | 599 | // General-purpose constants |
michael@0 | 600 | strundefined = typeof undefined, |
michael@0 | 601 | MAX_NEGATIVE = 1 << 31, |
michael@0 | 602 | |
michael@0 | 603 | // Instance methods |
michael@0 | 604 | hasOwn = ({}).hasOwnProperty, |
michael@0 | 605 | arr = [], |
michael@0 | 606 | pop = arr.pop, |
michael@0 | 607 | push_native = arr.push, |
michael@0 | 608 | push = arr.push, |
michael@0 | 609 | slice = arr.slice, |
michael@0 | 610 | // Use a stripped-down indexOf if we can't use a native one |
michael@0 | 611 | indexOf = arr.indexOf || function( elem ) { |
michael@0 | 612 | var i = 0, |
michael@0 | 613 | len = this.length; |
michael@0 | 614 | for ( ; i < len; i++ ) { |
michael@0 | 615 | if ( this[i] === elem ) { |
michael@0 | 616 | return i; |
michael@0 | 617 | } |
michael@0 | 618 | } |
michael@0 | 619 | return -1; |
michael@0 | 620 | }, |
michael@0 | 621 | |
michael@0 | 622 | booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", |
michael@0 | 623 | |
michael@0 | 624 | // Regular expressions |
michael@0 | 625 | |
michael@0 | 626 | // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace |
michael@0 | 627 | whitespace = "[\\x20\\t\\r\\n\\f]", |
michael@0 | 628 | // http://www.w3.org/TR/css3-syntax/#characters |
michael@0 | 629 | characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", |
michael@0 | 630 | |
michael@0 | 631 | // Loosely modeled on CSS identifier characters |
michael@0 | 632 | // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors |
michael@0 | 633 | // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier |
michael@0 | 634 | identifier = characterEncoding.replace( "w", "w#" ), |
michael@0 | 635 | |
michael@0 | 636 | // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors |
michael@0 | 637 | attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + |
michael@0 | 638 | // Operator (capture 2) |
michael@0 | 639 | "*([*^$|!~]?=)" + whitespace + |
michael@0 | 640 | // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" |
michael@0 | 641 | "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + |
michael@0 | 642 | "*\\]", |
michael@0 | 643 | |
michael@0 | 644 | pseudos = ":(" + characterEncoding + ")(?:\\((" + |
michael@0 | 645 | // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: |
michael@0 | 646 | // 1. quoted (capture 3; capture 4 or capture 5) |
michael@0 | 647 | "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + |
michael@0 | 648 | // 2. simple (capture 6) |
michael@0 | 649 | "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + |
michael@0 | 650 | // 3. anything else (capture 2) |
michael@0 | 651 | ".*" + |
michael@0 | 652 | ")\\)|)", |
michael@0 | 653 | |
michael@0 | 654 | // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter |
michael@0 | 655 | rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), |
michael@0 | 656 | |
michael@0 | 657 | rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), |
michael@0 | 658 | rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), |
michael@0 | 659 | |
michael@0 | 660 | rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), |
michael@0 | 661 | |
michael@0 | 662 | rpseudo = new RegExp( pseudos ), |
michael@0 | 663 | ridentifier = new RegExp( "^" + identifier + "$" ), |
michael@0 | 664 | |
michael@0 | 665 | matchExpr = { |
michael@0 | 666 | "ID": new RegExp( "^#(" + characterEncoding + ")" ), |
michael@0 | 667 | "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), |
michael@0 | 668 | "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), |
michael@0 | 669 | "ATTR": new RegExp( "^" + attributes ), |
michael@0 | 670 | "PSEUDO": new RegExp( "^" + pseudos ), |
michael@0 | 671 | "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + |
michael@0 | 672 | "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + |
michael@0 | 673 | "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), |
michael@0 | 674 | "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), |
michael@0 | 675 | // For use in libraries implementing .is() |
michael@0 | 676 | // We use this for POS matching in `select` |
michael@0 | 677 | "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + |
michael@0 | 678 | whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) |
michael@0 | 679 | }, |
michael@0 | 680 | |
michael@0 | 681 | rinputs = /^(?:input|select|textarea|button)$/i, |
michael@0 | 682 | rheader = /^h\d$/i, |
michael@0 | 683 | |
michael@0 | 684 | rnative = /^[^{]+\{\s*\[native \w/, |
michael@0 | 685 | |
michael@0 | 686 | // Easily-parseable/retrievable ID or TAG or CLASS selectors |
michael@0 | 687 | rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, |
michael@0 | 688 | |
michael@0 | 689 | rsibling = /[+~]/, |
michael@0 | 690 | rescape = /'|\\/g, |
michael@0 | 691 | |
michael@0 | 692 | // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters |
michael@0 | 693 | runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), |
michael@0 | 694 | funescape = function( _, escaped, escapedWhitespace ) { |
michael@0 | 695 | var high = "0x" + escaped - 0x10000; |
michael@0 | 696 | // NaN means non-codepoint |
michael@0 | 697 | // Support: Firefox<24 |
michael@0 | 698 | // Workaround erroneous numeric interpretation of +"0x" |
michael@0 | 699 | return high !== high || escapedWhitespace ? |
michael@0 | 700 | escaped : |
michael@0 | 701 | high < 0 ? |
michael@0 | 702 | // BMP codepoint |
michael@0 | 703 | String.fromCharCode( high + 0x10000 ) : |
michael@0 | 704 | // Supplemental Plane codepoint (surrogate pair) |
michael@0 | 705 | String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); |
michael@0 | 706 | }; |
michael@0 | 707 | |
michael@0 | 708 | // Optimize for push.apply( _, NodeList ) |
michael@0 | 709 | try { |
michael@0 | 710 | push.apply( |
michael@0 | 711 | (arr = slice.call( preferredDoc.childNodes )), |
michael@0 | 712 | preferredDoc.childNodes |
michael@0 | 713 | ); |
michael@0 | 714 | // Support: Android<4.0 |
michael@0 | 715 | // Detect silently failing push.apply |
michael@0 | 716 | arr[ preferredDoc.childNodes.length ].nodeType; |
michael@0 | 717 | } catch ( e ) { |
michael@0 | 718 | push = { apply: arr.length ? |
michael@0 | 719 | |
michael@0 | 720 | // Leverage slice if possible |
michael@0 | 721 | function( target, els ) { |
michael@0 | 722 | push_native.apply( target, slice.call(els) ); |
michael@0 | 723 | } : |
michael@0 | 724 | |
michael@0 | 725 | // Support: IE<9 |
michael@0 | 726 | // Otherwise append directly |
michael@0 | 727 | function( target, els ) { |
michael@0 | 728 | var j = target.length, |
michael@0 | 729 | i = 0; |
michael@0 | 730 | // Can't trust NodeList.length |
michael@0 | 731 | while ( (target[j++] = els[i++]) ) {} |
michael@0 | 732 | target.length = j - 1; |
michael@0 | 733 | } |
michael@0 | 734 | }; |
michael@0 | 735 | } |
michael@0 | 736 | |
michael@0 | 737 | function Sizzle( selector, context, results, seed ) { |
michael@0 | 738 | var match, elem, m, nodeType, |
michael@0 | 739 | // QSA vars |
michael@0 | 740 | i, groups, old, nid, newContext, newSelector; |
michael@0 | 741 | |
michael@0 | 742 | if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { |
michael@0 | 743 | setDocument( context ); |
michael@0 | 744 | } |
michael@0 | 745 | |
michael@0 | 746 | context = context || document; |
michael@0 | 747 | results = results || []; |
michael@0 | 748 | |
michael@0 | 749 | if ( !selector || typeof selector !== "string" ) { |
michael@0 | 750 | return results; |
michael@0 | 751 | } |
michael@0 | 752 | |
michael@0 | 753 | if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { |
michael@0 | 754 | return []; |
michael@0 | 755 | } |
michael@0 | 756 | |
michael@0 | 757 | if ( documentIsHTML && !seed ) { |
michael@0 | 758 | |
michael@0 | 759 | // Shortcuts |
michael@0 | 760 | if ( (match = rquickExpr.exec( selector )) ) { |
michael@0 | 761 | // Speed-up: Sizzle("#ID") |
michael@0 | 762 | if ( (m = match[1]) ) { |
michael@0 | 763 | if ( nodeType === 9 ) { |
michael@0 | 764 | elem = context.getElementById( m ); |
michael@0 | 765 | // Check parentNode to catch when Blackberry 4.6 returns |
michael@0 | 766 | // nodes that are no longer in the document (jQuery #6963) |
michael@0 | 767 | if ( elem && elem.parentNode ) { |
michael@0 | 768 | // Handle the case where IE, Opera, and Webkit return items |
michael@0 | 769 | // by name instead of ID |
michael@0 | 770 | if ( elem.id === m ) { |
michael@0 | 771 | results.push( elem ); |
michael@0 | 772 | return results; |
michael@0 | 773 | } |
michael@0 | 774 | } else { |
michael@0 | 775 | return results; |
michael@0 | 776 | } |
michael@0 | 777 | } else { |
michael@0 | 778 | // Context is not a document |
michael@0 | 779 | if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && |
michael@0 | 780 | contains( context, elem ) && elem.id === m ) { |
michael@0 | 781 | results.push( elem ); |
michael@0 | 782 | return results; |
michael@0 | 783 | } |
michael@0 | 784 | } |
michael@0 | 785 | |
michael@0 | 786 | // Speed-up: Sizzle("TAG") |
michael@0 | 787 | } else if ( match[2] ) { |
michael@0 | 788 | push.apply( results, context.getElementsByTagName( selector ) ); |
michael@0 | 789 | return results; |
michael@0 | 790 | |
michael@0 | 791 | // Speed-up: Sizzle(".CLASS") |
michael@0 | 792 | } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { |
michael@0 | 793 | push.apply( results, context.getElementsByClassName( m ) ); |
michael@0 | 794 | return results; |
michael@0 | 795 | } |
michael@0 | 796 | } |
michael@0 | 797 | |
michael@0 | 798 | // QSA path |
michael@0 | 799 | if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { |
michael@0 | 800 | nid = old = expando; |
michael@0 | 801 | newContext = context; |
michael@0 | 802 | newSelector = nodeType === 9 && selector; |
michael@0 | 803 | |
michael@0 | 804 | // qSA works strangely on Element-rooted queries |
michael@0 | 805 | // We can work around this by specifying an extra ID on the root |
michael@0 | 806 | // and working up from there (Thanks to Andrew Dupont for the technique) |
michael@0 | 807 | // IE 8 doesn't work on object elements |
michael@0 | 808 | if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { |
michael@0 | 809 | groups = tokenize( selector ); |
michael@0 | 810 | |
michael@0 | 811 | if ( (old = context.getAttribute("id")) ) { |
michael@0 | 812 | nid = old.replace( rescape, "\\$&" ); |
michael@0 | 813 | } else { |
michael@0 | 814 | context.setAttribute( "id", nid ); |
michael@0 | 815 | } |
michael@0 | 816 | nid = "[id='" + nid + "'] "; |
michael@0 | 817 | |
michael@0 | 818 | i = groups.length; |
michael@0 | 819 | while ( i-- ) { |
michael@0 | 820 | groups[i] = nid + toSelector( groups[i] ); |
michael@0 | 821 | } |
michael@0 | 822 | newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; |
michael@0 | 823 | newSelector = groups.join(","); |
michael@0 | 824 | } |
michael@0 | 825 | |
michael@0 | 826 | if ( newSelector ) { |
michael@0 | 827 | try { |
michael@0 | 828 | push.apply( results, |
michael@0 | 829 | newContext.querySelectorAll( newSelector ) |
michael@0 | 830 | ); |
michael@0 | 831 | return results; |
michael@0 | 832 | } catch(qsaError) { |
michael@0 | 833 | } finally { |
michael@0 | 834 | if ( !old ) { |
michael@0 | 835 | context.removeAttribute("id"); |
michael@0 | 836 | } |
michael@0 | 837 | } |
michael@0 | 838 | } |
michael@0 | 839 | } |
michael@0 | 840 | } |
michael@0 | 841 | |
michael@0 | 842 | // All others |
michael@0 | 843 | return select( selector.replace( rtrim, "$1" ), context, results, seed ); |
michael@0 | 844 | } |
michael@0 | 845 | |
michael@0 | 846 | /** |
michael@0 | 847 | * Create key-value caches of limited size |
michael@0 | 848 | * @returns {Function(string, Object)} Returns the Object data after storing it on itself with |
michael@0 | 849 | * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) |
michael@0 | 850 | * deleting the oldest entry |
michael@0 | 851 | */ |
michael@0 | 852 | function createCache() { |
michael@0 | 853 | var keys = []; |
michael@0 | 854 | |
michael@0 | 855 | function cache( key, value ) { |
michael@0 | 856 | // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) |
michael@0 | 857 | if ( keys.push( key + " " ) > Expr.cacheLength ) { |
michael@0 | 858 | // Only keep the most recent entries |
michael@0 | 859 | delete cache[ keys.shift() ]; |
michael@0 | 860 | } |
michael@0 | 861 | return (cache[ key + " " ] = value); |
michael@0 | 862 | } |
michael@0 | 863 | return cache; |
michael@0 | 864 | } |
michael@0 | 865 | |
michael@0 | 866 | /** |
michael@0 | 867 | * Mark a function for special use by Sizzle |
michael@0 | 868 | * @param {Function} fn The function to mark |
michael@0 | 869 | */ |
michael@0 | 870 | function markFunction( fn ) { |
michael@0 | 871 | fn[ expando ] = true; |
michael@0 | 872 | return fn; |
michael@0 | 873 | } |
michael@0 | 874 | |
michael@0 | 875 | /** |
michael@0 | 876 | * Support testing using an element |
michael@0 | 877 | * @param {Function} fn Passed the created div and expects a boolean result |
michael@0 | 878 | */ |
michael@0 | 879 | function assert( fn ) { |
michael@0 | 880 | var div = document.createElement("div"); |
michael@0 | 881 | |
michael@0 | 882 | try { |
michael@0 | 883 | return !!fn( div ); |
michael@0 | 884 | } catch (e) { |
michael@0 | 885 | return false; |
michael@0 | 886 | } finally { |
michael@0 | 887 | // Remove from its parent by default |
michael@0 | 888 | if ( div.parentNode ) { |
michael@0 | 889 | div.parentNode.removeChild( div ); |
michael@0 | 890 | } |
michael@0 | 891 | // release memory in IE |
michael@0 | 892 | div = null; |
michael@0 | 893 | } |
michael@0 | 894 | } |
michael@0 | 895 | |
michael@0 | 896 | /** |
michael@0 | 897 | * Adds the same handler for all of the specified attrs |
michael@0 | 898 | * @param {String} attrs Pipe-separated list of attributes |
michael@0 | 899 | * @param {Function} handler The method that will be applied |
michael@0 | 900 | */ |
michael@0 | 901 | function addHandle( attrs, handler ) { |
michael@0 | 902 | var arr = attrs.split("|"), |
michael@0 | 903 | i = attrs.length; |
michael@0 | 904 | |
michael@0 | 905 | while ( i-- ) { |
michael@0 | 906 | Expr.attrHandle[ arr[i] ] = handler; |
michael@0 | 907 | } |
michael@0 | 908 | } |
michael@0 | 909 | |
michael@0 | 910 | /** |
michael@0 | 911 | * Checks document order of two siblings |
michael@0 | 912 | * @param {Element} a |
michael@0 | 913 | * @param {Element} b |
michael@0 | 914 | * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b |
michael@0 | 915 | */ |
michael@0 | 916 | function siblingCheck( a, b ) { |
michael@0 | 917 | var cur = b && a, |
michael@0 | 918 | diff = cur && a.nodeType === 1 && b.nodeType === 1 && |
michael@0 | 919 | ( ~b.sourceIndex || MAX_NEGATIVE ) - |
michael@0 | 920 | ( ~a.sourceIndex || MAX_NEGATIVE ); |
michael@0 | 921 | |
michael@0 | 922 | // Use IE sourceIndex if available on both nodes |
michael@0 | 923 | if ( diff ) { |
michael@0 | 924 | return diff; |
michael@0 | 925 | } |
michael@0 | 926 | |
michael@0 | 927 | // Check if b follows a |
michael@0 | 928 | if ( cur ) { |
michael@0 | 929 | while ( (cur = cur.nextSibling) ) { |
michael@0 | 930 | if ( cur === b ) { |
michael@0 | 931 | return -1; |
michael@0 | 932 | } |
michael@0 | 933 | } |
michael@0 | 934 | } |
michael@0 | 935 | |
michael@0 | 936 | return a ? 1 : -1; |
michael@0 | 937 | } |
michael@0 | 938 | |
michael@0 | 939 | /** |
michael@0 | 940 | * Returns a function to use in pseudos for input types |
michael@0 | 941 | * @param {String} type |
michael@0 | 942 | */ |
michael@0 | 943 | function createInputPseudo( type ) { |
michael@0 | 944 | return function( elem ) { |
michael@0 | 945 | var name = elem.nodeName.toLowerCase(); |
michael@0 | 946 | return name === "input" && elem.type === type; |
michael@0 | 947 | }; |
michael@0 | 948 | } |
michael@0 | 949 | |
michael@0 | 950 | /** |
michael@0 | 951 | * Returns a function to use in pseudos for buttons |
michael@0 | 952 | * @param {String} type |
michael@0 | 953 | */ |
michael@0 | 954 | function createButtonPseudo( type ) { |
michael@0 | 955 | return function( elem ) { |
michael@0 | 956 | var name = elem.nodeName.toLowerCase(); |
michael@0 | 957 | return (name === "input" || name === "button") && elem.type === type; |
michael@0 | 958 | }; |
michael@0 | 959 | } |
michael@0 | 960 | |
michael@0 | 961 | /** |
michael@0 | 962 | * Returns a function to use in pseudos for positionals |
michael@0 | 963 | * @param {Function} fn |
michael@0 | 964 | */ |
michael@0 | 965 | function createPositionalPseudo( fn ) { |
michael@0 | 966 | return markFunction(function( argument ) { |
michael@0 | 967 | argument = +argument; |
michael@0 | 968 | return markFunction(function( seed, matches ) { |
michael@0 | 969 | var j, |
michael@0 | 970 | matchIndexes = fn( [], seed.length, argument ), |
michael@0 | 971 | i = matchIndexes.length; |
michael@0 | 972 | |
michael@0 | 973 | // Match elements found at the specified indexes |
michael@0 | 974 | while ( i-- ) { |
michael@0 | 975 | if ( seed[ (j = matchIndexes[i]) ] ) { |
michael@0 | 976 | seed[j] = !(matches[j] = seed[j]); |
michael@0 | 977 | } |
michael@0 | 978 | } |
michael@0 | 979 | }); |
michael@0 | 980 | }); |
michael@0 | 981 | } |
michael@0 | 982 | |
michael@0 | 983 | /** |
michael@0 | 984 | * Checks a node for validity as a Sizzle context |
michael@0 | 985 | * @param {Element|Object=} context |
michael@0 | 986 | * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value |
michael@0 | 987 | */ |
michael@0 | 988 | function testContext( context ) { |
michael@0 | 989 | return context && typeof context.getElementsByTagName !== strundefined && context; |
michael@0 | 990 | } |
michael@0 | 991 | |
michael@0 | 992 | // Expose support vars for convenience |
michael@0 | 993 | support = Sizzle.support = {}; |
michael@0 | 994 | |
michael@0 | 995 | /** |
michael@0 | 996 | * Detects XML nodes |
michael@0 | 997 | * @param {Element|Object} elem An element or a document |
michael@0 | 998 | * @returns {Boolean} True iff elem is a non-HTML XML node |
michael@0 | 999 | */ |
michael@0 | 1000 | isXML = Sizzle.isXML = function( elem ) { |
michael@0 | 1001 | // documentElement is verified for cases where it doesn't yet exist |
michael@0 | 1002 | // (such as loading iframes in IE - #4833) |
michael@0 | 1003 | var documentElement = elem && (elem.ownerDocument || elem).documentElement; |
michael@0 | 1004 | return documentElement ? documentElement.nodeName !== "HTML" : false; |
michael@0 | 1005 | }; |
michael@0 | 1006 | |
michael@0 | 1007 | /** |
michael@0 | 1008 | * Sets document-related variables once based on the current document |
michael@0 | 1009 | * @param {Element|Object} [doc] An element or document object to use to set the document |
michael@0 | 1010 | * @returns {Object} Returns the current document |
michael@0 | 1011 | */ |
michael@0 | 1012 | setDocument = Sizzle.setDocument = function( node ) { |
michael@0 | 1013 | var hasCompare, |
michael@0 | 1014 | doc = node ? node.ownerDocument || node : preferredDoc, |
michael@0 | 1015 | parent = doc.defaultView; |
michael@0 | 1016 | |
michael@0 | 1017 | // If no document and documentElement is available, return |
michael@0 | 1018 | if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { |
michael@0 | 1019 | return document; |
michael@0 | 1020 | } |
michael@0 | 1021 | |
michael@0 | 1022 | // Set our document |
michael@0 | 1023 | document = doc; |
michael@0 | 1024 | docElem = doc.documentElement; |
michael@0 | 1025 | |
michael@0 | 1026 | // Support tests |
michael@0 | 1027 | documentIsHTML = !isXML( doc ); |
michael@0 | 1028 | |
michael@0 | 1029 | // Support: IE>8 |
michael@0 | 1030 | // If iframe document is assigned to "document" variable and if iframe has been reloaded, |
michael@0 | 1031 | // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 |
michael@0 | 1032 | // IE6-8 do not support the defaultView property so parent will be undefined |
michael@0 | 1033 | if ( parent && parent !== parent.top ) { |
michael@0 | 1034 | // IE11 does not have attachEvent, so all must suffer |
michael@0 | 1035 | if ( parent.addEventListener ) { |
michael@0 | 1036 | parent.addEventListener( "unload", function() { |
michael@0 | 1037 | setDocument(); |
michael@0 | 1038 | }, false ); |
michael@0 | 1039 | } else if ( parent.attachEvent ) { |
michael@0 | 1040 | parent.attachEvent( "onunload", function() { |
michael@0 | 1041 | setDocument(); |
michael@0 | 1042 | }); |
michael@0 | 1043 | } |
michael@0 | 1044 | } |
michael@0 | 1045 | |
michael@0 | 1046 | /* Attributes |
michael@0 | 1047 | ---------------------------------------------------------------------- */ |
michael@0 | 1048 | |
michael@0 | 1049 | // Support: IE<8 |
michael@0 | 1050 | // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) |
michael@0 | 1051 | support.attributes = assert(function( div ) { |
michael@0 | 1052 | div.className = "i"; |
michael@0 | 1053 | return !div.getAttribute("className"); |
michael@0 | 1054 | }); |
michael@0 | 1055 | |
michael@0 | 1056 | /* getElement(s)By* |
michael@0 | 1057 | ---------------------------------------------------------------------- */ |
michael@0 | 1058 | |
michael@0 | 1059 | // Check if getElementsByTagName("*") returns only elements |
michael@0 | 1060 | support.getElementsByTagName = assert(function( div ) { |
michael@0 | 1061 | div.appendChild( doc.createComment("") ); |
michael@0 | 1062 | return !div.getElementsByTagName("*").length; |
michael@0 | 1063 | }); |
michael@0 | 1064 | |
michael@0 | 1065 | // Check if getElementsByClassName can be trusted |
michael@0 | 1066 | support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { |
michael@0 | 1067 | div.innerHTML = "<div class='a'></div><div class='a i'></div>"; |
michael@0 | 1068 | |
michael@0 | 1069 | // Support: Safari<4 |
michael@0 | 1070 | // Catch class over-caching |
michael@0 | 1071 | div.firstChild.className = "i"; |
michael@0 | 1072 | // Support: Opera<10 |
michael@0 | 1073 | // Catch gEBCN failure to find non-leading classes |
michael@0 | 1074 | return div.getElementsByClassName("i").length === 2; |
michael@0 | 1075 | }); |
michael@0 | 1076 | |
michael@0 | 1077 | // Support: IE<10 |
michael@0 | 1078 | // Check if getElementById returns elements by name |
michael@0 | 1079 | // The broken getElementById methods don't pick up programatically-set names, |
michael@0 | 1080 | // so use a roundabout getElementsByName test |
michael@0 | 1081 | support.getById = assert(function( div ) { |
michael@0 | 1082 | docElem.appendChild( div ).id = expando; |
michael@0 | 1083 | return !doc.getElementsByName || !doc.getElementsByName( expando ).length; |
michael@0 | 1084 | }); |
michael@0 | 1085 | |
michael@0 | 1086 | // ID find and filter |
michael@0 | 1087 | if ( support.getById ) { |
michael@0 | 1088 | Expr.find["ID"] = function( id, context ) { |
michael@0 | 1089 | if ( typeof context.getElementById !== strundefined && documentIsHTML ) { |
michael@0 | 1090 | var m = context.getElementById( id ); |
michael@0 | 1091 | // Check parentNode to catch when Blackberry 4.6 returns |
michael@0 | 1092 | // nodes that are no longer in the document #6963 |
michael@0 | 1093 | return m && m.parentNode ? [ m ] : []; |
michael@0 | 1094 | } |
michael@0 | 1095 | }; |
michael@0 | 1096 | Expr.filter["ID"] = function( id ) { |
michael@0 | 1097 | var attrId = id.replace( runescape, funescape ); |
michael@0 | 1098 | return function( elem ) { |
michael@0 | 1099 | return elem.getAttribute("id") === attrId; |
michael@0 | 1100 | }; |
michael@0 | 1101 | }; |
michael@0 | 1102 | } else { |
michael@0 | 1103 | // Support: IE6/7 |
michael@0 | 1104 | // getElementById is not reliable as a find shortcut |
michael@0 | 1105 | delete Expr.find["ID"]; |
michael@0 | 1106 | |
michael@0 | 1107 | Expr.filter["ID"] = function( id ) { |
michael@0 | 1108 | var attrId = id.replace( runescape, funescape ); |
michael@0 | 1109 | return function( elem ) { |
michael@0 | 1110 | var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); |
michael@0 | 1111 | return node && node.value === attrId; |
michael@0 | 1112 | }; |
michael@0 | 1113 | }; |
michael@0 | 1114 | } |
michael@0 | 1115 | |
michael@0 | 1116 | // Tag |
michael@0 | 1117 | Expr.find["TAG"] = support.getElementsByTagName ? |
michael@0 | 1118 | function( tag, context ) { |
michael@0 | 1119 | if ( typeof context.getElementsByTagName !== strundefined ) { |
michael@0 | 1120 | return context.getElementsByTagName( tag ); |
michael@0 | 1121 | } |
michael@0 | 1122 | } : |
michael@0 | 1123 | function( tag, context ) { |
michael@0 | 1124 | var elem, |
michael@0 | 1125 | tmp = [], |
michael@0 | 1126 | i = 0, |
michael@0 | 1127 | results = context.getElementsByTagName( tag ); |
michael@0 | 1128 | |
michael@0 | 1129 | // Filter out possible comments |
michael@0 | 1130 | if ( tag === "*" ) { |
michael@0 | 1131 | while ( (elem = results[i++]) ) { |
michael@0 | 1132 | if ( elem.nodeType === 1 ) { |
michael@0 | 1133 | tmp.push( elem ); |
michael@0 | 1134 | } |
michael@0 | 1135 | } |
michael@0 | 1136 | |
michael@0 | 1137 | return tmp; |
michael@0 | 1138 | } |
michael@0 | 1139 | return results; |
michael@0 | 1140 | }; |
michael@0 | 1141 | |
michael@0 | 1142 | // Class |
michael@0 | 1143 | Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { |
michael@0 | 1144 | if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { |
michael@0 | 1145 | return context.getElementsByClassName( className ); |
michael@0 | 1146 | } |
michael@0 | 1147 | }; |
michael@0 | 1148 | |
michael@0 | 1149 | /* QSA/matchesSelector |
michael@0 | 1150 | ---------------------------------------------------------------------- */ |
michael@0 | 1151 | |
michael@0 | 1152 | // QSA and matchesSelector support |
michael@0 | 1153 | |
michael@0 | 1154 | // matchesSelector(:active) reports false when true (IE9/Opera 11.5) |
michael@0 | 1155 | rbuggyMatches = []; |
michael@0 | 1156 | |
michael@0 | 1157 | // qSa(:focus) reports false when true (Chrome 21) |
michael@0 | 1158 | // We allow this because of a bug in IE8/9 that throws an error |
michael@0 | 1159 | // whenever `document.activeElement` is accessed on an iframe |
michael@0 | 1160 | // So, we allow :focus to pass through QSA all the time to avoid the IE error |
michael@0 | 1161 | // See http://bugs.jquery.com/ticket/13378 |
michael@0 | 1162 | rbuggyQSA = []; |
michael@0 | 1163 | |
michael@0 | 1164 | if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { |
michael@0 | 1165 | // Build QSA regex |
michael@0 | 1166 | // Regex strategy adopted from Diego Perini |
michael@0 | 1167 | assert(function( div ) { |
michael@0 | 1168 | // Select is set to empty string on purpose |
michael@0 | 1169 | // This is to test IE's treatment of not explicitly |
michael@0 | 1170 | // setting a boolean content attribute, |
michael@0 | 1171 | // since its presence should be enough |
michael@0 | 1172 | // http://bugs.jquery.com/ticket/12359 |
michael@0 | 1173 | div.innerHTML = "<select msallowclip=''><option selected=''></option></select>"; |
michael@0 | 1174 | |
michael@0 | 1175 | // Support: IE8, Opera 11-12.16 |
michael@0 | 1176 | // Nothing should be selected when empty strings follow ^= or $= or *= |
michael@0 | 1177 | // The test attribute must be unknown in Opera but "safe" for WinRT |
michael@0 | 1178 | // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section |
michael@0 | 1179 | if ( div.querySelectorAll("[msallowclip^='']").length ) { |
michael@0 | 1180 | rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); |
michael@0 | 1181 | } |
michael@0 | 1182 | |
michael@0 | 1183 | // Support: IE8 |
michael@0 | 1184 | // Boolean attributes and "value" are not treated correctly |
michael@0 | 1185 | if ( !div.querySelectorAll("[selected]").length ) { |
michael@0 | 1186 | rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); |
michael@0 | 1187 | } |
michael@0 | 1188 | |
michael@0 | 1189 | // Webkit/Opera - :checked should return selected option elements |
michael@0 | 1190 | // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
michael@0 | 1191 | // IE8 throws error here and will not see later tests |
michael@0 | 1192 | if ( !div.querySelectorAll(":checked").length ) { |
michael@0 | 1193 | rbuggyQSA.push(":checked"); |
michael@0 | 1194 | } |
michael@0 | 1195 | }); |
michael@0 | 1196 | |
michael@0 | 1197 | assert(function( div ) { |
michael@0 | 1198 | // Support: Windows 8 Native Apps |
michael@0 | 1199 | // The type and name attributes are restricted during .innerHTML assignment |
michael@0 | 1200 | var input = doc.createElement("input"); |
michael@0 | 1201 | input.setAttribute( "type", "hidden" ); |
michael@0 | 1202 | div.appendChild( input ).setAttribute( "name", "D" ); |
michael@0 | 1203 | |
michael@0 | 1204 | // Support: IE8 |
michael@0 | 1205 | // Enforce case-sensitivity of name attribute |
michael@0 | 1206 | if ( div.querySelectorAll("[name=d]").length ) { |
michael@0 | 1207 | rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); |
michael@0 | 1208 | } |
michael@0 | 1209 | |
michael@0 | 1210 | // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) |
michael@0 | 1211 | // IE8 throws error here and will not see later tests |
michael@0 | 1212 | if ( !div.querySelectorAll(":enabled").length ) { |
michael@0 | 1213 | rbuggyQSA.push( ":enabled", ":disabled" ); |
michael@0 | 1214 | } |
michael@0 | 1215 | |
michael@0 | 1216 | // Opera 10-11 does not throw on post-comma invalid pseudos |
michael@0 | 1217 | div.querySelectorAll("*,:x"); |
michael@0 | 1218 | rbuggyQSA.push(",.*:"); |
michael@0 | 1219 | }); |
michael@0 | 1220 | } |
michael@0 | 1221 | |
michael@0 | 1222 | if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || |
michael@0 | 1223 | docElem.webkitMatchesSelector || |
michael@0 | 1224 | docElem.mozMatchesSelector || |
michael@0 | 1225 | docElem.oMatchesSelector || |
michael@0 | 1226 | docElem.msMatchesSelector) )) ) { |
michael@0 | 1227 | |
michael@0 | 1228 | assert(function( div ) { |
michael@0 | 1229 | // Check to see if it's possible to do matchesSelector |
michael@0 | 1230 | // on a disconnected node (IE 9) |
michael@0 | 1231 | support.disconnectedMatch = matches.call( div, "div" ); |
michael@0 | 1232 | |
michael@0 | 1233 | // This should fail with an exception |
michael@0 | 1234 | // Gecko does not error, returns false instead |
michael@0 | 1235 | matches.call( div, "[s!='']:x" ); |
michael@0 | 1236 | rbuggyMatches.push( "!=", pseudos ); |
michael@0 | 1237 | }); |
michael@0 | 1238 | } |
michael@0 | 1239 | |
michael@0 | 1240 | rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); |
michael@0 | 1241 | rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); |
michael@0 | 1242 | |
michael@0 | 1243 | /* Contains |
michael@0 | 1244 | ---------------------------------------------------------------------- */ |
michael@0 | 1245 | hasCompare = rnative.test( docElem.compareDocumentPosition ); |
michael@0 | 1246 | |
michael@0 | 1247 | // Element contains another |
michael@0 | 1248 | // Purposefully does not implement inclusive descendent |
michael@0 | 1249 | // As in, an element does not contain itself |
michael@0 | 1250 | contains = hasCompare || rnative.test( docElem.contains ) ? |
michael@0 | 1251 | function( a, b ) { |
michael@0 | 1252 | var adown = a.nodeType === 9 ? a.documentElement : a, |
michael@0 | 1253 | bup = b && b.parentNode; |
michael@0 | 1254 | return a === bup || !!( bup && bup.nodeType === 1 && ( |
michael@0 | 1255 | adown.contains ? |
michael@0 | 1256 | adown.contains( bup ) : |
michael@0 | 1257 | a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 |
michael@0 | 1258 | )); |
michael@0 | 1259 | } : |
michael@0 | 1260 | function( a, b ) { |
michael@0 | 1261 | if ( b ) { |
michael@0 | 1262 | while ( (b = b.parentNode) ) { |
michael@0 | 1263 | if ( b === a ) { |
michael@0 | 1264 | return true; |
michael@0 | 1265 | } |
michael@0 | 1266 | } |
michael@0 | 1267 | } |
michael@0 | 1268 | return false; |
michael@0 | 1269 | }; |
michael@0 | 1270 | |
michael@0 | 1271 | /* Sorting |
michael@0 | 1272 | ---------------------------------------------------------------------- */ |
michael@0 | 1273 | |
michael@0 | 1274 | // Document order sorting |
michael@0 | 1275 | sortOrder = hasCompare ? |
michael@0 | 1276 | function( a, b ) { |
michael@0 | 1277 | |
michael@0 | 1278 | // Flag for duplicate removal |
michael@0 | 1279 | if ( a === b ) { |
michael@0 | 1280 | hasDuplicate = true; |
michael@0 | 1281 | return 0; |
michael@0 | 1282 | } |
michael@0 | 1283 | |
michael@0 | 1284 | // Sort on method existence if only one input has compareDocumentPosition |
michael@0 | 1285 | var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; |
michael@0 | 1286 | if ( compare ) { |
michael@0 | 1287 | return compare; |
michael@0 | 1288 | } |
michael@0 | 1289 | |
michael@0 | 1290 | // Calculate position if both inputs belong to the same document |
michael@0 | 1291 | compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? |
michael@0 | 1292 | a.compareDocumentPosition( b ) : |
michael@0 | 1293 | |
michael@0 | 1294 | // Otherwise we know they are disconnected |
michael@0 | 1295 | 1; |
michael@0 | 1296 | |
michael@0 | 1297 | // Disconnected nodes |
michael@0 | 1298 | if ( compare & 1 || |
michael@0 | 1299 | (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { |
michael@0 | 1300 | |
michael@0 | 1301 | // Choose the first element that is related to our preferred document |
michael@0 | 1302 | if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { |
michael@0 | 1303 | return -1; |
michael@0 | 1304 | } |
michael@0 | 1305 | if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { |
michael@0 | 1306 | return 1; |
michael@0 | 1307 | } |
michael@0 | 1308 | |
michael@0 | 1309 | // Maintain original order |
michael@0 | 1310 | return sortInput ? |
michael@0 | 1311 | ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : |
michael@0 | 1312 | 0; |
michael@0 | 1313 | } |
michael@0 | 1314 | |
michael@0 | 1315 | return compare & 4 ? -1 : 1; |
michael@0 | 1316 | } : |
michael@0 | 1317 | function( a, b ) { |
michael@0 | 1318 | // Exit early if the nodes are identical |
michael@0 | 1319 | if ( a === b ) { |
michael@0 | 1320 | hasDuplicate = true; |
michael@0 | 1321 | return 0; |
michael@0 | 1322 | } |
michael@0 | 1323 | |
michael@0 | 1324 | var cur, |
michael@0 | 1325 | i = 0, |
michael@0 | 1326 | aup = a.parentNode, |
michael@0 | 1327 | bup = b.parentNode, |
michael@0 | 1328 | ap = [ a ], |
michael@0 | 1329 | bp = [ b ]; |
michael@0 | 1330 | |
michael@0 | 1331 | // Parentless nodes are either documents or disconnected |
michael@0 | 1332 | if ( !aup || !bup ) { |
michael@0 | 1333 | return a === doc ? -1 : |
michael@0 | 1334 | b === doc ? 1 : |
michael@0 | 1335 | aup ? -1 : |
michael@0 | 1336 | bup ? 1 : |
michael@0 | 1337 | sortInput ? |
michael@0 | 1338 | ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : |
michael@0 | 1339 | 0; |
michael@0 | 1340 | |
michael@0 | 1341 | // If the nodes are siblings, we can do a quick check |
michael@0 | 1342 | } else if ( aup === bup ) { |
michael@0 | 1343 | return siblingCheck( a, b ); |
michael@0 | 1344 | } |
michael@0 | 1345 | |
michael@0 | 1346 | // Otherwise we need full lists of their ancestors for comparison |
michael@0 | 1347 | cur = a; |
michael@0 | 1348 | while ( (cur = cur.parentNode) ) { |
michael@0 | 1349 | ap.unshift( cur ); |
michael@0 | 1350 | } |
michael@0 | 1351 | cur = b; |
michael@0 | 1352 | while ( (cur = cur.parentNode) ) { |
michael@0 | 1353 | bp.unshift( cur ); |
michael@0 | 1354 | } |
michael@0 | 1355 | |
michael@0 | 1356 | // Walk down the tree looking for a discrepancy |
michael@0 | 1357 | while ( ap[i] === bp[i] ) { |
michael@0 | 1358 | i++; |
michael@0 | 1359 | } |
michael@0 | 1360 | |
michael@0 | 1361 | return i ? |
michael@0 | 1362 | // Do a sibling check if the nodes have a common ancestor |
michael@0 | 1363 | siblingCheck( ap[i], bp[i] ) : |
michael@0 | 1364 | |
michael@0 | 1365 | // Otherwise nodes in our document sort first |
michael@0 | 1366 | ap[i] === preferredDoc ? -1 : |
michael@0 | 1367 | bp[i] === preferredDoc ? 1 : |
michael@0 | 1368 | 0; |
michael@0 | 1369 | }; |
michael@0 | 1370 | |
michael@0 | 1371 | return doc; |
michael@0 | 1372 | }; |
michael@0 | 1373 | |
michael@0 | 1374 | Sizzle.matches = function( expr, elements ) { |
michael@0 | 1375 | return Sizzle( expr, null, null, elements ); |
michael@0 | 1376 | }; |
michael@0 | 1377 | |
michael@0 | 1378 | Sizzle.matchesSelector = function( elem, expr ) { |
michael@0 | 1379 | // Set document vars if needed |
michael@0 | 1380 | if ( ( elem.ownerDocument || elem ) !== document ) { |
michael@0 | 1381 | setDocument( elem ); |
michael@0 | 1382 | } |
michael@0 | 1383 | |
michael@0 | 1384 | // Make sure that attribute selectors are quoted |
michael@0 | 1385 | expr = expr.replace( rattributeQuotes, "='$1']" ); |
michael@0 | 1386 | |
michael@0 | 1387 | if ( support.matchesSelector && documentIsHTML && |
michael@0 | 1388 | ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && |
michael@0 | 1389 | ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { |
michael@0 | 1390 | |
michael@0 | 1391 | try { |
michael@0 | 1392 | var ret = matches.call( elem, expr ); |
michael@0 | 1393 | |
michael@0 | 1394 | // IE 9's matchesSelector returns false on disconnected nodes |
michael@0 | 1395 | if ( ret || support.disconnectedMatch || |
michael@0 | 1396 | // As well, disconnected nodes are said to be in a document |
michael@0 | 1397 | // fragment in IE 9 |
michael@0 | 1398 | elem.document && elem.document.nodeType !== 11 ) { |
michael@0 | 1399 | return ret; |
michael@0 | 1400 | } |
michael@0 | 1401 | } catch(e) {} |
michael@0 | 1402 | } |
michael@0 | 1403 | |
michael@0 | 1404 | return Sizzle( expr, document, null, [ elem ] ).length > 0; |
michael@0 | 1405 | }; |
michael@0 | 1406 | |
michael@0 | 1407 | Sizzle.contains = function( context, elem ) { |
michael@0 | 1408 | // Set document vars if needed |
michael@0 | 1409 | if ( ( context.ownerDocument || context ) !== document ) { |
michael@0 | 1410 | setDocument( context ); |
michael@0 | 1411 | } |
michael@0 | 1412 | return contains( context, elem ); |
michael@0 | 1413 | }; |
michael@0 | 1414 | |
michael@0 | 1415 | Sizzle.attr = function( elem, name ) { |
michael@0 | 1416 | // Set document vars if needed |
michael@0 | 1417 | if ( ( elem.ownerDocument || elem ) !== document ) { |
michael@0 | 1418 | setDocument( elem ); |
michael@0 | 1419 | } |
michael@0 | 1420 | |
michael@0 | 1421 | var fn = Expr.attrHandle[ name.toLowerCase() ], |
michael@0 | 1422 | // Don't get fooled by Object.prototype properties (jQuery #13807) |
michael@0 | 1423 | val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? |
michael@0 | 1424 | fn( elem, name, !documentIsHTML ) : |
michael@0 | 1425 | undefined; |
michael@0 | 1426 | |
michael@0 | 1427 | return val !== undefined ? |
michael@0 | 1428 | val : |
michael@0 | 1429 | support.attributes || !documentIsHTML ? |
michael@0 | 1430 | elem.getAttribute( name ) : |
michael@0 | 1431 | (val = elem.getAttributeNode(name)) && val.specified ? |
michael@0 | 1432 | val.value : |
michael@0 | 1433 | null; |
michael@0 | 1434 | }; |
michael@0 | 1435 | |
michael@0 | 1436 | Sizzle.error = function( msg ) { |
michael@0 | 1437 | throw new Error( "Syntax error, unrecognized expression: " + msg ); |
michael@0 | 1438 | }; |
michael@0 | 1439 | |
michael@0 | 1440 | /** |
michael@0 | 1441 | * Document sorting and removing duplicates |
michael@0 | 1442 | * @param {ArrayLike} results |
michael@0 | 1443 | */ |
michael@0 | 1444 | Sizzle.uniqueSort = function( results ) { |
michael@0 | 1445 | var elem, |
michael@0 | 1446 | duplicates = [], |
michael@0 | 1447 | j = 0, |
michael@0 | 1448 | i = 0; |
michael@0 | 1449 | |
michael@0 | 1450 | // Unless we *know* we can detect duplicates, assume their presence |
michael@0 | 1451 | hasDuplicate = !support.detectDuplicates; |
michael@0 | 1452 | sortInput = !support.sortStable && results.slice( 0 ); |
michael@0 | 1453 | results.sort( sortOrder ); |
michael@0 | 1454 | |
michael@0 | 1455 | if ( hasDuplicate ) { |
michael@0 | 1456 | while ( (elem = results[i++]) ) { |
michael@0 | 1457 | if ( elem === results[ i ] ) { |
michael@0 | 1458 | j = duplicates.push( i ); |
michael@0 | 1459 | } |
michael@0 | 1460 | } |
michael@0 | 1461 | while ( j-- ) { |
michael@0 | 1462 | results.splice( duplicates[ j ], 1 ); |
michael@0 | 1463 | } |
michael@0 | 1464 | } |
michael@0 | 1465 | |
michael@0 | 1466 | // Clear input after sorting to release objects |
michael@0 | 1467 | // See https://github.com/jquery/sizzle/pull/225 |
michael@0 | 1468 | sortInput = null; |
michael@0 | 1469 | |
michael@0 | 1470 | return results; |
michael@0 | 1471 | }; |
michael@0 | 1472 | |
michael@0 | 1473 | /** |
michael@0 | 1474 | * Utility function for retrieving the text value of an array of DOM nodes |
michael@0 | 1475 | * @param {Array|Element} elem |
michael@0 | 1476 | */ |
michael@0 | 1477 | getText = Sizzle.getText = function( elem ) { |
michael@0 | 1478 | var node, |
michael@0 | 1479 | ret = "", |
michael@0 | 1480 | i = 0, |
michael@0 | 1481 | nodeType = elem.nodeType; |
michael@0 | 1482 | |
michael@0 | 1483 | if ( !nodeType ) { |
michael@0 | 1484 | // If no nodeType, this is expected to be an array |
michael@0 | 1485 | while ( (node = elem[i++]) ) { |
michael@0 | 1486 | // Do not traverse comment nodes |
michael@0 | 1487 | ret += getText( node ); |
michael@0 | 1488 | } |
michael@0 | 1489 | } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { |
michael@0 | 1490 | // Use textContent for elements |
michael@0 | 1491 | // innerText usage removed for consistency of new lines (jQuery #11153) |
michael@0 | 1492 | if ( typeof elem.textContent === "string" ) { |
michael@0 | 1493 | return elem.textContent; |
michael@0 | 1494 | } else { |
michael@0 | 1495 | // Traverse its children |
michael@0 | 1496 | for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
michael@0 | 1497 | ret += getText( elem ); |
michael@0 | 1498 | } |
michael@0 | 1499 | } |
michael@0 | 1500 | } else if ( nodeType === 3 || nodeType === 4 ) { |
michael@0 | 1501 | return elem.nodeValue; |
michael@0 | 1502 | } |
michael@0 | 1503 | // Do not include comment or processing instruction nodes |
michael@0 | 1504 | |
michael@0 | 1505 | return ret; |
michael@0 | 1506 | }; |
michael@0 | 1507 | |
michael@0 | 1508 | Expr = Sizzle.selectors = { |
michael@0 | 1509 | |
michael@0 | 1510 | // Can be adjusted by the user |
michael@0 | 1511 | cacheLength: 50, |
michael@0 | 1512 | |
michael@0 | 1513 | createPseudo: markFunction, |
michael@0 | 1514 | |
michael@0 | 1515 | match: matchExpr, |
michael@0 | 1516 | |
michael@0 | 1517 | attrHandle: {}, |
michael@0 | 1518 | |
michael@0 | 1519 | find: {}, |
michael@0 | 1520 | |
michael@0 | 1521 | relative: { |
michael@0 | 1522 | ">": { dir: "parentNode", first: true }, |
michael@0 | 1523 | " ": { dir: "parentNode" }, |
michael@0 | 1524 | "+": { dir: "previousSibling", first: true }, |
michael@0 | 1525 | "~": { dir: "previousSibling" } |
michael@0 | 1526 | }, |
michael@0 | 1527 | |
michael@0 | 1528 | preFilter: { |
michael@0 | 1529 | "ATTR": function( match ) { |
michael@0 | 1530 | match[1] = match[1].replace( runescape, funescape ); |
michael@0 | 1531 | |
michael@0 | 1532 | // Move the given value to match[3] whether quoted or unquoted |
michael@0 | 1533 | match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); |
michael@0 | 1534 | |
michael@0 | 1535 | if ( match[2] === "~=" ) { |
michael@0 | 1536 | match[3] = " " + match[3] + " "; |
michael@0 | 1537 | } |
michael@0 | 1538 | |
michael@0 | 1539 | return match.slice( 0, 4 ); |
michael@0 | 1540 | }, |
michael@0 | 1541 | |
michael@0 | 1542 | "CHILD": function( match ) { |
michael@0 | 1543 | /* matches from matchExpr["CHILD"] |
michael@0 | 1544 | 1 type (only|nth|...) |
michael@0 | 1545 | 2 what (child|of-type) |
michael@0 | 1546 | 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) |
michael@0 | 1547 | 4 xn-component of xn+y argument ([+-]?\d*n|) |
michael@0 | 1548 | 5 sign of xn-component |
michael@0 | 1549 | 6 x of xn-component |
michael@0 | 1550 | 7 sign of y-component |
michael@0 | 1551 | 8 y of y-component |
michael@0 | 1552 | */ |
michael@0 | 1553 | match[1] = match[1].toLowerCase(); |
michael@0 | 1554 | |
michael@0 | 1555 | if ( match[1].slice( 0, 3 ) === "nth" ) { |
michael@0 | 1556 | // nth-* requires argument |
michael@0 | 1557 | if ( !match[3] ) { |
michael@0 | 1558 | Sizzle.error( match[0] ); |
michael@0 | 1559 | } |
michael@0 | 1560 | |
michael@0 | 1561 | // numeric x and y parameters for Expr.filter.CHILD |
michael@0 | 1562 | // remember that false/true cast respectively to 0/1 |
michael@0 | 1563 | match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); |
michael@0 | 1564 | match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); |
michael@0 | 1565 | |
michael@0 | 1566 | // other types prohibit arguments |
michael@0 | 1567 | } else if ( match[3] ) { |
michael@0 | 1568 | Sizzle.error( match[0] ); |
michael@0 | 1569 | } |
michael@0 | 1570 | |
michael@0 | 1571 | return match; |
michael@0 | 1572 | }, |
michael@0 | 1573 | |
michael@0 | 1574 | "PSEUDO": function( match ) { |
michael@0 | 1575 | var excess, |
michael@0 | 1576 | unquoted = !match[6] && match[2]; |
michael@0 | 1577 | |
michael@0 | 1578 | if ( matchExpr["CHILD"].test( match[0] ) ) { |
michael@0 | 1579 | return null; |
michael@0 | 1580 | } |
michael@0 | 1581 | |
michael@0 | 1582 | // Accept quoted arguments as-is |
michael@0 | 1583 | if ( match[3] ) { |
michael@0 | 1584 | match[2] = match[4] || match[5] || ""; |
michael@0 | 1585 | |
michael@0 | 1586 | // Strip excess characters from unquoted arguments |
michael@0 | 1587 | } else if ( unquoted && rpseudo.test( unquoted ) && |
michael@0 | 1588 | // Get excess from tokenize (recursively) |
michael@0 | 1589 | (excess = tokenize( unquoted, true )) && |
michael@0 | 1590 | // advance to the next closing parenthesis |
michael@0 | 1591 | (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { |
michael@0 | 1592 | |
michael@0 | 1593 | // excess is a negative index |
michael@0 | 1594 | match[0] = match[0].slice( 0, excess ); |
michael@0 | 1595 | match[2] = unquoted.slice( 0, excess ); |
michael@0 | 1596 | } |
michael@0 | 1597 | |
michael@0 | 1598 | // Return only captures needed by the pseudo filter method (type and argument) |
michael@0 | 1599 | return match.slice( 0, 3 ); |
michael@0 | 1600 | } |
michael@0 | 1601 | }, |
michael@0 | 1602 | |
michael@0 | 1603 | filter: { |
michael@0 | 1604 | |
michael@0 | 1605 | "TAG": function( nodeNameSelector ) { |
michael@0 | 1606 | var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); |
michael@0 | 1607 | return nodeNameSelector === "*" ? |
michael@0 | 1608 | function() { return true; } : |
michael@0 | 1609 | function( elem ) { |
michael@0 | 1610 | return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; |
michael@0 | 1611 | }; |
michael@0 | 1612 | }, |
michael@0 | 1613 | |
michael@0 | 1614 | "CLASS": function( className ) { |
michael@0 | 1615 | var pattern = classCache[ className + " " ]; |
michael@0 | 1616 | |
michael@0 | 1617 | return pattern || |
michael@0 | 1618 | (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && |
michael@0 | 1619 | classCache( className, function( elem ) { |
michael@0 | 1620 | return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); |
michael@0 | 1621 | }); |
michael@0 | 1622 | }, |
michael@0 | 1623 | |
michael@0 | 1624 | "ATTR": function( name, operator, check ) { |
michael@0 | 1625 | return function( elem ) { |
michael@0 | 1626 | var result = Sizzle.attr( elem, name ); |
michael@0 | 1627 | |
michael@0 | 1628 | if ( result == null ) { |
michael@0 | 1629 | return operator === "!="; |
michael@0 | 1630 | } |
michael@0 | 1631 | if ( !operator ) { |
michael@0 | 1632 | return true; |
michael@0 | 1633 | } |
michael@0 | 1634 | |
michael@0 | 1635 | result += ""; |
michael@0 | 1636 | |
michael@0 | 1637 | return operator === "=" ? result === check : |
michael@0 | 1638 | operator === "!=" ? result !== check : |
michael@0 | 1639 | operator === "^=" ? check && result.indexOf( check ) === 0 : |
michael@0 | 1640 | operator === "*=" ? check && result.indexOf( check ) > -1 : |
michael@0 | 1641 | operator === "$=" ? check && result.slice( -check.length ) === check : |
michael@0 | 1642 | operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : |
michael@0 | 1643 | operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : |
michael@0 | 1644 | false; |
michael@0 | 1645 | }; |
michael@0 | 1646 | }, |
michael@0 | 1647 | |
michael@0 | 1648 | "CHILD": function( type, what, argument, first, last ) { |
michael@0 | 1649 | var simple = type.slice( 0, 3 ) !== "nth", |
michael@0 | 1650 | forward = type.slice( -4 ) !== "last", |
michael@0 | 1651 | ofType = what === "of-type"; |
michael@0 | 1652 | |
michael@0 | 1653 | return first === 1 && last === 0 ? |
michael@0 | 1654 | |
michael@0 | 1655 | // Shortcut for :nth-*(n) |
michael@0 | 1656 | function( elem ) { |
michael@0 | 1657 | return !!elem.parentNode; |
michael@0 | 1658 | } : |
michael@0 | 1659 | |
michael@0 | 1660 | function( elem, context, xml ) { |
michael@0 | 1661 | var cache, outerCache, node, diff, nodeIndex, start, |
michael@0 | 1662 | dir = simple !== forward ? "nextSibling" : "previousSibling", |
michael@0 | 1663 | parent = elem.parentNode, |
michael@0 | 1664 | name = ofType && elem.nodeName.toLowerCase(), |
michael@0 | 1665 | useCache = !xml && !ofType; |
michael@0 | 1666 | |
michael@0 | 1667 | if ( parent ) { |
michael@0 | 1668 | |
michael@0 | 1669 | // :(first|last|only)-(child|of-type) |
michael@0 | 1670 | if ( simple ) { |
michael@0 | 1671 | while ( dir ) { |
michael@0 | 1672 | node = elem; |
michael@0 | 1673 | while ( (node = node[ dir ]) ) { |
michael@0 | 1674 | if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { |
michael@0 | 1675 | return false; |
michael@0 | 1676 | } |
michael@0 | 1677 | } |
michael@0 | 1678 | // Reverse direction for :only-* (if we haven't yet done so) |
michael@0 | 1679 | start = dir = type === "only" && !start && "nextSibling"; |
michael@0 | 1680 | } |
michael@0 | 1681 | return true; |
michael@0 | 1682 | } |
michael@0 | 1683 | |
michael@0 | 1684 | start = [ forward ? parent.firstChild : parent.lastChild ]; |
michael@0 | 1685 | |
michael@0 | 1686 | // non-xml :nth-child(...) stores cache data on `parent` |
michael@0 | 1687 | if ( forward && useCache ) { |
michael@0 | 1688 | // Seek `elem` from a previously-cached index |
michael@0 | 1689 | outerCache = parent[ expando ] || (parent[ expando ] = {}); |
michael@0 | 1690 | cache = outerCache[ type ] || []; |
michael@0 | 1691 | nodeIndex = cache[0] === dirruns && cache[1]; |
michael@0 | 1692 | diff = cache[0] === dirruns && cache[2]; |
michael@0 | 1693 | node = nodeIndex && parent.childNodes[ nodeIndex ]; |
michael@0 | 1694 | |
michael@0 | 1695 | while ( (node = ++nodeIndex && node && node[ dir ] || |
michael@0 | 1696 | |
michael@0 | 1697 | // Fallback to seeking `elem` from the start |
michael@0 | 1698 | (diff = nodeIndex = 0) || start.pop()) ) { |
michael@0 | 1699 | |
michael@0 | 1700 | // When found, cache indexes on `parent` and break |
michael@0 | 1701 | if ( node.nodeType === 1 && ++diff && node === elem ) { |
michael@0 | 1702 | outerCache[ type ] = [ dirruns, nodeIndex, diff ]; |
michael@0 | 1703 | break; |
michael@0 | 1704 | } |
michael@0 | 1705 | } |
michael@0 | 1706 | |
michael@0 | 1707 | // Use previously-cached element index if available |
michael@0 | 1708 | } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { |
michael@0 | 1709 | diff = cache[1]; |
michael@0 | 1710 | |
michael@0 | 1711 | // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) |
michael@0 | 1712 | } else { |
michael@0 | 1713 | // Use the same loop as above to seek `elem` from the start |
michael@0 | 1714 | while ( (node = ++nodeIndex && node && node[ dir ] || |
michael@0 | 1715 | (diff = nodeIndex = 0) || start.pop()) ) { |
michael@0 | 1716 | |
michael@0 | 1717 | if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { |
michael@0 | 1718 | // Cache the index of each encountered element |
michael@0 | 1719 | if ( useCache ) { |
michael@0 | 1720 | (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; |
michael@0 | 1721 | } |
michael@0 | 1722 | |
michael@0 | 1723 | if ( node === elem ) { |
michael@0 | 1724 | break; |
michael@0 | 1725 | } |
michael@0 | 1726 | } |
michael@0 | 1727 | } |
michael@0 | 1728 | } |
michael@0 | 1729 | |
michael@0 | 1730 | // Incorporate the offset, then check against cycle size |
michael@0 | 1731 | diff -= last; |
michael@0 | 1732 | return diff === first || ( diff % first === 0 && diff / first >= 0 ); |
michael@0 | 1733 | } |
michael@0 | 1734 | }; |
michael@0 | 1735 | }, |
michael@0 | 1736 | |
michael@0 | 1737 | "PSEUDO": function( pseudo, argument ) { |
michael@0 | 1738 | // pseudo-class names are case-insensitive |
michael@0 | 1739 | // http://www.w3.org/TR/selectors/#pseudo-classes |
michael@0 | 1740 | // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters |
michael@0 | 1741 | // Remember that setFilters inherits from pseudos |
michael@0 | 1742 | var args, |
michael@0 | 1743 | fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || |
michael@0 | 1744 | Sizzle.error( "unsupported pseudo: " + pseudo ); |
michael@0 | 1745 | |
michael@0 | 1746 | // The user may use createPseudo to indicate that |
michael@0 | 1747 | // arguments are needed to create the filter function |
michael@0 | 1748 | // just as Sizzle does |
michael@0 | 1749 | if ( fn[ expando ] ) { |
michael@0 | 1750 | return fn( argument ); |
michael@0 | 1751 | } |
michael@0 | 1752 | |
michael@0 | 1753 | // But maintain support for old signatures |
michael@0 | 1754 | if ( fn.length > 1 ) { |
michael@0 | 1755 | args = [ pseudo, pseudo, "", argument ]; |
michael@0 | 1756 | return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? |
michael@0 | 1757 | markFunction(function( seed, matches ) { |
michael@0 | 1758 | var idx, |
michael@0 | 1759 | matched = fn( seed, argument ), |
michael@0 | 1760 | i = matched.length; |
michael@0 | 1761 | while ( i-- ) { |
michael@0 | 1762 | idx = indexOf.call( seed, matched[i] ); |
michael@0 | 1763 | seed[ idx ] = !( matches[ idx ] = matched[i] ); |
michael@0 | 1764 | } |
michael@0 | 1765 | }) : |
michael@0 | 1766 | function( elem ) { |
michael@0 | 1767 | return fn( elem, 0, args ); |
michael@0 | 1768 | }; |
michael@0 | 1769 | } |
michael@0 | 1770 | |
michael@0 | 1771 | return fn; |
michael@0 | 1772 | } |
michael@0 | 1773 | }, |
michael@0 | 1774 | |
michael@0 | 1775 | pseudos: { |
michael@0 | 1776 | // Potentially complex pseudos |
michael@0 | 1777 | "not": markFunction(function( selector ) { |
michael@0 | 1778 | // Trim the selector passed to compile |
michael@0 | 1779 | // to avoid treating leading and trailing |
michael@0 | 1780 | // spaces as combinators |
michael@0 | 1781 | var input = [], |
michael@0 | 1782 | results = [], |
michael@0 | 1783 | matcher = compile( selector.replace( rtrim, "$1" ) ); |
michael@0 | 1784 | |
michael@0 | 1785 | return matcher[ expando ] ? |
michael@0 | 1786 | markFunction(function( seed, matches, context, xml ) { |
michael@0 | 1787 | var elem, |
michael@0 | 1788 | unmatched = matcher( seed, null, xml, [] ), |
michael@0 | 1789 | i = seed.length; |
michael@0 | 1790 | |
michael@0 | 1791 | // Match elements unmatched by `matcher` |
michael@0 | 1792 | while ( i-- ) { |
michael@0 | 1793 | if ( (elem = unmatched[i]) ) { |
michael@0 | 1794 | seed[i] = !(matches[i] = elem); |
michael@0 | 1795 | } |
michael@0 | 1796 | } |
michael@0 | 1797 | }) : |
michael@0 | 1798 | function( elem, context, xml ) { |
michael@0 | 1799 | input[0] = elem; |
michael@0 | 1800 | matcher( input, null, xml, results ); |
michael@0 | 1801 | return !results.pop(); |
michael@0 | 1802 | }; |
michael@0 | 1803 | }), |
michael@0 | 1804 | |
michael@0 | 1805 | "has": markFunction(function( selector ) { |
michael@0 | 1806 | return function( elem ) { |
michael@0 | 1807 | return Sizzle( selector, elem ).length > 0; |
michael@0 | 1808 | }; |
michael@0 | 1809 | }), |
michael@0 | 1810 | |
michael@0 | 1811 | "contains": markFunction(function( text ) { |
michael@0 | 1812 | return function( elem ) { |
michael@0 | 1813 | return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; |
michael@0 | 1814 | }; |
michael@0 | 1815 | }), |
michael@0 | 1816 | |
michael@0 | 1817 | // "Whether an element is represented by a :lang() selector |
michael@0 | 1818 | // is based solely on the element's language value |
michael@0 | 1819 | // being equal to the identifier C, |
michael@0 | 1820 | // or beginning with the identifier C immediately followed by "-". |
michael@0 | 1821 | // The matching of C against the element's language value is performed case-insensitively. |
michael@0 | 1822 | // The identifier C does not have to be a valid language name." |
michael@0 | 1823 | // http://www.w3.org/TR/selectors/#lang-pseudo |
michael@0 | 1824 | "lang": markFunction( function( lang ) { |
michael@0 | 1825 | // lang value must be a valid identifier |
michael@0 | 1826 | if ( !ridentifier.test(lang || "") ) { |
michael@0 | 1827 | Sizzle.error( "unsupported lang: " + lang ); |
michael@0 | 1828 | } |
michael@0 | 1829 | lang = lang.replace( runescape, funescape ).toLowerCase(); |
michael@0 | 1830 | return function( elem ) { |
michael@0 | 1831 | var elemLang; |
michael@0 | 1832 | do { |
michael@0 | 1833 | if ( (elemLang = documentIsHTML ? |
michael@0 | 1834 | elem.lang : |
michael@0 | 1835 | elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { |
michael@0 | 1836 | |
michael@0 | 1837 | elemLang = elemLang.toLowerCase(); |
michael@0 | 1838 | return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; |
michael@0 | 1839 | } |
michael@0 | 1840 | } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); |
michael@0 | 1841 | return false; |
michael@0 | 1842 | }; |
michael@0 | 1843 | }), |
michael@0 | 1844 | |
michael@0 | 1845 | // Miscellaneous |
michael@0 | 1846 | "target": function( elem ) { |
michael@0 | 1847 | var hash = window.location && window.location.hash; |
michael@0 | 1848 | return hash && hash.slice( 1 ) === elem.id; |
michael@0 | 1849 | }, |
michael@0 | 1850 | |
michael@0 | 1851 | "root": function( elem ) { |
michael@0 | 1852 | return elem === docElem; |
michael@0 | 1853 | }, |
michael@0 | 1854 | |
michael@0 | 1855 | "focus": function( elem ) { |
michael@0 | 1856 | return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); |
michael@0 | 1857 | }, |
michael@0 | 1858 | |
michael@0 | 1859 | // Boolean properties |
michael@0 | 1860 | "enabled": function( elem ) { |
michael@0 | 1861 | return elem.disabled === false; |
michael@0 | 1862 | }, |
michael@0 | 1863 | |
michael@0 | 1864 | "disabled": function( elem ) { |
michael@0 | 1865 | return elem.disabled === true; |
michael@0 | 1866 | }, |
michael@0 | 1867 | |
michael@0 | 1868 | "checked": function( elem ) { |
michael@0 | 1869 | // In CSS3, :checked should return both checked and selected elements |
michael@0 | 1870 | // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
michael@0 | 1871 | var nodeName = elem.nodeName.toLowerCase(); |
michael@0 | 1872 | return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); |
michael@0 | 1873 | }, |
michael@0 | 1874 | |
michael@0 | 1875 | "selected": function( elem ) { |
michael@0 | 1876 | // Accessing this property makes selected-by-default |
michael@0 | 1877 | // options in Safari work properly |
michael@0 | 1878 | if ( elem.parentNode ) { |
michael@0 | 1879 | elem.parentNode.selectedIndex; |
michael@0 | 1880 | } |
michael@0 | 1881 | |
michael@0 | 1882 | return elem.selected === true; |
michael@0 | 1883 | }, |
michael@0 | 1884 | |
michael@0 | 1885 | // Contents |
michael@0 | 1886 | "empty": function( elem ) { |
michael@0 | 1887 | // http://www.w3.org/TR/selectors/#empty-pseudo |
michael@0 | 1888 | // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), |
michael@0 | 1889 | // but not by others (comment: 8; processing instruction: 7; etc.) |
michael@0 | 1890 | // nodeType < 6 works because attributes (2) do not appear as children |
michael@0 | 1891 | for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
michael@0 | 1892 | if ( elem.nodeType < 6 ) { |
michael@0 | 1893 | return false; |
michael@0 | 1894 | } |
michael@0 | 1895 | } |
michael@0 | 1896 | return true; |
michael@0 | 1897 | }, |
michael@0 | 1898 | |
michael@0 | 1899 | "parent": function( elem ) { |
michael@0 | 1900 | return !Expr.pseudos["empty"]( elem ); |
michael@0 | 1901 | }, |
michael@0 | 1902 | |
michael@0 | 1903 | // Element/input types |
michael@0 | 1904 | "header": function( elem ) { |
michael@0 | 1905 | return rheader.test( elem.nodeName ); |
michael@0 | 1906 | }, |
michael@0 | 1907 | |
michael@0 | 1908 | "input": function( elem ) { |
michael@0 | 1909 | return rinputs.test( elem.nodeName ); |
michael@0 | 1910 | }, |
michael@0 | 1911 | |
michael@0 | 1912 | "button": function( elem ) { |
michael@0 | 1913 | var name = elem.nodeName.toLowerCase(); |
michael@0 | 1914 | return name === "input" && elem.type === "button" || name === "button"; |
michael@0 | 1915 | }, |
michael@0 | 1916 | |
michael@0 | 1917 | "text": function( elem ) { |
michael@0 | 1918 | var attr; |
michael@0 | 1919 | return elem.nodeName.toLowerCase() === "input" && |
michael@0 | 1920 | elem.type === "text" && |
michael@0 | 1921 | |
michael@0 | 1922 | // Support: IE<8 |
michael@0 | 1923 | // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" |
michael@0 | 1924 | ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); |
michael@0 | 1925 | }, |
michael@0 | 1926 | |
michael@0 | 1927 | // Position-in-collection |
michael@0 | 1928 | "first": createPositionalPseudo(function() { |
michael@0 | 1929 | return [ 0 ]; |
michael@0 | 1930 | }), |
michael@0 | 1931 | |
michael@0 | 1932 | "last": createPositionalPseudo(function( matchIndexes, length ) { |
michael@0 | 1933 | return [ length - 1 ]; |
michael@0 | 1934 | }), |
michael@0 | 1935 | |
michael@0 | 1936 | "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { |
michael@0 | 1937 | return [ argument < 0 ? argument + length : argument ]; |
michael@0 | 1938 | }), |
michael@0 | 1939 | |
michael@0 | 1940 | "even": createPositionalPseudo(function( matchIndexes, length ) { |
michael@0 | 1941 | var i = 0; |
michael@0 | 1942 | for ( ; i < length; i += 2 ) { |
michael@0 | 1943 | matchIndexes.push( i ); |
michael@0 | 1944 | } |
michael@0 | 1945 | return matchIndexes; |
michael@0 | 1946 | }), |
michael@0 | 1947 | |
michael@0 | 1948 | "odd": createPositionalPseudo(function( matchIndexes, length ) { |
michael@0 | 1949 | var i = 1; |
michael@0 | 1950 | for ( ; i < length; i += 2 ) { |
michael@0 | 1951 | matchIndexes.push( i ); |
michael@0 | 1952 | } |
michael@0 | 1953 | return matchIndexes; |
michael@0 | 1954 | }), |
michael@0 | 1955 | |
michael@0 | 1956 | "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
michael@0 | 1957 | var i = argument < 0 ? argument + length : argument; |
michael@0 | 1958 | for ( ; --i >= 0; ) { |
michael@0 | 1959 | matchIndexes.push( i ); |
michael@0 | 1960 | } |
michael@0 | 1961 | return matchIndexes; |
michael@0 | 1962 | }), |
michael@0 | 1963 | |
michael@0 | 1964 | "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
michael@0 | 1965 | var i = argument < 0 ? argument + length : argument; |
michael@0 | 1966 | for ( ; ++i < length; ) { |
michael@0 | 1967 | matchIndexes.push( i ); |
michael@0 | 1968 | } |
michael@0 | 1969 | return matchIndexes; |
michael@0 | 1970 | }) |
michael@0 | 1971 | } |
michael@0 | 1972 | }; |
michael@0 | 1973 | |
michael@0 | 1974 | Expr.pseudos["nth"] = Expr.pseudos["eq"]; |
michael@0 | 1975 | |
michael@0 | 1976 | // Add button/input type pseudos |
michael@0 | 1977 | for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { |
michael@0 | 1978 | Expr.pseudos[ i ] = createInputPseudo( i ); |
michael@0 | 1979 | } |
michael@0 | 1980 | for ( i in { submit: true, reset: true } ) { |
michael@0 | 1981 | Expr.pseudos[ i ] = createButtonPseudo( i ); |
michael@0 | 1982 | } |
michael@0 | 1983 | |
michael@0 | 1984 | // Easy API for creating new setFilters |
michael@0 | 1985 | function setFilters() {} |
michael@0 | 1986 | setFilters.prototype = Expr.filters = Expr.pseudos; |
michael@0 | 1987 | Expr.setFilters = new setFilters(); |
michael@0 | 1988 | |
michael@0 | 1989 | tokenize = Sizzle.tokenize = function( selector, parseOnly ) { |
michael@0 | 1990 | var matched, match, tokens, type, |
michael@0 | 1991 | soFar, groups, preFilters, |
michael@0 | 1992 | cached = tokenCache[ selector + " " ]; |
michael@0 | 1993 | |
michael@0 | 1994 | if ( cached ) { |
michael@0 | 1995 | return parseOnly ? 0 : cached.slice( 0 ); |
michael@0 | 1996 | } |
michael@0 | 1997 | |
michael@0 | 1998 | soFar = selector; |
michael@0 | 1999 | groups = []; |
michael@0 | 2000 | preFilters = Expr.preFilter; |
michael@0 | 2001 | |
michael@0 | 2002 | while ( soFar ) { |
michael@0 | 2003 | |
michael@0 | 2004 | // Comma and first run |
michael@0 | 2005 | if ( !matched || (match = rcomma.exec( soFar )) ) { |
michael@0 | 2006 | if ( match ) { |
michael@0 | 2007 | // Don't consume trailing commas as valid |
michael@0 | 2008 | soFar = soFar.slice( match[0].length ) || soFar; |
michael@0 | 2009 | } |
michael@0 | 2010 | groups.push( (tokens = []) ); |
michael@0 | 2011 | } |
michael@0 | 2012 | |
michael@0 | 2013 | matched = false; |
michael@0 | 2014 | |
michael@0 | 2015 | // Combinators |
michael@0 | 2016 | if ( (match = rcombinators.exec( soFar )) ) { |
michael@0 | 2017 | matched = match.shift(); |
michael@0 | 2018 | tokens.push({ |
michael@0 | 2019 | value: matched, |
michael@0 | 2020 | // Cast descendant combinators to space |
michael@0 | 2021 | type: match[0].replace( rtrim, " " ) |
michael@0 | 2022 | }); |
michael@0 | 2023 | soFar = soFar.slice( matched.length ); |
michael@0 | 2024 | } |
michael@0 | 2025 | |
michael@0 | 2026 | // Filters |
michael@0 | 2027 | for ( type in Expr.filter ) { |
michael@0 | 2028 | if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || |
michael@0 | 2029 | (match = preFilters[ type ]( match ))) ) { |
michael@0 | 2030 | matched = match.shift(); |
michael@0 | 2031 | tokens.push({ |
michael@0 | 2032 | value: matched, |
michael@0 | 2033 | type: type, |
michael@0 | 2034 | matches: match |
michael@0 | 2035 | }); |
michael@0 | 2036 | soFar = soFar.slice( matched.length ); |
michael@0 | 2037 | } |
michael@0 | 2038 | } |
michael@0 | 2039 | |
michael@0 | 2040 | if ( !matched ) { |
michael@0 | 2041 | break; |
michael@0 | 2042 | } |
michael@0 | 2043 | } |
michael@0 | 2044 | |
michael@0 | 2045 | // Return the length of the invalid excess |
michael@0 | 2046 | // if we're just parsing |
michael@0 | 2047 | // Otherwise, throw an error or return tokens |
michael@0 | 2048 | return parseOnly ? |
michael@0 | 2049 | soFar.length : |
michael@0 | 2050 | soFar ? |
michael@0 | 2051 | Sizzle.error( selector ) : |
michael@0 | 2052 | // Cache the tokens |
michael@0 | 2053 | tokenCache( selector, groups ).slice( 0 ); |
michael@0 | 2054 | }; |
michael@0 | 2055 | |
michael@0 | 2056 | function toSelector( tokens ) { |
michael@0 | 2057 | var i = 0, |
michael@0 | 2058 | len = tokens.length, |
michael@0 | 2059 | selector = ""; |
michael@0 | 2060 | for ( ; i < len; i++ ) { |
michael@0 | 2061 | selector += tokens[i].value; |
michael@0 | 2062 | } |
michael@0 | 2063 | return selector; |
michael@0 | 2064 | } |
michael@0 | 2065 | |
michael@0 | 2066 | function addCombinator( matcher, combinator, base ) { |
michael@0 | 2067 | var dir = combinator.dir, |
michael@0 | 2068 | checkNonElements = base && dir === "parentNode", |
michael@0 | 2069 | doneName = done++; |
michael@0 | 2070 | |
michael@0 | 2071 | return combinator.first ? |
michael@0 | 2072 | // Check against closest ancestor/preceding element |
michael@0 | 2073 | function( elem, context, xml ) { |
michael@0 | 2074 | while ( (elem = elem[ dir ]) ) { |
michael@0 | 2075 | if ( elem.nodeType === 1 || checkNonElements ) { |
michael@0 | 2076 | return matcher( elem, context, xml ); |
michael@0 | 2077 | } |
michael@0 | 2078 | } |
michael@0 | 2079 | } : |
michael@0 | 2080 | |
michael@0 | 2081 | // Check against all ancestor/preceding elements |
michael@0 | 2082 | function( elem, context, xml ) { |
michael@0 | 2083 | var oldCache, outerCache, |
michael@0 | 2084 | newCache = [ dirruns, doneName ]; |
michael@0 | 2085 | |
michael@0 | 2086 | // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching |
michael@0 | 2087 | if ( xml ) { |
michael@0 | 2088 | while ( (elem = elem[ dir ]) ) { |
michael@0 | 2089 | if ( elem.nodeType === 1 || checkNonElements ) { |
michael@0 | 2090 | if ( matcher( elem, context, xml ) ) { |
michael@0 | 2091 | return true; |
michael@0 | 2092 | } |
michael@0 | 2093 | } |
michael@0 | 2094 | } |
michael@0 | 2095 | } else { |
michael@0 | 2096 | while ( (elem = elem[ dir ]) ) { |
michael@0 | 2097 | if ( elem.nodeType === 1 || checkNonElements ) { |
michael@0 | 2098 | outerCache = elem[ expando ] || (elem[ expando ] = {}); |
michael@0 | 2099 | if ( (oldCache = outerCache[ dir ]) && |
michael@0 | 2100 | oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
michael@0 | 2101 | |
michael@0 | 2102 | // Assign to newCache so results back-propagate to previous elements |
michael@0 | 2103 | return (newCache[ 2 ] = oldCache[ 2 ]); |
michael@0 | 2104 | } else { |
michael@0 | 2105 | // Reuse newcache so results back-propagate to previous elements |
michael@0 | 2106 | outerCache[ dir ] = newCache; |
michael@0 | 2107 | |
michael@0 | 2108 | // A match means we're done; a fail means we have to keep checking |
michael@0 | 2109 | if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { |
michael@0 | 2110 | return true; |
michael@0 | 2111 | } |
michael@0 | 2112 | } |
michael@0 | 2113 | } |
michael@0 | 2114 | } |
michael@0 | 2115 | } |
michael@0 | 2116 | }; |
michael@0 | 2117 | } |
michael@0 | 2118 | |
michael@0 | 2119 | function elementMatcher( matchers ) { |
michael@0 | 2120 | return matchers.length > 1 ? |
michael@0 | 2121 | function( elem, context, xml ) { |
michael@0 | 2122 | var i = matchers.length; |
michael@0 | 2123 | while ( i-- ) { |
michael@0 | 2124 | if ( !matchers[i]( elem, context, xml ) ) { |
michael@0 | 2125 | return false; |
michael@0 | 2126 | } |
michael@0 | 2127 | } |
michael@0 | 2128 | return true; |
michael@0 | 2129 | } : |
michael@0 | 2130 | matchers[0]; |
michael@0 | 2131 | } |
michael@0 | 2132 | |
michael@0 | 2133 | function multipleContexts( selector, contexts, results ) { |
michael@0 | 2134 | var i = 0, |
michael@0 | 2135 | len = contexts.length; |
michael@0 | 2136 | for ( ; i < len; i++ ) { |
michael@0 | 2137 | Sizzle( selector, contexts[i], results ); |
michael@0 | 2138 | } |
michael@0 | 2139 | return results; |
michael@0 | 2140 | } |
michael@0 | 2141 | |
michael@0 | 2142 | function condense( unmatched, map, filter, context, xml ) { |
michael@0 | 2143 | var elem, |
michael@0 | 2144 | newUnmatched = [], |
michael@0 | 2145 | i = 0, |
michael@0 | 2146 | len = unmatched.length, |
michael@0 | 2147 | mapped = map != null; |
michael@0 | 2148 | |
michael@0 | 2149 | for ( ; i < len; i++ ) { |
michael@0 | 2150 | if ( (elem = unmatched[i]) ) { |
michael@0 | 2151 | if ( !filter || filter( elem, context, xml ) ) { |
michael@0 | 2152 | newUnmatched.push( elem ); |
michael@0 | 2153 | if ( mapped ) { |
michael@0 | 2154 | map.push( i ); |
michael@0 | 2155 | } |
michael@0 | 2156 | } |
michael@0 | 2157 | } |
michael@0 | 2158 | } |
michael@0 | 2159 | |
michael@0 | 2160 | return newUnmatched; |
michael@0 | 2161 | } |
michael@0 | 2162 | |
michael@0 | 2163 | function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { |
michael@0 | 2164 | if ( postFilter && !postFilter[ expando ] ) { |
michael@0 | 2165 | postFilter = setMatcher( postFilter ); |
michael@0 | 2166 | } |
michael@0 | 2167 | if ( postFinder && !postFinder[ expando ] ) { |
michael@0 | 2168 | postFinder = setMatcher( postFinder, postSelector ); |
michael@0 | 2169 | } |
michael@0 | 2170 | return markFunction(function( seed, results, context, xml ) { |
michael@0 | 2171 | var temp, i, elem, |
michael@0 | 2172 | preMap = [], |
michael@0 | 2173 | postMap = [], |
michael@0 | 2174 | preexisting = results.length, |
michael@0 | 2175 | |
michael@0 | 2176 | // Get initial elements from seed or context |
michael@0 | 2177 | elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), |
michael@0 | 2178 | |
michael@0 | 2179 | // Prefilter to get matcher input, preserving a map for seed-results synchronization |
michael@0 | 2180 | matcherIn = preFilter && ( seed || !selector ) ? |
michael@0 | 2181 | condense( elems, preMap, preFilter, context, xml ) : |
michael@0 | 2182 | elems, |
michael@0 | 2183 | |
michael@0 | 2184 | matcherOut = matcher ? |
michael@0 | 2185 | // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, |
michael@0 | 2186 | postFinder || ( seed ? preFilter : preexisting || postFilter ) ? |
michael@0 | 2187 | |
michael@0 | 2188 | // ...intermediate processing is necessary |
michael@0 | 2189 | [] : |
michael@0 | 2190 | |
michael@0 | 2191 | // ...otherwise use results directly |
michael@0 | 2192 | results : |
michael@0 | 2193 | matcherIn; |
michael@0 | 2194 | |
michael@0 | 2195 | // Find primary matches |
michael@0 | 2196 | if ( matcher ) { |
michael@0 | 2197 | matcher( matcherIn, matcherOut, context, xml ); |
michael@0 | 2198 | } |
michael@0 | 2199 | |
michael@0 | 2200 | // Apply postFilter |
michael@0 | 2201 | if ( postFilter ) { |
michael@0 | 2202 | temp = condense( matcherOut, postMap ); |
michael@0 | 2203 | postFilter( temp, [], context, xml ); |
michael@0 | 2204 | |
michael@0 | 2205 | // Un-match failing elements by moving them back to matcherIn |
michael@0 | 2206 | i = temp.length; |
michael@0 | 2207 | while ( i-- ) { |
michael@0 | 2208 | if ( (elem = temp[i]) ) { |
michael@0 | 2209 | matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); |
michael@0 | 2210 | } |
michael@0 | 2211 | } |
michael@0 | 2212 | } |
michael@0 | 2213 | |
michael@0 | 2214 | if ( seed ) { |
michael@0 | 2215 | if ( postFinder || preFilter ) { |
michael@0 | 2216 | if ( postFinder ) { |
michael@0 | 2217 | // Get the final matcherOut by condensing this intermediate into postFinder contexts |
michael@0 | 2218 | temp = []; |
michael@0 | 2219 | i = matcherOut.length; |
michael@0 | 2220 | while ( i-- ) { |
michael@0 | 2221 | if ( (elem = matcherOut[i]) ) { |
michael@0 | 2222 | // Restore matcherIn since elem is not yet a final match |
michael@0 | 2223 | temp.push( (matcherIn[i] = elem) ); |
michael@0 | 2224 | } |
michael@0 | 2225 | } |
michael@0 | 2226 | postFinder( null, (matcherOut = []), temp, xml ); |
michael@0 | 2227 | } |
michael@0 | 2228 | |
michael@0 | 2229 | // Move matched elements from seed to results to keep them synchronized |
michael@0 | 2230 | i = matcherOut.length; |
michael@0 | 2231 | while ( i-- ) { |
michael@0 | 2232 | if ( (elem = matcherOut[i]) && |
michael@0 | 2233 | (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { |
michael@0 | 2234 | |
michael@0 | 2235 | seed[temp] = !(results[temp] = elem); |
michael@0 | 2236 | } |
michael@0 | 2237 | } |
michael@0 | 2238 | } |
michael@0 | 2239 | |
michael@0 | 2240 | // Add elements to results, through postFinder if defined |
michael@0 | 2241 | } else { |
michael@0 | 2242 | matcherOut = condense( |
michael@0 | 2243 | matcherOut === results ? |
michael@0 | 2244 | matcherOut.splice( preexisting, matcherOut.length ) : |
michael@0 | 2245 | matcherOut |
michael@0 | 2246 | ); |
michael@0 | 2247 | if ( postFinder ) { |
michael@0 | 2248 | postFinder( null, results, matcherOut, xml ); |
michael@0 | 2249 | } else { |
michael@0 | 2250 | push.apply( results, matcherOut ); |
michael@0 | 2251 | } |
michael@0 | 2252 | } |
michael@0 | 2253 | }); |
michael@0 | 2254 | } |
michael@0 | 2255 | |
michael@0 | 2256 | function matcherFromTokens( tokens ) { |
michael@0 | 2257 | var checkContext, matcher, j, |
michael@0 | 2258 | len = tokens.length, |
michael@0 | 2259 | leadingRelative = Expr.relative[ tokens[0].type ], |
michael@0 | 2260 | implicitRelative = leadingRelative || Expr.relative[" "], |
michael@0 | 2261 | i = leadingRelative ? 1 : 0, |
michael@0 | 2262 | |
michael@0 | 2263 | // The foundational matcher ensures that elements are reachable from top-level context(s) |
michael@0 | 2264 | matchContext = addCombinator( function( elem ) { |
michael@0 | 2265 | return elem === checkContext; |
michael@0 | 2266 | }, implicitRelative, true ), |
michael@0 | 2267 | matchAnyContext = addCombinator( function( elem ) { |
michael@0 | 2268 | return indexOf.call( checkContext, elem ) > -1; |
michael@0 | 2269 | }, implicitRelative, true ), |
michael@0 | 2270 | matchers = [ function( elem, context, xml ) { |
michael@0 | 2271 | return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( |
michael@0 | 2272 | (checkContext = context).nodeType ? |
michael@0 | 2273 | matchContext( elem, context, xml ) : |
michael@0 | 2274 | matchAnyContext( elem, context, xml ) ); |
michael@0 | 2275 | } ]; |
michael@0 | 2276 | |
michael@0 | 2277 | for ( ; i < len; i++ ) { |
michael@0 | 2278 | if ( (matcher = Expr.relative[ tokens[i].type ]) ) { |
michael@0 | 2279 | matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; |
michael@0 | 2280 | } else { |
michael@0 | 2281 | matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); |
michael@0 | 2282 | |
michael@0 | 2283 | // Return special upon seeing a positional matcher |
michael@0 | 2284 | if ( matcher[ expando ] ) { |
michael@0 | 2285 | // Find the next relative operator (if any) for proper handling |
michael@0 | 2286 | j = ++i; |
michael@0 | 2287 | for ( ; j < len; j++ ) { |
michael@0 | 2288 | if ( Expr.relative[ tokens[j].type ] ) { |
michael@0 | 2289 | break; |
michael@0 | 2290 | } |
michael@0 | 2291 | } |
michael@0 | 2292 | return setMatcher( |
michael@0 | 2293 | i > 1 && elementMatcher( matchers ), |
michael@0 | 2294 | i > 1 && toSelector( |
michael@0 | 2295 | // If the preceding token was a descendant combinator, insert an implicit any-element `*` |
michael@0 | 2296 | tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) |
michael@0 | 2297 | ).replace( rtrim, "$1" ), |
michael@0 | 2298 | matcher, |
michael@0 | 2299 | i < j && matcherFromTokens( tokens.slice( i, j ) ), |
michael@0 | 2300 | j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), |
michael@0 | 2301 | j < len && toSelector( tokens ) |
michael@0 | 2302 | ); |
michael@0 | 2303 | } |
michael@0 | 2304 | matchers.push( matcher ); |
michael@0 | 2305 | } |
michael@0 | 2306 | } |
michael@0 | 2307 | |
michael@0 | 2308 | return elementMatcher( matchers ); |
michael@0 | 2309 | } |
michael@0 | 2310 | |
michael@0 | 2311 | function matcherFromGroupMatchers( elementMatchers, setMatchers ) { |
michael@0 | 2312 | var bySet = setMatchers.length > 0, |
michael@0 | 2313 | byElement = elementMatchers.length > 0, |
michael@0 | 2314 | superMatcher = function( seed, context, xml, results, outermost ) { |
michael@0 | 2315 | var elem, j, matcher, |
michael@0 | 2316 | matchedCount = 0, |
michael@0 | 2317 | i = "0", |
michael@0 | 2318 | unmatched = seed && [], |
michael@0 | 2319 | setMatched = [], |
michael@0 | 2320 | contextBackup = outermostContext, |
michael@0 | 2321 | // We must always have either seed elements or outermost context |
michael@0 | 2322 | elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), |
michael@0 | 2323 | // Use integer dirruns iff this is the outermost matcher |
michael@0 | 2324 | dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), |
michael@0 | 2325 | len = elems.length; |
michael@0 | 2326 | |
michael@0 | 2327 | if ( outermost ) { |
michael@0 | 2328 | outermostContext = context !== document && context; |
michael@0 | 2329 | } |
michael@0 | 2330 | |
michael@0 | 2331 | // Add elements passing elementMatchers directly to results |
michael@0 | 2332 | // Keep `i` a string if there are no elements so `matchedCount` will be "00" below |
michael@0 | 2333 | // Support: IE<9, Safari |
michael@0 | 2334 | // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id |
michael@0 | 2335 | for ( ; i !== len && (elem = elems[i]) != null; i++ ) { |
michael@0 | 2336 | if ( byElement && elem ) { |
michael@0 | 2337 | j = 0; |
michael@0 | 2338 | while ( (matcher = elementMatchers[j++]) ) { |
michael@0 | 2339 | if ( matcher( elem, context, xml ) ) { |
michael@0 | 2340 | results.push( elem ); |
michael@0 | 2341 | break; |
michael@0 | 2342 | } |
michael@0 | 2343 | } |
michael@0 | 2344 | if ( outermost ) { |
michael@0 | 2345 | dirruns = dirrunsUnique; |
michael@0 | 2346 | } |
michael@0 | 2347 | } |
michael@0 | 2348 | |
michael@0 | 2349 | // Track unmatched elements for set filters |
michael@0 | 2350 | if ( bySet ) { |
michael@0 | 2351 | // They will have gone through all possible matchers |
michael@0 | 2352 | if ( (elem = !matcher && elem) ) { |
michael@0 | 2353 | matchedCount--; |
michael@0 | 2354 | } |
michael@0 | 2355 | |
michael@0 | 2356 | // Lengthen the array for every element, matched or not |
michael@0 | 2357 | if ( seed ) { |
michael@0 | 2358 | unmatched.push( elem ); |
michael@0 | 2359 | } |
michael@0 | 2360 | } |
michael@0 | 2361 | } |
michael@0 | 2362 | |
michael@0 | 2363 | // Apply set filters to unmatched elements |
michael@0 | 2364 | matchedCount += i; |
michael@0 | 2365 | if ( bySet && i !== matchedCount ) { |
michael@0 | 2366 | j = 0; |
michael@0 | 2367 | while ( (matcher = setMatchers[j++]) ) { |
michael@0 | 2368 | matcher( unmatched, setMatched, context, xml ); |
michael@0 | 2369 | } |
michael@0 | 2370 | |
michael@0 | 2371 | if ( seed ) { |
michael@0 | 2372 | // Reintegrate element matches to eliminate the need for sorting |
michael@0 | 2373 | if ( matchedCount > 0 ) { |
michael@0 | 2374 | while ( i-- ) { |
michael@0 | 2375 | if ( !(unmatched[i] || setMatched[i]) ) { |
michael@0 | 2376 | setMatched[i] = pop.call( results ); |
michael@0 | 2377 | } |
michael@0 | 2378 | } |
michael@0 | 2379 | } |
michael@0 | 2380 | |
michael@0 | 2381 | // Discard index placeholder values to get only actual matches |
michael@0 | 2382 | setMatched = condense( setMatched ); |
michael@0 | 2383 | } |
michael@0 | 2384 | |
michael@0 | 2385 | // Add matches to results |
michael@0 | 2386 | push.apply( results, setMatched ); |
michael@0 | 2387 | |
michael@0 | 2388 | // Seedless set matches succeeding multiple successful matchers stipulate sorting |
michael@0 | 2389 | if ( outermost && !seed && setMatched.length > 0 && |
michael@0 | 2390 | ( matchedCount + setMatchers.length ) > 1 ) { |
michael@0 | 2391 | |
michael@0 | 2392 | Sizzle.uniqueSort( results ); |
michael@0 | 2393 | } |
michael@0 | 2394 | } |
michael@0 | 2395 | |
michael@0 | 2396 | // Override manipulation of globals by nested matchers |
michael@0 | 2397 | if ( outermost ) { |
michael@0 | 2398 | dirruns = dirrunsUnique; |
michael@0 | 2399 | outermostContext = contextBackup; |
michael@0 | 2400 | } |
michael@0 | 2401 | |
michael@0 | 2402 | return unmatched; |
michael@0 | 2403 | }; |
michael@0 | 2404 | |
michael@0 | 2405 | return bySet ? |
michael@0 | 2406 | markFunction( superMatcher ) : |
michael@0 | 2407 | superMatcher; |
michael@0 | 2408 | } |
michael@0 | 2409 | |
michael@0 | 2410 | compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { |
michael@0 | 2411 | var i, |
michael@0 | 2412 | setMatchers = [], |
michael@0 | 2413 | elementMatchers = [], |
michael@0 | 2414 | cached = compilerCache[ selector + " " ]; |
michael@0 | 2415 | |
michael@0 | 2416 | if ( !cached ) { |
michael@0 | 2417 | // Generate a function of recursive functions that can be used to check each element |
michael@0 | 2418 | if ( !match ) { |
michael@0 | 2419 | match = tokenize( selector ); |
michael@0 | 2420 | } |
michael@0 | 2421 | i = match.length; |
michael@0 | 2422 | while ( i-- ) { |
michael@0 | 2423 | cached = matcherFromTokens( match[i] ); |
michael@0 | 2424 | if ( cached[ expando ] ) { |
michael@0 | 2425 | setMatchers.push( cached ); |
michael@0 | 2426 | } else { |
michael@0 | 2427 | elementMatchers.push( cached ); |
michael@0 | 2428 | } |
michael@0 | 2429 | } |
michael@0 | 2430 | |
michael@0 | 2431 | // Cache the compiled function |
michael@0 | 2432 | cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); |
michael@0 | 2433 | |
michael@0 | 2434 | // Save selector and tokenization |
michael@0 | 2435 | cached.selector = selector; |
michael@0 | 2436 | } |
michael@0 | 2437 | return cached; |
michael@0 | 2438 | }; |
michael@0 | 2439 | |
michael@0 | 2440 | /** |
michael@0 | 2441 | * A low-level selection function that works with Sizzle's compiled |
michael@0 | 2442 | * selector functions |
michael@0 | 2443 | * @param {String|Function} selector A selector or a pre-compiled |
michael@0 | 2444 | * selector function built with Sizzle.compile |
michael@0 | 2445 | * @param {Element} context |
michael@0 | 2446 | * @param {Array} [results] |
michael@0 | 2447 | * @param {Array} [seed] A set of elements to match against |
michael@0 | 2448 | */ |
michael@0 | 2449 | select = Sizzle.select = function( selector, context, results, seed ) { |
michael@0 | 2450 | var i, tokens, token, type, find, |
michael@0 | 2451 | compiled = typeof selector === "function" && selector, |
michael@0 | 2452 | match = !seed && tokenize( (selector = compiled.selector || selector) ); |
michael@0 | 2453 | |
michael@0 | 2454 | results = results || []; |
michael@0 | 2455 | |
michael@0 | 2456 | // Try to minimize operations if there is no seed and only one group |
michael@0 | 2457 | if ( match.length === 1 ) { |
michael@0 | 2458 | |
michael@0 | 2459 | // Take a shortcut and set the context if the root selector is an ID |
michael@0 | 2460 | tokens = match[0] = match[0].slice( 0 ); |
michael@0 | 2461 | if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && |
michael@0 | 2462 | support.getById && context.nodeType === 9 && documentIsHTML && |
michael@0 | 2463 | Expr.relative[ tokens[1].type ] ) { |
michael@0 | 2464 | |
michael@0 | 2465 | context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; |
michael@0 | 2466 | if ( !context ) { |
michael@0 | 2467 | return results; |
michael@0 | 2468 | |
michael@0 | 2469 | // Precompiled matchers will still verify ancestry, so step up a level |
michael@0 | 2470 | } else if ( compiled ) { |
michael@0 | 2471 | context = context.parentNode; |
michael@0 | 2472 | } |
michael@0 | 2473 | |
michael@0 | 2474 | selector = selector.slice( tokens.shift().value.length ); |
michael@0 | 2475 | } |
michael@0 | 2476 | |
michael@0 | 2477 | // Fetch a seed set for right-to-left matching |
michael@0 | 2478 | i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; |
michael@0 | 2479 | while ( i-- ) { |
michael@0 | 2480 | token = tokens[i]; |
michael@0 | 2481 | |
michael@0 | 2482 | // Abort if we hit a combinator |
michael@0 | 2483 | if ( Expr.relative[ (type = token.type) ] ) { |
michael@0 | 2484 | break; |
michael@0 | 2485 | } |
michael@0 | 2486 | if ( (find = Expr.find[ type ]) ) { |
michael@0 | 2487 | // Search, expanding context for leading sibling combinators |
michael@0 | 2488 | if ( (seed = find( |
michael@0 | 2489 | token.matches[0].replace( runescape, funescape ), |
michael@0 | 2490 | rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context |
michael@0 | 2491 | )) ) { |
michael@0 | 2492 | |
michael@0 | 2493 | // If seed is empty or no tokens remain, we can return early |
michael@0 | 2494 | tokens.splice( i, 1 ); |
michael@0 | 2495 | selector = seed.length && toSelector( tokens ); |
michael@0 | 2496 | if ( !selector ) { |
michael@0 | 2497 | push.apply( results, seed ); |
michael@0 | 2498 | return results; |
michael@0 | 2499 | } |
michael@0 | 2500 | |
michael@0 | 2501 | break; |
michael@0 | 2502 | } |
michael@0 | 2503 | } |
michael@0 | 2504 | } |
michael@0 | 2505 | } |
michael@0 | 2506 | |
michael@0 | 2507 | // Compile and execute a filtering function if one is not provided |
michael@0 | 2508 | // Provide `match` to avoid retokenization if we modified the selector above |
michael@0 | 2509 | ( compiled || compile( selector, match ) )( |
michael@0 | 2510 | seed, |
michael@0 | 2511 | context, |
michael@0 | 2512 | !documentIsHTML, |
michael@0 | 2513 | results, |
michael@0 | 2514 | rsibling.test( selector ) && testContext( context.parentNode ) || context |
michael@0 | 2515 | ); |
michael@0 | 2516 | return results; |
michael@0 | 2517 | }; |
michael@0 | 2518 | |
michael@0 | 2519 | // One-time assignments |
michael@0 | 2520 | |
michael@0 | 2521 | // Sort stability |
michael@0 | 2522 | support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; |
michael@0 | 2523 | |
michael@0 | 2524 | // Support: Chrome<14 |
michael@0 | 2525 | // Always assume duplicates if they aren't passed to the comparison function |
michael@0 | 2526 | support.detectDuplicates = !!hasDuplicate; |
michael@0 | 2527 | |
michael@0 | 2528 | // Initialize against the default document |
michael@0 | 2529 | setDocument(); |
michael@0 | 2530 | |
michael@0 | 2531 | // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) |
michael@0 | 2532 | // Detached nodes confoundingly follow *each other* |
michael@0 | 2533 | support.sortDetached = assert(function( div1 ) { |
michael@0 | 2534 | // Should return 1, but returns 4 (following) |
michael@0 | 2535 | return div1.compareDocumentPosition( document.createElement("div") ) & 1; |
michael@0 | 2536 | }); |
michael@0 | 2537 | |
michael@0 | 2538 | // Support: IE<8 |
michael@0 | 2539 | // Prevent attribute/property "interpolation" |
michael@0 | 2540 | // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx |
michael@0 | 2541 | if ( !assert(function( div ) { |
michael@0 | 2542 | div.innerHTML = "<a href='#'></a>"; |
michael@0 | 2543 | return div.firstChild.getAttribute("href") === "#" ; |
michael@0 | 2544 | }) ) { |
michael@0 | 2545 | addHandle( "type|href|height|width", function( elem, name, isXML ) { |
michael@0 | 2546 | if ( !isXML ) { |
michael@0 | 2547 | return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); |
michael@0 | 2548 | } |
michael@0 | 2549 | }); |
michael@0 | 2550 | } |
michael@0 | 2551 | |
michael@0 | 2552 | // Support: IE<9 |
michael@0 | 2553 | // Use defaultValue in place of getAttribute("value") |
michael@0 | 2554 | if ( !support.attributes || !assert(function( div ) { |
michael@0 | 2555 | div.innerHTML = "<input/>"; |
michael@0 | 2556 | div.firstChild.setAttribute( "value", "" ); |
michael@0 | 2557 | return div.firstChild.getAttribute( "value" ) === ""; |
michael@0 | 2558 | }) ) { |
michael@0 | 2559 | addHandle( "value", function( elem, name, isXML ) { |
michael@0 | 2560 | if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { |
michael@0 | 2561 | return elem.defaultValue; |
michael@0 | 2562 | } |
michael@0 | 2563 | }); |
michael@0 | 2564 | } |
michael@0 | 2565 | |
michael@0 | 2566 | // Support: IE<9 |
michael@0 | 2567 | // Use getAttributeNode to fetch booleans when getAttribute lies |
michael@0 | 2568 | if ( !assert(function( div ) { |
michael@0 | 2569 | return div.getAttribute("disabled") == null; |
michael@0 | 2570 | }) ) { |
michael@0 | 2571 | addHandle( booleans, function( elem, name, isXML ) { |
michael@0 | 2572 | var val; |
michael@0 | 2573 | if ( !isXML ) { |
michael@0 | 2574 | return elem[ name ] === true ? name.toLowerCase() : |
michael@0 | 2575 | (val = elem.getAttributeNode( name )) && val.specified ? |
michael@0 | 2576 | val.value : |
michael@0 | 2577 | null; |
michael@0 | 2578 | } |
michael@0 | 2579 | }); |
michael@0 | 2580 | } |
michael@0 | 2581 | |
michael@0 | 2582 | return Sizzle; |
michael@0 | 2583 | |
michael@0 | 2584 | })( window ); |
michael@0 | 2585 | |
michael@0 | 2586 | |
michael@0 | 2587 | |
michael@0 | 2588 | jQuery.find = Sizzle; |
michael@0 | 2589 | jQuery.expr = Sizzle.selectors; |
michael@0 | 2590 | jQuery.expr[":"] = jQuery.expr.pseudos; |
michael@0 | 2591 | jQuery.unique = Sizzle.uniqueSort; |
michael@0 | 2592 | jQuery.text = Sizzle.getText; |
michael@0 | 2593 | jQuery.isXMLDoc = Sizzle.isXML; |
michael@0 | 2594 | jQuery.contains = Sizzle.contains; |
michael@0 | 2595 | |
michael@0 | 2596 | |
michael@0 | 2597 | |
michael@0 | 2598 | var rneedsContext = jQuery.expr.match.needsContext; |
michael@0 | 2599 | |
michael@0 | 2600 | var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); |
michael@0 | 2601 | |
michael@0 | 2602 | |
michael@0 | 2603 | |
michael@0 | 2604 | var risSimple = /^.[^:#\[\.,]*$/; |
michael@0 | 2605 | |
michael@0 | 2606 | // Implement the identical functionality for filter and not |
michael@0 | 2607 | function winnow( elements, qualifier, not ) { |
michael@0 | 2608 | if ( jQuery.isFunction( qualifier ) ) { |
michael@0 | 2609 | return jQuery.grep( elements, function( elem, i ) { |
michael@0 | 2610 | /* jshint -W018 */ |
michael@0 | 2611 | return !!qualifier.call( elem, i, elem ) !== not; |
michael@0 | 2612 | }); |
michael@0 | 2613 | |
michael@0 | 2614 | } |
michael@0 | 2615 | |
michael@0 | 2616 | if ( qualifier.nodeType ) { |
michael@0 | 2617 | return jQuery.grep( elements, function( elem ) { |
michael@0 | 2618 | return ( elem === qualifier ) !== not; |
michael@0 | 2619 | }); |
michael@0 | 2620 | |
michael@0 | 2621 | } |
michael@0 | 2622 | |
michael@0 | 2623 | if ( typeof qualifier === "string" ) { |
michael@0 | 2624 | if ( risSimple.test( qualifier ) ) { |
michael@0 | 2625 | return jQuery.filter( qualifier, elements, not ); |
michael@0 | 2626 | } |
michael@0 | 2627 | |
michael@0 | 2628 | qualifier = jQuery.filter( qualifier, elements ); |
michael@0 | 2629 | } |
michael@0 | 2630 | |
michael@0 | 2631 | return jQuery.grep( elements, function( elem ) { |
michael@0 | 2632 | return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; |
michael@0 | 2633 | }); |
michael@0 | 2634 | } |
michael@0 | 2635 | |
michael@0 | 2636 | jQuery.filter = function( expr, elems, not ) { |
michael@0 | 2637 | var elem = elems[ 0 ]; |
michael@0 | 2638 | |
michael@0 | 2639 | if ( not ) { |
michael@0 | 2640 | expr = ":not(" + expr + ")"; |
michael@0 | 2641 | } |
michael@0 | 2642 | |
michael@0 | 2643 | return elems.length === 1 && elem.nodeType === 1 ? |
michael@0 | 2644 | jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : |
michael@0 | 2645 | jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { |
michael@0 | 2646 | return elem.nodeType === 1; |
michael@0 | 2647 | })); |
michael@0 | 2648 | }; |
michael@0 | 2649 | |
michael@0 | 2650 | jQuery.fn.extend({ |
michael@0 | 2651 | find: function( selector ) { |
michael@0 | 2652 | var i, |
michael@0 | 2653 | len = this.length, |
michael@0 | 2654 | ret = [], |
michael@0 | 2655 | self = this; |
michael@0 | 2656 | |
michael@0 | 2657 | if ( typeof selector !== "string" ) { |
michael@0 | 2658 | return this.pushStack( jQuery( selector ).filter(function() { |
michael@0 | 2659 | for ( i = 0; i < len; i++ ) { |
michael@0 | 2660 | if ( jQuery.contains( self[ i ], this ) ) { |
michael@0 | 2661 | return true; |
michael@0 | 2662 | } |
michael@0 | 2663 | } |
michael@0 | 2664 | }) ); |
michael@0 | 2665 | } |
michael@0 | 2666 | |
michael@0 | 2667 | for ( i = 0; i < len; i++ ) { |
michael@0 | 2668 | jQuery.find( selector, self[ i ], ret ); |
michael@0 | 2669 | } |
michael@0 | 2670 | |
michael@0 | 2671 | // Needed because $( selector, context ) becomes $( context ).find( selector ) |
michael@0 | 2672 | ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); |
michael@0 | 2673 | ret.selector = this.selector ? this.selector + " " + selector : selector; |
michael@0 | 2674 | return ret; |
michael@0 | 2675 | }, |
michael@0 | 2676 | filter: function( selector ) { |
michael@0 | 2677 | return this.pushStack( winnow(this, selector || [], false) ); |
michael@0 | 2678 | }, |
michael@0 | 2679 | not: function( selector ) { |
michael@0 | 2680 | return this.pushStack( winnow(this, selector || [], true) ); |
michael@0 | 2681 | }, |
michael@0 | 2682 | is: function( selector ) { |
michael@0 | 2683 | return !!winnow( |
michael@0 | 2684 | this, |
michael@0 | 2685 | |
michael@0 | 2686 | // If this is a positional/relative selector, check membership in the returned set |
michael@0 | 2687 | // so $("p:first").is("p:last") won't return true for a doc with two "p". |
michael@0 | 2688 | typeof selector === "string" && rneedsContext.test( selector ) ? |
michael@0 | 2689 | jQuery( selector ) : |
michael@0 | 2690 | selector || [], |
michael@0 | 2691 | false |
michael@0 | 2692 | ).length; |
michael@0 | 2693 | } |
michael@0 | 2694 | }); |
michael@0 | 2695 | |
michael@0 | 2696 | |
michael@0 | 2697 | // Initialize a jQuery object |
michael@0 | 2698 | |
michael@0 | 2699 | |
michael@0 | 2700 | // A central reference to the root jQuery(document) |
michael@0 | 2701 | var rootjQuery, |
michael@0 | 2702 | |
michael@0 | 2703 | // A simple way to check for HTML strings |
michael@0 | 2704 | // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) |
michael@0 | 2705 | // Strict HTML recognition (#11290: must start with <) |
michael@0 | 2706 | rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, |
michael@0 | 2707 | |
michael@0 | 2708 | init = jQuery.fn.init = function( selector, context ) { |
michael@0 | 2709 | var match, elem; |
michael@0 | 2710 | |
michael@0 | 2711 | // HANDLE: $(""), $(null), $(undefined), $(false) |
michael@0 | 2712 | if ( !selector ) { |
michael@0 | 2713 | return this; |
michael@0 | 2714 | } |
michael@0 | 2715 | |
michael@0 | 2716 | // Handle HTML strings |
michael@0 | 2717 | if ( typeof selector === "string" ) { |
michael@0 | 2718 | if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { |
michael@0 | 2719 | // Assume that strings that start and end with <> are HTML and skip the regex check |
michael@0 | 2720 | match = [ null, selector, null ]; |
michael@0 | 2721 | |
michael@0 | 2722 | } else { |
michael@0 | 2723 | match = rquickExpr.exec( selector ); |
michael@0 | 2724 | } |
michael@0 | 2725 | |
michael@0 | 2726 | // Match html or make sure no context is specified for #id |
michael@0 | 2727 | if ( match && (match[1] || !context) ) { |
michael@0 | 2728 | |
michael@0 | 2729 | // HANDLE: $(html) -> $(array) |
michael@0 | 2730 | if ( match[1] ) { |
michael@0 | 2731 | context = context instanceof jQuery ? context[0] : context; |
michael@0 | 2732 | |
michael@0 | 2733 | // scripts is true for back-compat |
michael@0 | 2734 | // Intentionally let the error be thrown if parseHTML is not present |
michael@0 | 2735 | jQuery.merge( this, jQuery.parseHTML( |
michael@0 | 2736 | match[1], |
michael@0 | 2737 | context && context.nodeType ? context.ownerDocument || context : document, |
michael@0 | 2738 | true |
michael@0 | 2739 | ) ); |
michael@0 | 2740 | |
michael@0 | 2741 | // HANDLE: $(html, props) |
michael@0 | 2742 | if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { |
michael@0 | 2743 | for ( match in context ) { |
michael@0 | 2744 | // Properties of context are called as methods if possible |
michael@0 | 2745 | if ( jQuery.isFunction( this[ match ] ) ) { |
michael@0 | 2746 | this[ match ]( context[ match ] ); |
michael@0 | 2747 | |
michael@0 | 2748 | // ...and otherwise set as attributes |
michael@0 | 2749 | } else { |
michael@0 | 2750 | this.attr( match, context[ match ] ); |
michael@0 | 2751 | } |
michael@0 | 2752 | } |
michael@0 | 2753 | } |
michael@0 | 2754 | |
michael@0 | 2755 | return this; |
michael@0 | 2756 | |
michael@0 | 2757 | // HANDLE: $(#id) |
michael@0 | 2758 | } else { |
michael@0 | 2759 | elem = document.getElementById( match[2] ); |
michael@0 | 2760 | |
michael@0 | 2761 | // Check parentNode to catch when Blackberry 4.6 returns |
michael@0 | 2762 | // nodes that are no longer in the document #6963 |
michael@0 | 2763 | if ( elem && elem.parentNode ) { |
michael@0 | 2764 | // Inject the element directly into the jQuery object |
michael@0 | 2765 | this.length = 1; |
michael@0 | 2766 | this[0] = elem; |
michael@0 | 2767 | } |
michael@0 | 2768 | |
michael@0 | 2769 | this.context = document; |
michael@0 | 2770 | this.selector = selector; |
michael@0 | 2771 | return this; |
michael@0 | 2772 | } |
michael@0 | 2773 | |
michael@0 | 2774 | // HANDLE: $(expr, $(...)) |
michael@0 | 2775 | } else if ( !context || context.jquery ) { |
michael@0 | 2776 | return ( context || rootjQuery ).find( selector ); |
michael@0 | 2777 | |
michael@0 | 2778 | // HANDLE: $(expr, context) |
michael@0 | 2779 | // (which is just equivalent to: $(context).find(expr) |
michael@0 | 2780 | } else { |
michael@0 | 2781 | return this.constructor( context ).find( selector ); |
michael@0 | 2782 | } |
michael@0 | 2783 | |
michael@0 | 2784 | // HANDLE: $(DOMElement) |
michael@0 | 2785 | } else if ( selector.nodeType ) { |
michael@0 | 2786 | this.context = this[0] = selector; |
michael@0 | 2787 | this.length = 1; |
michael@0 | 2788 | return this; |
michael@0 | 2789 | |
michael@0 | 2790 | // HANDLE: $(function) |
michael@0 | 2791 | // Shortcut for document ready |
michael@0 | 2792 | } else if ( jQuery.isFunction( selector ) ) { |
michael@0 | 2793 | return typeof rootjQuery.ready !== "undefined" ? |
michael@0 | 2794 | rootjQuery.ready( selector ) : |
michael@0 | 2795 | // Execute immediately if ready is not present |
michael@0 | 2796 | selector( jQuery ); |
michael@0 | 2797 | } |
michael@0 | 2798 | |
michael@0 | 2799 | if ( selector.selector !== undefined ) { |
michael@0 | 2800 | this.selector = selector.selector; |
michael@0 | 2801 | this.context = selector.context; |
michael@0 | 2802 | } |
michael@0 | 2803 | |
michael@0 | 2804 | return jQuery.makeArray( selector, this ); |
michael@0 | 2805 | }; |
michael@0 | 2806 | |
michael@0 | 2807 | // Give the init function the jQuery prototype for later instantiation |
michael@0 | 2808 | init.prototype = jQuery.fn; |
michael@0 | 2809 | |
michael@0 | 2810 | // Initialize central reference |
michael@0 | 2811 | rootjQuery = jQuery( document ); |
michael@0 | 2812 | |
michael@0 | 2813 | |
michael@0 | 2814 | var rparentsprev = /^(?:parents|prev(?:Until|All))/, |
michael@0 | 2815 | // methods guaranteed to produce a unique set when starting from a unique set |
michael@0 | 2816 | guaranteedUnique = { |
michael@0 | 2817 | children: true, |
michael@0 | 2818 | contents: true, |
michael@0 | 2819 | next: true, |
michael@0 | 2820 | prev: true |
michael@0 | 2821 | }; |
michael@0 | 2822 | |
michael@0 | 2823 | jQuery.extend({ |
michael@0 | 2824 | dir: function( elem, dir, until ) { |
michael@0 | 2825 | var matched = [], |
michael@0 | 2826 | truncate = until !== undefined; |
michael@0 | 2827 | |
michael@0 | 2828 | while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { |
michael@0 | 2829 | if ( elem.nodeType === 1 ) { |
michael@0 | 2830 | if ( truncate && jQuery( elem ).is( until ) ) { |
michael@0 | 2831 | break; |
michael@0 | 2832 | } |
michael@0 | 2833 | matched.push( elem ); |
michael@0 | 2834 | } |
michael@0 | 2835 | } |
michael@0 | 2836 | return matched; |
michael@0 | 2837 | }, |
michael@0 | 2838 | |
michael@0 | 2839 | sibling: function( n, elem ) { |
michael@0 | 2840 | var matched = []; |
michael@0 | 2841 | |
michael@0 | 2842 | for ( ; n; n = n.nextSibling ) { |
michael@0 | 2843 | if ( n.nodeType === 1 && n !== elem ) { |
michael@0 | 2844 | matched.push( n ); |
michael@0 | 2845 | } |
michael@0 | 2846 | } |
michael@0 | 2847 | |
michael@0 | 2848 | return matched; |
michael@0 | 2849 | } |
michael@0 | 2850 | }); |
michael@0 | 2851 | |
michael@0 | 2852 | jQuery.fn.extend({ |
michael@0 | 2853 | has: function( target ) { |
michael@0 | 2854 | var targets = jQuery( target, this ), |
michael@0 | 2855 | l = targets.length; |
michael@0 | 2856 | |
michael@0 | 2857 | return this.filter(function() { |
michael@0 | 2858 | var i = 0; |
michael@0 | 2859 | for ( ; i < l; i++ ) { |
michael@0 | 2860 | if ( jQuery.contains( this, targets[i] ) ) { |
michael@0 | 2861 | return true; |
michael@0 | 2862 | } |
michael@0 | 2863 | } |
michael@0 | 2864 | }); |
michael@0 | 2865 | }, |
michael@0 | 2866 | |
michael@0 | 2867 | closest: function( selectors, context ) { |
michael@0 | 2868 | var cur, |
michael@0 | 2869 | i = 0, |
michael@0 | 2870 | l = this.length, |
michael@0 | 2871 | matched = [], |
michael@0 | 2872 | pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? |
michael@0 | 2873 | jQuery( selectors, context || this.context ) : |
michael@0 | 2874 | 0; |
michael@0 | 2875 | |
michael@0 | 2876 | for ( ; i < l; i++ ) { |
michael@0 | 2877 | for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { |
michael@0 | 2878 | // Always skip document fragments |
michael@0 | 2879 | if ( cur.nodeType < 11 && (pos ? |
michael@0 | 2880 | pos.index(cur) > -1 : |
michael@0 | 2881 | |
michael@0 | 2882 | // Don't pass non-elements to Sizzle |
michael@0 | 2883 | cur.nodeType === 1 && |
michael@0 | 2884 | jQuery.find.matchesSelector(cur, selectors)) ) { |
michael@0 | 2885 | |
michael@0 | 2886 | matched.push( cur ); |
michael@0 | 2887 | break; |
michael@0 | 2888 | } |
michael@0 | 2889 | } |
michael@0 | 2890 | } |
michael@0 | 2891 | |
michael@0 | 2892 | return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); |
michael@0 | 2893 | }, |
michael@0 | 2894 | |
michael@0 | 2895 | // Determine the position of an element within |
michael@0 | 2896 | // the matched set of elements |
michael@0 | 2897 | index: function( elem ) { |
michael@0 | 2898 | |
michael@0 | 2899 | // No argument, return index in parent |
michael@0 | 2900 | if ( !elem ) { |
michael@0 | 2901 | return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; |
michael@0 | 2902 | } |
michael@0 | 2903 | |
michael@0 | 2904 | // index in selector |
michael@0 | 2905 | if ( typeof elem === "string" ) { |
michael@0 | 2906 | return indexOf.call( jQuery( elem ), this[ 0 ] ); |
michael@0 | 2907 | } |
michael@0 | 2908 | |
michael@0 | 2909 | // Locate the position of the desired element |
michael@0 | 2910 | return indexOf.call( this, |
michael@0 | 2911 | |
michael@0 | 2912 | // If it receives a jQuery object, the first element is used |
michael@0 | 2913 | elem.jquery ? elem[ 0 ] : elem |
michael@0 | 2914 | ); |
michael@0 | 2915 | }, |
michael@0 | 2916 | |
michael@0 | 2917 | add: function( selector, context ) { |
michael@0 | 2918 | return this.pushStack( |
michael@0 | 2919 | jQuery.unique( |
michael@0 | 2920 | jQuery.merge( this.get(), jQuery( selector, context ) ) |
michael@0 | 2921 | ) |
michael@0 | 2922 | ); |
michael@0 | 2923 | }, |
michael@0 | 2924 | |
michael@0 | 2925 | addBack: function( selector ) { |
michael@0 | 2926 | return this.add( selector == null ? |
michael@0 | 2927 | this.prevObject : this.prevObject.filter(selector) |
michael@0 | 2928 | ); |
michael@0 | 2929 | } |
michael@0 | 2930 | }); |
michael@0 | 2931 | |
michael@0 | 2932 | function sibling( cur, dir ) { |
michael@0 | 2933 | while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} |
michael@0 | 2934 | return cur; |
michael@0 | 2935 | } |
michael@0 | 2936 | |
michael@0 | 2937 | jQuery.each({ |
michael@0 | 2938 | parent: function( elem ) { |
michael@0 | 2939 | var parent = elem.parentNode; |
michael@0 | 2940 | return parent && parent.nodeType !== 11 ? parent : null; |
michael@0 | 2941 | }, |
michael@0 | 2942 | parents: function( elem ) { |
michael@0 | 2943 | return jQuery.dir( elem, "parentNode" ); |
michael@0 | 2944 | }, |
michael@0 | 2945 | parentsUntil: function( elem, i, until ) { |
michael@0 | 2946 | return jQuery.dir( elem, "parentNode", until ); |
michael@0 | 2947 | }, |
michael@0 | 2948 | next: function( elem ) { |
michael@0 | 2949 | return sibling( elem, "nextSibling" ); |
michael@0 | 2950 | }, |
michael@0 | 2951 | prev: function( elem ) { |
michael@0 | 2952 | return sibling( elem, "previousSibling" ); |
michael@0 | 2953 | }, |
michael@0 | 2954 | nextAll: function( elem ) { |
michael@0 | 2955 | return jQuery.dir( elem, "nextSibling" ); |
michael@0 | 2956 | }, |
michael@0 | 2957 | prevAll: function( elem ) { |
michael@0 | 2958 | return jQuery.dir( elem, "previousSibling" ); |
michael@0 | 2959 | }, |
michael@0 | 2960 | nextUntil: function( elem, i, until ) { |
michael@0 | 2961 | return jQuery.dir( elem, "nextSibling", until ); |
michael@0 | 2962 | }, |
michael@0 | 2963 | prevUntil: function( elem, i, until ) { |
michael@0 | 2964 | return jQuery.dir( elem, "previousSibling", until ); |
michael@0 | 2965 | }, |
michael@0 | 2966 | siblings: function( elem ) { |
michael@0 | 2967 | return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); |
michael@0 | 2968 | }, |
michael@0 | 2969 | children: function( elem ) { |
michael@0 | 2970 | return jQuery.sibling( elem.firstChild ); |
michael@0 | 2971 | }, |
michael@0 | 2972 | contents: function( elem ) { |
michael@0 | 2973 | return elem.contentDocument || jQuery.merge( [], elem.childNodes ); |
michael@0 | 2974 | } |
michael@0 | 2975 | }, function( name, fn ) { |
michael@0 | 2976 | jQuery.fn[ name ] = function( until, selector ) { |
michael@0 | 2977 | var matched = jQuery.map( this, fn, until ); |
michael@0 | 2978 | |
michael@0 | 2979 | if ( name.slice( -5 ) !== "Until" ) { |
michael@0 | 2980 | selector = until; |
michael@0 | 2981 | } |
michael@0 | 2982 | |
michael@0 | 2983 | if ( selector && typeof selector === "string" ) { |
michael@0 | 2984 | matched = jQuery.filter( selector, matched ); |
michael@0 | 2985 | } |
michael@0 | 2986 | |
michael@0 | 2987 | if ( this.length > 1 ) { |
michael@0 | 2988 | // Remove duplicates |
michael@0 | 2989 | if ( !guaranteedUnique[ name ] ) { |
michael@0 | 2990 | jQuery.unique( matched ); |
michael@0 | 2991 | } |
michael@0 | 2992 | |
michael@0 | 2993 | // Reverse order for parents* and prev-derivatives |
michael@0 | 2994 | if ( rparentsprev.test( name ) ) { |
michael@0 | 2995 | matched.reverse(); |
michael@0 | 2996 | } |
michael@0 | 2997 | } |
michael@0 | 2998 | |
michael@0 | 2999 | return this.pushStack( matched ); |
michael@0 | 3000 | }; |
michael@0 | 3001 | }); |
michael@0 | 3002 | var rnotwhite = (/\S+/g); |
michael@0 | 3003 | |
michael@0 | 3004 | |
michael@0 | 3005 | |
michael@0 | 3006 | // String to Object options format cache |
michael@0 | 3007 | var optionsCache = {}; |
michael@0 | 3008 | |
michael@0 | 3009 | // Convert String-formatted options into Object-formatted ones and store in cache |
michael@0 | 3010 | function createOptions( options ) { |
michael@0 | 3011 | var object = optionsCache[ options ] = {}; |
michael@0 | 3012 | jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { |
michael@0 | 3013 | object[ flag ] = true; |
michael@0 | 3014 | }); |
michael@0 | 3015 | return object; |
michael@0 | 3016 | } |
michael@0 | 3017 | |
michael@0 | 3018 | /* |
michael@0 | 3019 | * Create a callback list using the following parameters: |
michael@0 | 3020 | * |
michael@0 | 3021 | * options: an optional list of space-separated options that will change how |
michael@0 | 3022 | * the callback list behaves or a more traditional option object |
michael@0 | 3023 | * |
michael@0 | 3024 | * By default a callback list will act like an event callback list and can be |
michael@0 | 3025 | * "fired" multiple times. |
michael@0 | 3026 | * |
michael@0 | 3027 | * Possible options: |
michael@0 | 3028 | * |
michael@0 | 3029 | * once: will ensure the callback list can only be fired once (like a Deferred) |
michael@0 | 3030 | * |
michael@0 | 3031 | * memory: will keep track of previous values and will call any callback added |
michael@0 | 3032 | * after the list has been fired right away with the latest "memorized" |
michael@0 | 3033 | * values (like a Deferred) |
michael@0 | 3034 | * |
michael@0 | 3035 | * unique: will ensure a callback can only be added once (no duplicate in the list) |
michael@0 | 3036 | * |
michael@0 | 3037 | * stopOnFalse: interrupt callings when a callback returns false |
michael@0 | 3038 | * |
michael@0 | 3039 | */ |
michael@0 | 3040 | jQuery.Callbacks = function( options ) { |
michael@0 | 3041 | |
michael@0 | 3042 | // Convert options from String-formatted to Object-formatted if needed |
michael@0 | 3043 | // (we check in cache first) |
michael@0 | 3044 | options = typeof options === "string" ? |
michael@0 | 3045 | ( optionsCache[ options ] || createOptions( options ) ) : |
michael@0 | 3046 | jQuery.extend( {}, options ); |
michael@0 | 3047 | |
michael@0 | 3048 | var // Last fire value (for non-forgettable lists) |
michael@0 | 3049 | memory, |
michael@0 | 3050 | // Flag to know if list was already fired |
michael@0 | 3051 | fired, |
michael@0 | 3052 | // Flag to know if list is currently firing |
michael@0 | 3053 | firing, |
michael@0 | 3054 | // First callback to fire (used internally by add and fireWith) |
michael@0 | 3055 | firingStart, |
michael@0 | 3056 | // End of the loop when firing |
michael@0 | 3057 | firingLength, |
michael@0 | 3058 | // Index of currently firing callback (modified by remove if needed) |
michael@0 | 3059 | firingIndex, |
michael@0 | 3060 | // Actual callback list |
michael@0 | 3061 | list = [], |
michael@0 | 3062 | // Stack of fire calls for repeatable lists |
michael@0 | 3063 | stack = !options.once && [], |
michael@0 | 3064 | // Fire callbacks |
michael@0 | 3065 | fire = function( data ) { |
michael@0 | 3066 | memory = options.memory && data; |
michael@0 | 3067 | fired = true; |
michael@0 | 3068 | firingIndex = firingStart || 0; |
michael@0 | 3069 | firingStart = 0; |
michael@0 | 3070 | firingLength = list.length; |
michael@0 | 3071 | firing = true; |
michael@0 | 3072 | for ( ; list && firingIndex < firingLength; firingIndex++ ) { |
michael@0 | 3073 | if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { |
michael@0 | 3074 | memory = false; // To prevent further calls using add |
michael@0 | 3075 | break; |
michael@0 | 3076 | } |
michael@0 | 3077 | } |
michael@0 | 3078 | firing = false; |
michael@0 | 3079 | if ( list ) { |
michael@0 | 3080 | if ( stack ) { |
michael@0 | 3081 | if ( stack.length ) { |
michael@0 | 3082 | fire( stack.shift() ); |
michael@0 | 3083 | } |
michael@0 | 3084 | } else if ( memory ) { |
michael@0 | 3085 | list = []; |
michael@0 | 3086 | } else { |
michael@0 | 3087 | self.disable(); |
michael@0 | 3088 | } |
michael@0 | 3089 | } |
michael@0 | 3090 | }, |
michael@0 | 3091 | // Actual Callbacks object |
michael@0 | 3092 | self = { |
michael@0 | 3093 | // Add a callback or a collection of callbacks to the list |
michael@0 | 3094 | add: function() { |
michael@0 | 3095 | if ( list ) { |
michael@0 | 3096 | // First, we save the current length |
michael@0 | 3097 | var start = list.length; |
michael@0 | 3098 | (function add( args ) { |
michael@0 | 3099 | jQuery.each( args, function( _, arg ) { |
michael@0 | 3100 | var type = jQuery.type( arg ); |
michael@0 | 3101 | if ( type === "function" ) { |
michael@0 | 3102 | if ( !options.unique || !self.has( arg ) ) { |
michael@0 | 3103 | list.push( arg ); |
michael@0 | 3104 | } |
michael@0 | 3105 | } else if ( arg && arg.length && type !== "string" ) { |
michael@0 | 3106 | // Inspect recursively |
michael@0 | 3107 | add( arg ); |
michael@0 | 3108 | } |
michael@0 | 3109 | }); |
michael@0 | 3110 | })( arguments ); |
michael@0 | 3111 | // Do we need to add the callbacks to the |
michael@0 | 3112 | // current firing batch? |
michael@0 | 3113 | if ( firing ) { |
michael@0 | 3114 | firingLength = list.length; |
michael@0 | 3115 | // With memory, if we're not firing then |
michael@0 | 3116 | // we should call right away |
michael@0 | 3117 | } else if ( memory ) { |
michael@0 | 3118 | firingStart = start; |
michael@0 | 3119 | fire( memory ); |
michael@0 | 3120 | } |
michael@0 | 3121 | } |
michael@0 | 3122 | return this; |
michael@0 | 3123 | }, |
michael@0 | 3124 | // Remove a callback from the list |
michael@0 | 3125 | remove: function() { |
michael@0 | 3126 | if ( list ) { |
michael@0 | 3127 | jQuery.each( arguments, function( _, arg ) { |
michael@0 | 3128 | var index; |
michael@0 | 3129 | while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { |
michael@0 | 3130 | list.splice( index, 1 ); |
michael@0 | 3131 | // Handle firing indexes |
michael@0 | 3132 | if ( firing ) { |
michael@0 | 3133 | if ( index <= firingLength ) { |
michael@0 | 3134 | firingLength--; |
michael@0 | 3135 | } |
michael@0 | 3136 | if ( index <= firingIndex ) { |
michael@0 | 3137 | firingIndex--; |
michael@0 | 3138 | } |
michael@0 | 3139 | } |
michael@0 | 3140 | } |
michael@0 | 3141 | }); |
michael@0 | 3142 | } |
michael@0 | 3143 | return this; |
michael@0 | 3144 | }, |
michael@0 | 3145 | // Check if a given callback is in the list. |
michael@0 | 3146 | // If no argument is given, return whether or not list has callbacks attached. |
michael@0 | 3147 | has: function( fn ) { |
michael@0 | 3148 | return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); |
michael@0 | 3149 | }, |
michael@0 | 3150 | // Remove all callbacks from the list |
michael@0 | 3151 | empty: function() { |
michael@0 | 3152 | list = []; |
michael@0 | 3153 | firingLength = 0; |
michael@0 | 3154 | return this; |
michael@0 | 3155 | }, |
michael@0 | 3156 | // Have the list do nothing anymore |
michael@0 | 3157 | disable: function() { |
michael@0 | 3158 | list = stack = memory = undefined; |
michael@0 | 3159 | return this; |
michael@0 | 3160 | }, |
michael@0 | 3161 | // Is it disabled? |
michael@0 | 3162 | disabled: function() { |
michael@0 | 3163 | return !list; |
michael@0 | 3164 | }, |
michael@0 | 3165 | // Lock the list in its current state |
michael@0 | 3166 | lock: function() { |
michael@0 | 3167 | stack = undefined; |
michael@0 | 3168 | if ( !memory ) { |
michael@0 | 3169 | self.disable(); |
michael@0 | 3170 | } |
michael@0 | 3171 | return this; |
michael@0 | 3172 | }, |
michael@0 | 3173 | // Is it locked? |
michael@0 | 3174 | locked: function() { |
michael@0 | 3175 | return !stack; |
michael@0 | 3176 | }, |
michael@0 | 3177 | // Call all callbacks with the given context and arguments |
michael@0 | 3178 | fireWith: function( context, args ) { |
michael@0 | 3179 | if ( list && ( !fired || stack ) ) { |
michael@0 | 3180 | args = args || []; |
michael@0 | 3181 | args = [ context, args.slice ? args.slice() : args ]; |
michael@0 | 3182 | if ( firing ) { |
michael@0 | 3183 | stack.push( args ); |
michael@0 | 3184 | } else { |
michael@0 | 3185 | fire( args ); |
michael@0 | 3186 | } |
michael@0 | 3187 | } |
michael@0 | 3188 | return this; |
michael@0 | 3189 | }, |
michael@0 | 3190 | // Call all the callbacks with the given arguments |
michael@0 | 3191 | fire: function() { |
michael@0 | 3192 | self.fireWith( this, arguments ); |
michael@0 | 3193 | return this; |
michael@0 | 3194 | }, |
michael@0 | 3195 | // To know if the callbacks have already been called at least once |
michael@0 | 3196 | fired: function() { |
michael@0 | 3197 | return !!fired; |
michael@0 | 3198 | } |
michael@0 | 3199 | }; |
michael@0 | 3200 | |
michael@0 | 3201 | return self; |
michael@0 | 3202 | }; |
michael@0 | 3203 | |
michael@0 | 3204 | |
michael@0 | 3205 | jQuery.extend({ |
michael@0 | 3206 | |
michael@0 | 3207 | Deferred: function( func ) { |
michael@0 | 3208 | var tuples = [ |
michael@0 | 3209 | // action, add listener, listener list, final state |
michael@0 | 3210 | [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], |
michael@0 | 3211 | [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], |
michael@0 | 3212 | [ "notify", "progress", jQuery.Callbacks("memory") ] |
michael@0 | 3213 | ], |
michael@0 | 3214 | state = "pending", |
michael@0 | 3215 | promise = { |
michael@0 | 3216 | state: function() { |
michael@0 | 3217 | return state; |
michael@0 | 3218 | }, |
michael@0 | 3219 | always: function() { |
michael@0 | 3220 | deferred.done( arguments ).fail( arguments ); |
michael@0 | 3221 | return this; |
michael@0 | 3222 | }, |
michael@0 | 3223 | then: function( /* fnDone, fnFail, fnProgress */ ) { |
michael@0 | 3224 | var fns = arguments; |
michael@0 | 3225 | return jQuery.Deferred(function( newDefer ) { |
michael@0 | 3226 | jQuery.each( tuples, function( i, tuple ) { |
michael@0 | 3227 | var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; |
michael@0 | 3228 | // deferred[ done | fail | progress ] for forwarding actions to newDefer |
michael@0 | 3229 | deferred[ tuple[1] ](function() { |
michael@0 | 3230 | var returned = fn && fn.apply( this, arguments ); |
michael@0 | 3231 | if ( returned && jQuery.isFunction( returned.promise ) ) { |
michael@0 | 3232 | returned.promise() |
michael@0 | 3233 | .done( newDefer.resolve ) |
michael@0 | 3234 | .fail( newDefer.reject ) |
michael@0 | 3235 | .progress( newDefer.notify ); |
michael@0 | 3236 | } else { |
michael@0 | 3237 | newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); |
michael@0 | 3238 | } |
michael@0 | 3239 | }); |
michael@0 | 3240 | }); |
michael@0 | 3241 | fns = null; |
michael@0 | 3242 | }).promise(); |
michael@0 | 3243 | }, |
michael@0 | 3244 | // Get a promise for this deferred |
michael@0 | 3245 | // If obj is provided, the promise aspect is added to the object |
michael@0 | 3246 | promise: function( obj ) { |
michael@0 | 3247 | return obj != null ? jQuery.extend( obj, promise ) : promise; |
michael@0 | 3248 | } |
michael@0 | 3249 | }, |
michael@0 | 3250 | deferred = {}; |
michael@0 | 3251 | |
michael@0 | 3252 | // Keep pipe for back-compat |
michael@0 | 3253 | promise.pipe = promise.then; |
michael@0 | 3254 | |
michael@0 | 3255 | // Add list-specific methods |
michael@0 | 3256 | jQuery.each( tuples, function( i, tuple ) { |
michael@0 | 3257 | var list = tuple[ 2 ], |
michael@0 | 3258 | stateString = tuple[ 3 ]; |
michael@0 | 3259 | |
michael@0 | 3260 | // promise[ done | fail | progress ] = list.add |
michael@0 | 3261 | promise[ tuple[1] ] = list.add; |
michael@0 | 3262 | |
michael@0 | 3263 | // Handle state |
michael@0 | 3264 | if ( stateString ) { |
michael@0 | 3265 | list.add(function() { |
michael@0 | 3266 | // state = [ resolved | rejected ] |
michael@0 | 3267 | state = stateString; |
michael@0 | 3268 | |
michael@0 | 3269 | // [ reject_list | resolve_list ].disable; progress_list.lock |
michael@0 | 3270 | }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); |
michael@0 | 3271 | } |
michael@0 | 3272 | |
michael@0 | 3273 | // deferred[ resolve | reject | notify ] |
michael@0 | 3274 | deferred[ tuple[0] ] = function() { |
michael@0 | 3275 | deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); |
michael@0 | 3276 | return this; |
michael@0 | 3277 | }; |
michael@0 | 3278 | deferred[ tuple[0] + "With" ] = list.fireWith; |
michael@0 | 3279 | }); |
michael@0 | 3280 | |
michael@0 | 3281 | // Make the deferred a promise |
michael@0 | 3282 | promise.promise( deferred ); |
michael@0 | 3283 | |
michael@0 | 3284 | // Call given func if any |
michael@0 | 3285 | if ( func ) { |
michael@0 | 3286 | func.call( deferred, deferred ); |
michael@0 | 3287 | } |
michael@0 | 3288 | |
michael@0 | 3289 | // All done! |
michael@0 | 3290 | return deferred; |
michael@0 | 3291 | }, |
michael@0 | 3292 | |
michael@0 | 3293 | // Deferred helper |
michael@0 | 3294 | when: function( subordinate /* , ..., subordinateN */ ) { |
michael@0 | 3295 | var i = 0, |
michael@0 | 3296 | resolveValues = slice.call( arguments ), |
michael@0 | 3297 | length = resolveValues.length, |
michael@0 | 3298 | |
michael@0 | 3299 | // the count of uncompleted subordinates |
michael@0 | 3300 | remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, |
michael@0 | 3301 | |
michael@0 | 3302 | // the master Deferred. If resolveValues consist of only a single Deferred, just use that. |
michael@0 | 3303 | deferred = remaining === 1 ? subordinate : jQuery.Deferred(), |
michael@0 | 3304 | |
michael@0 | 3305 | // Update function for both resolve and progress values |
michael@0 | 3306 | updateFunc = function( i, contexts, values ) { |
michael@0 | 3307 | return function( value ) { |
michael@0 | 3308 | contexts[ i ] = this; |
michael@0 | 3309 | values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; |
michael@0 | 3310 | if ( values === progressValues ) { |
michael@0 | 3311 | deferred.notifyWith( contexts, values ); |
michael@0 | 3312 | } else if ( !( --remaining ) ) { |
michael@0 | 3313 | deferred.resolveWith( contexts, values ); |
michael@0 | 3314 | } |
michael@0 | 3315 | }; |
michael@0 | 3316 | }, |
michael@0 | 3317 | |
michael@0 | 3318 | progressValues, progressContexts, resolveContexts; |
michael@0 | 3319 | |
michael@0 | 3320 | // add listeners to Deferred subordinates; treat others as resolved |
michael@0 | 3321 | if ( length > 1 ) { |
michael@0 | 3322 | progressValues = new Array( length ); |
michael@0 | 3323 | progressContexts = new Array( length ); |
michael@0 | 3324 | resolveContexts = new Array( length ); |
michael@0 | 3325 | for ( ; i < length; i++ ) { |
michael@0 | 3326 | if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { |
michael@0 | 3327 | resolveValues[ i ].promise() |
michael@0 | 3328 | .done( updateFunc( i, resolveContexts, resolveValues ) ) |
michael@0 | 3329 | .fail( deferred.reject ) |
michael@0 | 3330 | .progress( updateFunc( i, progressContexts, progressValues ) ); |
michael@0 | 3331 | } else { |
michael@0 | 3332 | --remaining; |
michael@0 | 3333 | } |
michael@0 | 3334 | } |
michael@0 | 3335 | } |
michael@0 | 3336 | |
michael@0 | 3337 | // if we're not waiting on anything, resolve the master |
michael@0 | 3338 | if ( !remaining ) { |
michael@0 | 3339 | deferred.resolveWith( resolveContexts, resolveValues ); |
michael@0 | 3340 | } |
michael@0 | 3341 | |
michael@0 | 3342 | return deferred.promise(); |
michael@0 | 3343 | } |
michael@0 | 3344 | }); |
michael@0 | 3345 | |
michael@0 | 3346 | |
michael@0 | 3347 | // The deferred used on DOM ready |
michael@0 | 3348 | var readyList; |
michael@0 | 3349 | |
michael@0 | 3350 | jQuery.fn.ready = function( fn ) { |
michael@0 | 3351 | // Add the callback |
michael@0 | 3352 | jQuery.ready.promise().done( fn ); |
michael@0 | 3353 | |
michael@0 | 3354 | return this; |
michael@0 | 3355 | }; |
michael@0 | 3356 | |
michael@0 | 3357 | jQuery.extend({ |
michael@0 | 3358 | // Is the DOM ready to be used? Set to true once it occurs. |
michael@0 | 3359 | isReady: false, |
michael@0 | 3360 | |
michael@0 | 3361 | // A counter to track how many items to wait for before |
michael@0 | 3362 | // the ready event fires. See #6781 |
michael@0 | 3363 | readyWait: 1, |
michael@0 | 3364 | |
michael@0 | 3365 | // Hold (or release) the ready event |
michael@0 | 3366 | holdReady: function( hold ) { |
michael@0 | 3367 | if ( hold ) { |
michael@0 | 3368 | jQuery.readyWait++; |
michael@0 | 3369 | } else { |
michael@0 | 3370 | jQuery.ready( true ); |
michael@0 | 3371 | } |
michael@0 | 3372 | }, |
michael@0 | 3373 | |
michael@0 | 3374 | // Handle when the DOM is ready |
michael@0 | 3375 | ready: function( wait ) { |
michael@0 | 3376 | |
michael@0 | 3377 | // Abort if there are pending holds or we're already ready |
michael@0 | 3378 | if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { |
michael@0 | 3379 | return; |
michael@0 | 3380 | } |
michael@0 | 3381 | |
michael@0 | 3382 | // Remember that the DOM is ready |
michael@0 | 3383 | jQuery.isReady = true; |
michael@0 | 3384 | |
michael@0 | 3385 | // If a normal DOM Ready event fired, decrement, and wait if need be |
michael@0 | 3386 | if ( wait !== true && --jQuery.readyWait > 0 ) { |
michael@0 | 3387 | return; |
michael@0 | 3388 | } |
michael@0 | 3389 | |
michael@0 | 3390 | // If there are functions bound, to execute |
michael@0 | 3391 | readyList.resolveWith( document, [ jQuery ] ); |
michael@0 | 3392 | |
michael@0 | 3393 | // Trigger any bound ready events |
michael@0 | 3394 | if ( jQuery.fn.triggerHandler ) { |
michael@0 | 3395 | jQuery( document ).triggerHandler( "ready" ); |
michael@0 | 3396 | jQuery( document ).off( "ready" ); |
michael@0 | 3397 | } |
michael@0 | 3398 | } |
michael@0 | 3399 | }); |
michael@0 | 3400 | |
michael@0 | 3401 | /** |
michael@0 | 3402 | * The ready event handler and self cleanup method |
michael@0 | 3403 | */ |
michael@0 | 3404 | function completed() { |
michael@0 | 3405 | document.removeEventListener( "DOMContentLoaded", completed, false ); |
michael@0 | 3406 | window.removeEventListener( "load", completed, false ); |
michael@0 | 3407 | jQuery.ready(); |
michael@0 | 3408 | } |
michael@0 | 3409 | |
michael@0 | 3410 | jQuery.ready.promise = function( obj ) { |
michael@0 | 3411 | if ( !readyList ) { |
michael@0 | 3412 | |
michael@0 | 3413 | readyList = jQuery.Deferred(); |
michael@0 | 3414 | |
michael@0 | 3415 | // Catch cases where $(document).ready() is called after the browser event has already occurred. |
michael@0 | 3416 | // we once tried to use readyState "interactive" here, but it caused issues like the one |
michael@0 | 3417 | // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 |
michael@0 | 3418 | if ( document.readyState === "complete" ) { |
michael@0 | 3419 | // Handle it asynchronously to allow scripts the opportunity to delay ready |
michael@0 | 3420 | setTimeout( jQuery.ready ); |
michael@0 | 3421 | |
michael@0 | 3422 | } else { |
michael@0 | 3423 | |
michael@0 | 3424 | // Use the handy event callback |
michael@0 | 3425 | document.addEventListener( "DOMContentLoaded", completed, false ); |
michael@0 | 3426 | |
michael@0 | 3427 | // A fallback to window.onload, that will always work |
michael@0 | 3428 | window.addEventListener( "load", completed, false ); |
michael@0 | 3429 | } |
michael@0 | 3430 | } |
michael@0 | 3431 | return readyList.promise( obj ); |
michael@0 | 3432 | }; |
michael@0 | 3433 | |
michael@0 | 3434 | // Kick off the DOM ready check even if the user does not |
michael@0 | 3435 | jQuery.ready.promise(); |
michael@0 | 3436 | |
michael@0 | 3437 | |
michael@0 | 3438 | |
michael@0 | 3439 | |
michael@0 | 3440 | // Multifunctional method to get and set values of a collection |
michael@0 | 3441 | // The value/s can optionally be executed if it's a function |
michael@0 | 3442 | var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { |
michael@0 | 3443 | var i = 0, |
michael@0 | 3444 | len = elems.length, |
michael@0 | 3445 | bulk = key == null; |
michael@0 | 3446 | |
michael@0 | 3447 | // Sets many values |
michael@0 | 3448 | if ( jQuery.type( key ) === "object" ) { |
michael@0 | 3449 | chainable = true; |
michael@0 | 3450 | for ( i in key ) { |
michael@0 | 3451 | jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); |
michael@0 | 3452 | } |
michael@0 | 3453 | |
michael@0 | 3454 | // Sets one value |
michael@0 | 3455 | } else if ( value !== undefined ) { |
michael@0 | 3456 | chainable = true; |
michael@0 | 3457 | |
michael@0 | 3458 | if ( !jQuery.isFunction( value ) ) { |
michael@0 | 3459 | raw = true; |
michael@0 | 3460 | } |
michael@0 | 3461 | |
michael@0 | 3462 | if ( bulk ) { |
michael@0 | 3463 | // Bulk operations run against the entire set |
michael@0 | 3464 | if ( raw ) { |
michael@0 | 3465 | fn.call( elems, value ); |
michael@0 | 3466 | fn = null; |
michael@0 | 3467 | |
michael@0 | 3468 | // ...except when executing function values |
michael@0 | 3469 | } else { |
michael@0 | 3470 | bulk = fn; |
michael@0 | 3471 | fn = function( elem, key, value ) { |
michael@0 | 3472 | return bulk.call( jQuery( elem ), value ); |
michael@0 | 3473 | }; |
michael@0 | 3474 | } |
michael@0 | 3475 | } |
michael@0 | 3476 | |
michael@0 | 3477 | if ( fn ) { |
michael@0 | 3478 | for ( ; i < len; i++ ) { |
michael@0 | 3479 | fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); |
michael@0 | 3480 | } |
michael@0 | 3481 | } |
michael@0 | 3482 | } |
michael@0 | 3483 | |
michael@0 | 3484 | return chainable ? |
michael@0 | 3485 | elems : |
michael@0 | 3486 | |
michael@0 | 3487 | // Gets |
michael@0 | 3488 | bulk ? |
michael@0 | 3489 | fn.call( elems ) : |
michael@0 | 3490 | len ? fn( elems[0], key ) : emptyGet; |
michael@0 | 3491 | }; |
michael@0 | 3492 | |
michael@0 | 3493 | |
michael@0 | 3494 | /** |
michael@0 | 3495 | * Determines whether an object can have data |
michael@0 | 3496 | */ |
michael@0 | 3497 | jQuery.acceptData = function( owner ) { |
michael@0 | 3498 | // Accepts only: |
michael@0 | 3499 | // - Node |
michael@0 | 3500 | // - Node.ELEMENT_NODE |
michael@0 | 3501 | // - Node.DOCUMENT_NODE |
michael@0 | 3502 | // - Object |
michael@0 | 3503 | // - Any |
michael@0 | 3504 | /* jshint -W018 */ |
michael@0 | 3505 | return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); |
michael@0 | 3506 | }; |
michael@0 | 3507 | |
michael@0 | 3508 | |
michael@0 | 3509 | function Data() { |
michael@0 | 3510 | // Support: Android < 4, |
michael@0 | 3511 | // Old WebKit does not have Object.preventExtensions/freeze method, |
michael@0 | 3512 | // return new empty object instead with no [[set]] accessor |
michael@0 | 3513 | Object.defineProperty( this.cache = {}, 0, { |
michael@0 | 3514 | get: function() { |
michael@0 | 3515 | return {}; |
michael@0 | 3516 | } |
michael@0 | 3517 | }); |
michael@0 | 3518 | |
michael@0 | 3519 | this.expando = jQuery.expando + Math.random(); |
michael@0 | 3520 | } |
michael@0 | 3521 | |
michael@0 | 3522 | Data.uid = 1; |
michael@0 | 3523 | Data.accepts = jQuery.acceptData; |
michael@0 | 3524 | |
michael@0 | 3525 | Data.prototype = { |
michael@0 | 3526 | key: function( owner ) { |
michael@0 | 3527 | // We can accept data for non-element nodes in modern browsers, |
michael@0 | 3528 | // but we should not, see #8335. |
michael@0 | 3529 | // Always return the key for a frozen object. |
michael@0 | 3530 | if ( !Data.accepts( owner ) ) { |
michael@0 | 3531 | return 0; |
michael@0 | 3532 | } |
michael@0 | 3533 | |
michael@0 | 3534 | var descriptor = {}, |
michael@0 | 3535 | // Check if the owner object already has a cache key |
michael@0 | 3536 | unlock = owner[ this.expando ]; |
michael@0 | 3537 | |
michael@0 | 3538 | // If not, create one |
michael@0 | 3539 | if ( !unlock ) { |
michael@0 | 3540 | unlock = Data.uid++; |
michael@0 | 3541 | |
michael@0 | 3542 | // Secure it in a non-enumerable, non-writable property |
michael@0 | 3543 | try { |
michael@0 | 3544 | descriptor[ this.expando ] = { value: unlock }; |
michael@0 | 3545 | Object.defineProperties( owner, descriptor ); |
michael@0 | 3546 | |
michael@0 | 3547 | // Support: Android < 4 |
michael@0 | 3548 | // Fallback to a less secure definition |
michael@0 | 3549 | } catch ( e ) { |
michael@0 | 3550 | descriptor[ this.expando ] = unlock; |
michael@0 | 3551 | jQuery.extend( owner, descriptor ); |
michael@0 | 3552 | } |
michael@0 | 3553 | } |
michael@0 | 3554 | |
michael@0 | 3555 | // Ensure the cache object |
michael@0 | 3556 | if ( !this.cache[ unlock ] ) { |
michael@0 | 3557 | this.cache[ unlock ] = {}; |
michael@0 | 3558 | } |
michael@0 | 3559 | |
michael@0 | 3560 | return unlock; |
michael@0 | 3561 | }, |
michael@0 | 3562 | set: function( owner, data, value ) { |
michael@0 | 3563 | var prop, |
michael@0 | 3564 | // There may be an unlock assigned to this node, |
michael@0 | 3565 | // if there is no entry for this "owner", create one inline |
michael@0 | 3566 | // and set the unlock as though an owner entry had always existed |
michael@0 | 3567 | unlock = this.key( owner ), |
michael@0 | 3568 | cache = this.cache[ unlock ]; |
michael@0 | 3569 | |
michael@0 | 3570 | // Handle: [ owner, key, value ] args |
michael@0 | 3571 | if ( typeof data === "string" ) { |
michael@0 | 3572 | cache[ data ] = value; |
michael@0 | 3573 | |
michael@0 | 3574 | // Handle: [ owner, { properties } ] args |
michael@0 | 3575 | } else { |
michael@0 | 3576 | // Fresh assignments by object are shallow copied |
michael@0 | 3577 | if ( jQuery.isEmptyObject( cache ) ) { |
michael@0 | 3578 | jQuery.extend( this.cache[ unlock ], data ); |
michael@0 | 3579 | // Otherwise, copy the properties one-by-one to the cache object |
michael@0 | 3580 | } else { |
michael@0 | 3581 | for ( prop in data ) { |
michael@0 | 3582 | cache[ prop ] = data[ prop ]; |
michael@0 | 3583 | } |
michael@0 | 3584 | } |
michael@0 | 3585 | } |
michael@0 | 3586 | return cache; |
michael@0 | 3587 | }, |
michael@0 | 3588 | get: function( owner, key ) { |
michael@0 | 3589 | // Either a valid cache is found, or will be created. |
michael@0 | 3590 | // New caches will be created and the unlock returned, |
michael@0 | 3591 | // allowing direct access to the newly created |
michael@0 | 3592 | // empty data object. A valid owner object must be provided. |
michael@0 | 3593 | var cache = this.cache[ this.key( owner ) ]; |
michael@0 | 3594 | |
michael@0 | 3595 | return key === undefined ? |
michael@0 | 3596 | cache : cache[ key ]; |
michael@0 | 3597 | }, |
michael@0 | 3598 | access: function( owner, key, value ) { |
michael@0 | 3599 | var stored; |
michael@0 | 3600 | // In cases where either: |
michael@0 | 3601 | // |
michael@0 | 3602 | // 1. No key was specified |
michael@0 | 3603 | // 2. A string key was specified, but no value provided |
michael@0 | 3604 | // |
michael@0 | 3605 | // Take the "read" path and allow the get method to determine |
michael@0 | 3606 | // which value to return, respectively either: |
michael@0 | 3607 | // |
michael@0 | 3608 | // 1. The entire cache object |
michael@0 | 3609 | // 2. The data stored at the key |
michael@0 | 3610 | // |
michael@0 | 3611 | if ( key === undefined || |
michael@0 | 3612 | ((key && typeof key === "string") && value === undefined) ) { |
michael@0 | 3613 | |
michael@0 | 3614 | stored = this.get( owner, key ); |
michael@0 | 3615 | |
michael@0 | 3616 | return stored !== undefined ? |
michael@0 | 3617 | stored : this.get( owner, jQuery.camelCase(key) ); |
michael@0 | 3618 | } |
michael@0 | 3619 | |
michael@0 | 3620 | // [*]When the key is not a string, or both a key and value |
michael@0 | 3621 | // are specified, set or extend (existing objects) with either: |
michael@0 | 3622 | // |
michael@0 | 3623 | // 1. An object of properties |
michael@0 | 3624 | // 2. A key and value |
michael@0 | 3625 | // |
michael@0 | 3626 | this.set( owner, key, value ); |
michael@0 | 3627 | |
michael@0 | 3628 | // Since the "set" path can have two possible entry points |
michael@0 | 3629 | // return the expected data based on which path was taken[*] |
michael@0 | 3630 | return value !== undefined ? value : key; |
michael@0 | 3631 | }, |
michael@0 | 3632 | remove: function( owner, key ) { |
michael@0 | 3633 | var i, name, camel, |
michael@0 | 3634 | unlock = this.key( owner ), |
michael@0 | 3635 | cache = this.cache[ unlock ]; |
michael@0 | 3636 | |
michael@0 | 3637 | if ( key === undefined ) { |
michael@0 | 3638 | this.cache[ unlock ] = {}; |
michael@0 | 3639 | |
michael@0 | 3640 | } else { |
michael@0 | 3641 | // Support array or space separated string of keys |
michael@0 | 3642 | if ( jQuery.isArray( key ) ) { |
michael@0 | 3643 | // If "name" is an array of keys... |
michael@0 | 3644 | // When data is initially created, via ("key", "val") signature, |
michael@0 | 3645 | // keys will be converted to camelCase. |
michael@0 | 3646 | // Since there is no way to tell _how_ a key was added, remove |
michael@0 | 3647 | // both plain key and camelCase key. #12786 |
michael@0 | 3648 | // This will only penalize the array argument path. |
michael@0 | 3649 | name = key.concat( key.map( jQuery.camelCase ) ); |
michael@0 | 3650 | } else { |
michael@0 | 3651 | camel = jQuery.camelCase( key ); |
michael@0 | 3652 | // Try the string as a key before any manipulation |
michael@0 | 3653 | if ( key in cache ) { |
michael@0 | 3654 | name = [ key, camel ]; |
michael@0 | 3655 | } else { |
michael@0 | 3656 | // If a key with the spaces exists, use it. |
michael@0 | 3657 | // Otherwise, create an array by matching non-whitespace |
michael@0 | 3658 | name = camel; |
michael@0 | 3659 | name = name in cache ? |
michael@0 | 3660 | [ name ] : ( name.match( rnotwhite ) || [] ); |
michael@0 | 3661 | } |
michael@0 | 3662 | } |
michael@0 | 3663 | |
michael@0 | 3664 | i = name.length; |
michael@0 | 3665 | while ( i-- ) { |
michael@0 | 3666 | delete cache[ name[ i ] ]; |
michael@0 | 3667 | } |
michael@0 | 3668 | } |
michael@0 | 3669 | }, |
michael@0 | 3670 | hasData: function( owner ) { |
michael@0 | 3671 | return !jQuery.isEmptyObject( |
michael@0 | 3672 | this.cache[ owner[ this.expando ] ] || {} |
michael@0 | 3673 | ); |
michael@0 | 3674 | }, |
michael@0 | 3675 | discard: function( owner ) { |
michael@0 | 3676 | if ( owner[ this.expando ] ) { |
michael@0 | 3677 | delete this.cache[ owner[ this.expando ] ]; |
michael@0 | 3678 | } |
michael@0 | 3679 | } |
michael@0 | 3680 | }; |
michael@0 | 3681 | var data_priv = new Data(); |
michael@0 | 3682 | |
michael@0 | 3683 | var data_user = new Data(); |
michael@0 | 3684 | |
michael@0 | 3685 | |
michael@0 | 3686 | |
michael@0 | 3687 | /* |
michael@0 | 3688 | Implementation Summary |
michael@0 | 3689 | |
michael@0 | 3690 | 1. Enforce API surface and semantic compatibility with 1.9.x branch |
michael@0 | 3691 | 2. Improve the module's maintainability by reducing the storage |
michael@0 | 3692 | paths to a single mechanism. |
michael@0 | 3693 | 3. Use the same single mechanism to support "private" and "user" data. |
michael@0 | 3694 | 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) |
michael@0 | 3695 | 5. Avoid exposing implementation details on user objects (eg. expando properties) |
michael@0 | 3696 | 6. Provide a clear path for implementation upgrade to WeakMap in 2014 |
michael@0 | 3697 | */ |
michael@0 | 3698 | var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, |
michael@0 | 3699 | rmultiDash = /([A-Z])/g; |
michael@0 | 3700 | |
michael@0 | 3701 | function dataAttr( elem, key, data ) { |
michael@0 | 3702 | var name; |
michael@0 | 3703 | |
michael@0 | 3704 | // If nothing was found internally, try to fetch any |
michael@0 | 3705 | // data from the HTML5 data-* attribute |
michael@0 | 3706 | if ( data === undefined && elem.nodeType === 1 ) { |
michael@0 | 3707 | name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); |
michael@0 | 3708 | data = elem.getAttribute( name ); |
michael@0 | 3709 | |
michael@0 | 3710 | if ( typeof data === "string" ) { |
michael@0 | 3711 | try { |
michael@0 | 3712 | data = data === "true" ? true : |
michael@0 | 3713 | data === "false" ? false : |
michael@0 | 3714 | data === "null" ? null : |
michael@0 | 3715 | // Only convert to a number if it doesn't change the string |
michael@0 | 3716 | +data + "" === data ? +data : |
michael@0 | 3717 | rbrace.test( data ) ? jQuery.parseJSON( data ) : |
michael@0 | 3718 | data; |
michael@0 | 3719 | } catch( e ) {} |
michael@0 | 3720 | |
michael@0 | 3721 | // Make sure we set the data so it isn't changed later |
michael@0 | 3722 | data_user.set( elem, key, data ); |
michael@0 | 3723 | } else { |
michael@0 | 3724 | data = undefined; |
michael@0 | 3725 | } |
michael@0 | 3726 | } |
michael@0 | 3727 | return data; |
michael@0 | 3728 | } |
michael@0 | 3729 | |
michael@0 | 3730 | jQuery.extend({ |
michael@0 | 3731 | hasData: function( elem ) { |
michael@0 | 3732 | return data_user.hasData( elem ) || data_priv.hasData( elem ); |
michael@0 | 3733 | }, |
michael@0 | 3734 | |
michael@0 | 3735 | data: function( elem, name, data ) { |
michael@0 | 3736 | return data_user.access( elem, name, data ); |
michael@0 | 3737 | }, |
michael@0 | 3738 | |
michael@0 | 3739 | removeData: function( elem, name ) { |
michael@0 | 3740 | data_user.remove( elem, name ); |
michael@0 | 3741 | }, |
michael@0 | 3742 | |
michael@0 | 3743 | // TODO: Now that all calls to _data and _removeData have been replaced |
michael@0 | 3744 | // with direct calls to data_priv methods, these can be deprecated. |
michael@0 | 3745 | _data: function( elem, name, data ) { |
michael@0 | 3746 | return data_priv.access( elem, name, data ); |
michael@0 | 3747 | }, |
michael@0 | 3748 | |
michael@0 | 3749 | _removeData: function( elem, name ) { |
michael@0 | 3750 | data_priv.remove( elem, name ); |
michael@0 | 3751 | } |
michael@0 | 3752 | }); |
michael@0 | 3753 | |
michael@0 | 3754 | jQuery.fn.extend({ |
michael@0 | 3755 | data: function( key, value ) { |
michael@0 | 3756 | var i, name, data, |
michael@0 | 3757 | elem = this[ 0 ], |
michael@0 | 3758 | attrs = elem && elem.attributes; |
michael@0 | 3759 | |
michael@0 | 3760 | // Gets all values |
michael@0 | 3761 | if ( key === undefined ) { |
michael@0 | 3762 | if ( this.length ) { |
michael@0 | 3763 | data = data_user.get( elem ); |
michael@0 | 3764 | |
michael@0 | 3765 | if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { |
michael@0 | 3766 | i = attrs.length; |
michael@0 | 3767 | while ( i-- ) { |
michael@0 | 3768 | |
michael@0 | 3769 | // Support: IE11+ |
michael@0 | 3770 | // The attrs elements can be null (#14894) |
michael@0 | 3771 | if ( attrs[ i ] ) { |
michael@0 | 3772 | name = attrs[ i ].name; |
michael@0 | 3773 | if ( name.indexOf( "data-" ) === 0 ) { |
michael@0 | 3774 | name = jQuery.camelCase( name.slice(5) ); |
michael@0 | 3775 | dataAttr( elem, name, data[ name ] ); |
michael@0 | 3776 | } |
michael@0 | 3777 | } |
michael@0 | 3778 | } |
michael@0 | 3779 | data_priv.set( elem, "hasDataAttrs", true ); |
michael@0 | 3780 | } |
michael@0 | 3781 | } |
michael@0 | 3782 | |
michael@0 | 3783 | return data; |
michael@0 | 3784 | } |
michael@0 | 3785 | |
michael@0 | 3786 | // Sets multiple values |
michael@0 | 3787 | if ( typeof key === "object" ) { |
michael@0 | 3788 | return this.each(function() { |
michael@0 | 3789 | data_user.set( this, key ); |
michael@0 | 3790 | }); |
michael@0 | 3791 | } |
michael@0 | 3792 | |
michael@0 | 3793 | return access( this, function( value ) { |
michael@0 | 3794 | var data, |
michael@0 | 3795 | camelKey = jQuery.camelCase( key ); |
michael@0 | 3796 | |
michael@0 | 3797 | // The calling jQuery object (element matches) is not empty |
michael@0 | 3798 | // (and therefore has an element appears at this[ 0 ]) and the |
michael@0 | 3799 | // `value` parameter was not undefined. An empty jQuery object |
michael@0 | 3800 | // will result in `undefined` for elem = this[ 0 ] which will |
michael@0 | 3801 | // throw an exception if an attempt to read a data cache is made. |
michael@0 | 3802 | if ( elem && value === undefined ) { |
michael@0 | 3803 | // Attempt to get data from the cache |
michael@0 | 3804 | // with the key as-is |
michael@0 | 3805 | data = data_user.get( elem, key ); |
michael@0 | 3806 | if ( data !== undefined ) { |
michael@0 | 3807 | return data; |
michael@0 | 3808 | } |
michael@0 | 3809 | |
michael@0 | 3810 | // Attempt to get data from the cache |
michael@0 | 3811 | // with the key camelized |
michael@0 | 3812 | data = data_user.get( elem, camelKey ); |
michael@0 | 3813 | if ( data !== undefined ) { |
michael@0 | 3814 | return data; |
michael@0 | 3815 | } |
michael@0 | 3816 | |
michael@0 | 3817 | // Attempt to "discover" the data in |
michael@0 | 3818 | // HTML5 custom data-* attrs |
michael@0 | 3819 | data = dataAttr( elem, camelKey, undefined ); |
michael@0 | 3820 | if ( data !== undefined ) { |
michael@0 | 3821 | return data; |
michael@0 | 3822 | } |
michael@0 | 3823 | |
michael@0 | 3824 | // We tried really hard, but the data doesn't exist. |
michael@0 | 3825 | return; |
michael@0 | 3826 | } |
michael@0 | 3827 | |
michael@0 | 3828 | // Set the data... |
michael@0 | 3829 | this.each(function() { |
michael@0 | 3830 | // First, attempt to store a copy or reference of any |
michael@0 | 3831 | // data that might've been store with a camelCased key. |
michael@0 | 3832 | var data = data_user.get( this, camelKey ); |
michael@0 | 3833 | |
michael@0 | 3834 | // For HTML5 data-* attribute interop, we have to |
michael@0 | 3835 | // store property names with dashes in a camelCase form. |
michael@0 | 3836 | // This might not apply to all properties...* |
michael@0 | 3837 | data_user.set( this, camelKey, value ); |
michael@0 | 3838 | |
michael@0 | 3839 | // *... In the case of properties that might _actually_ |
michael@0 | 3840 | // have dashes, we need to also store a copy of that |
michael@0 | 3841 | // unchanged property. |
michael@0 | 3842 | if ( key.indexOf("-") !== -1 && data !== undefined ) { |
michael@0 | 3843 | data_user.set( this, key, value ); |
michael@0 | 3844 | } |
michael@0 | 3845 | }); |
michael@0 | 3846 | }, null, value, arguments.length > 1, null, true ); |
michael@0 | 3847 | }, |
michael@0 | 3848 | |
michael@0 | 3849 | removeData: function( key ) { |
michael@0 | 3850 | return this.each(function() { |
michael@0 | 3851 | data_user.remove( this, key ); |
michael@0 | 3852 | }); |
michael@0 | 3853 | } |
michael@0 | 3854 | }); |
michael@0 | 3855 | |
michael@0 | 3856 | |
michael@0 | 3857 | jQuery.extend({ |
michael@0 | 3858 | queue: function( elem, type, data ) { |
michael@0 | 3859 | var queue; |
michael@0 | 3860 | |
michael@0 | 3861 | if ( elem ) { |
michael@0 | 3862 | type = ( type || "fx" ) + "queue"; |
michael@0 | 3863 | queue = data_priv.get( elem, type ); |
michael@0 | 3864 | |
michael@0 | 3865 | // Speed up dequeue by getting out quickly if this is just a lookup |
michael@0 | 3866 | if ( data ) { |
michael@0 | 3867 | if ( !queue || jQuery.isArray( data ) ) { |
michael@0 | 3868 | queue = data_priv.access( elem, type, jQuery.makeArray(data) ); |
michael@0 | 3869 | } else { |
michael@0 | 3870 | queue.push( data ); |
michael@0 | 3871 | } |
michael@0 | 3872 | } |
michael@0 | 3873 | return queue || []; |
michael@0 | 3874 | } |
michael@0 | 3875 | }, |
michael@0 | 3876 | |
michael@0 | 3877 | dequeue: function( elem, type ) { |
michael@0 | 3878 | type = type || "fx"; |
michael@0 | 3879 | |
michael@0 | 3880 | var queue = jQuery.queue( elem, type ), |
michael@0 | 3881 | startLength = queue.length, |
michael@0 | 3882 | fn = queue.shift(), |
michael@0 | 3883 | hooks = jQuery._queueHooks( elem, type ), |
michael@0 | 3884 | next = function() { |
michael@0 | 3885 | jQuery.dequeue( elem, type ); |
michael@0 | 3886 | }; |
michael@0 | 3887 | |
michael@0 | 3888 | // If the fx queue is dequeued, always remove the progress sentinel |
michael@0 | 3889 | if ( fn === "inprogress" ) { |
michael@0 | 3890 | fn = queue.shift(); |
michael@0 | 3891 | startLength--; |
michael@0 | 3892 | } |
michael@0 | 3893 | |
michael@0 | 3894 | if ( fn ) { |
michael@0 | 3895 | |
michael@0 | 3896 | // Add a progress sentinel to prevent the fx queue from being |
michael@0 | 3897 | // automatically dequeued |
michael@0 | 3898 | if ( type === "fx" ) { |
michael@0 | 3899 | queue.unshift( "inprogress" ); |
michael@0 | 3900 | } |
michael@0 | 3901 | |
michael@0 | 3902 | // clear up the last queue stop function |
michael@0 | 3903 | delete hooks.stop; |
michael@0 | 3904 | fn.call( elem, next, hooks ); |
michael@0 | 3905 | } |
michael@0 | 3906 | |
michael@0 | 3907 | if ( !startLength && hooks ) { |
michael@0 | 3908 | hooks.empty.fire(); |
michael@0 | 3909 | } |
michael@0 | 3910 | }, |
michael@0 | 3911 | |
michael@0 | 3912 | // not intended for public consumption - generates a queueHooks object, or returns the current one |
michael@0 | 3913 | _queueHooks: function( elem, type ) { |
michael@0 | 3914 | var key = type + "queueHooks"; |
michael@0 | 3915 | return data_priv.get( elem, key ) || data_priv.access( elem, key, { |
michael@0 | 3916 | empty: jQuery.Callbacks("once memory").add(function() { |
michael@0 | 3917 | data_priv.remove( elem, [ type + "queue", key ] ); |
michael@0 | 3918 | }) |
michael@0 | 3919 | }); |
michael@0 | 3920 | } |
michael@0 | 3921 | }); |
michael@0 | 3922 | |
michael@0 | 3923 | jQuery.fn.extend({ |
michael@0 | 3924 | queue: function( type, data ) { |
michael@0 | 3925 | var setter = 2; |
michael@0 | 3926 | |
michael@0 | 3927 | if ( typeof type !== "string" ) { |
michael@0 | 3928 | data = type; |
michael@0 | 3929 | type = "fx"; |
michael@0 | 3930 | setter--; |
michael@0 | 3931 | } |
michael@0 | 3932 | |
michael@0 | 3933 | if ( arguments.length < setter ) { |
michael@0 | 3934 | return jQuery.queue( this[0], type ); |
michael@0 | 3935 | } |
michael@0 | 3936 | |
michael@0 | 3937 | return data === undefined ? |
michael@0 | 3938 | this : |
michael@0 | 3939 | this.each(function() { |
michael@0 | 3940 | var queue = jQuery.queue( this, type, data ); |
michael@0 | 3941 | |
michael@0 | 3942 | // ensure a hooks for this queue |
michael@0 | 3943 | jQuery._queueHooks( this, type ); |
michael@0 | 3944 | |
michael@0 | 3945 | if ( type === "fx" && queue[0] !== "inprogress" ) { |
michael@0 | 3946 | jQuery.dequeue( this, type ); |
michael@0 | 3947 | } |
michael@0 | 3948 | }); |
michael@0 | 3949 | }, |
michael@0 | 3950 | dequeue: function( type ) { |
michael@0 | 3951 | return this.each(function() { |
michael@0 | 3952 | jQuery.dequeue( this, type ); |
michael@0 | 3953 | }); |
michael@0 | 3954 | }, |
michael@0 | 3955 | clearQueue: function( type ) { |
michael@0 | 3956 | return this.queue( type || "fx", [] ); |
michael@0 | 3957 | }, |
michael@0 | 3958 | // Get a promise resolved when queues of a certain type |
michael@0 | 3959 | // are emptied (fx is the type by default) |
michael@0 | 3960 | promise: function( type, obj ) { |
michael@0 | 3961 | var tmp, |
michael@0 | 3962 | count = 1, |
michael@0 | 3963 | defer = jQuery.Deferred(), |
michael@0 | 3964 | elements = this, |
michael@0 | 3965 | i = this.length, |
michael@0 | 3966 | resolve = function() { |
michael@0 | 3967 | if ( !( --count ) ) { |
michael@0 | 3968 | defer.resolveWith( elements, [ elements ] ); |
michael@0 | 3969 | } |
michael@0 | 3970 | }; |
michael@0 | 3971 | |
michael@0 | 3972 | if ( typeof type !== "string" ) { |
michael@0 | 3973 | obj = type; |
michael@0 | 3974 | type = undefined; |
michael@0 | 3975 | } |
michael@0 | 3976 | type = type || "fx"; |
michael@0 | 3977 | |
michael@0 | 3978 | while ( i-- ) { |
michael@0 | 3979 | tmp = data_priv.get( elements[ i ], type + "queueHooks" ); |
michael@0 | 3980 | if ( tmp && tmp.empty ) { |
michael@0 | 3981 | count++; |
michael@0 | 3982 | tmp.empty.add( resolve ); |
michael@0 | 3983 | } |
michael@0 | 3984 | } |
michael@0 | 3985 | resolve(); |
michael@0 | 3986 | return defer.promise( obj ); |
michael@0 | 3987 | } |
michael@0 | 3988 | }); |
michael@0 | 3989 | var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; |
michael@0 | 3990 | |
michael@0 | 3991 | var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; |
michael@0 | 3992 | |
michael@0 | 3993 | var isHidden = function( elem, el ) { |
michael@0 | 3994 | // isHidden might be called from jQuery#filter function; |
michael@0 | 3995 | // in that case, element will be second argument |
michael@0 | 3996 | elem = el || elem; |
michael@0 | 3997 | return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); |
michael@0 | 3998 | }; |
michael@0 | 3999 | |
michael@0 | 4000 | var rcheckableType = (/^(?:checkbox|radio)$/i); |
michael@0 | 4001 | |
michael@0 | 4002 | |
michael@0 | 4003 | |
michael@0 | 4004 | (function() { |
michael@0 | 4005 | var fragment = document.createDocumentFragment(), |
michael@0 | 4006 | div = fragment.appendChild( document.createElement( "div" ) ), |
michael@0 | 4007 | input = document.createElement( "input" ); |
michael@0 | 4008 | |
michael@0 | 4009 | // #11217 - WebKit loses check when the name is after the checked attribute |
michael@0 | 4010 | // Support: Windows Web Apps (WWA) |
michael@0 | 4011 | // `name` and `type` need .setAttribute for WWA |
michael@0 | 4012 | input.setAttribute( "type", "radio" ); |
michael@0 | 4013 | input.setAttribute( "checked", "checked" ); |
michael@0 | 4014 | input.setAttribute( "name", "t" ); |
michael@0 | 4015 | |
michael@0 | 4016 | div.appendChild( input ); |
michael@0 | 4017 | |
michael@0 | 4018 | // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 |
michael@0 | 4019 | // old WebKit doesn't clone checked state correctly in fragments |
michael@0 | 4020 | support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; |
michael@0 | 4021 | |
michael@0 | 4022 | // Make sure textarea (and checkbox) defaultValue is properly cloned |
michael@0 | 4023 | // Support: IE9-IE11+ |
michael@0 | 4024 | div.innerHTML = "<textarea>x</textarea>"; |
michael@0 | 4025 | support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; |
michael@0 | 4026 | })(); |
michael@0 | 4027 | var strundefined = typeof undefined; |
michael@0 | 4028 | |
michael@0 | 4029 | |
michael@0 | 4030 | |
michael@0 | 4031 | support.focusinBubbles = "onfocusin" in window; |
michael@0 | 4032 | |
michael@0 | 4033 | |
michael@0 | 4034 | var |
michael@0 | 4035 | rkeyEvent = /^key/, |
michael@0 | 4036 | rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, |
michael@0 | 4037 | rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, |
michael@0 | 4038 | rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; |
michael@0 | 4039 | |
michael@0 | 4040 | function returnTrue() { |
michael@0 | 4041 | return true; |
michael@0 | 4042 | } |
michael@0 | 4043 | |
michael@0 | 4044 | function returnFalse() { |
michael@0 | 4045 | return false; |
michael@0 | 4046 | } |
michael@0 | 4047 | |
michael@0 | 4048 | function safeActiveElement() { |
michael@0 | 4049 | try { |
michael@0 | 4050 | return document.activeElement; |
michael@0 | 4051 | } catch ( err ) { } |
michael@0 | 4052 | } |
michael@0 | 4053 | |
michael@0 | 4054 | /* |
michael@0 | 4055 | * Helper functions for managing events -- not part of the public interface. |
michael@0 | 4056 | * Props to Dean Edwards' addEvent library for many of the ideas. |
michael@0 | 4057 | */ |
michael@0 | 4058 | jQuery.event = { |
michael@0 | 4059 | |
michael@0 | 4060 | global: {}, |
michael@0 | 4061 | |
michael@0 | 4062 | add: function( elem, types, handler, data, selector ) { |
michael@0 | 4063 | |
michael@0 | 4064 | var handleObjIn, eventHandle, tmp, |
michael@0 | 4065 | events, t, handleObj, |
michael@0 | 4066 | special, handlers, type, namespaces, origType, |
michael@0 | 4067 | elemData = data_priv.get( elem ); |
michael@0 | 4068 | |
michael@0 | 4069 | // Don't attach events to noData or text/comment nodes (but allow plain objects) |
michael@0 | 4070 | if ( !elemData ) { |
michael@0 | 4071 | return; |
michael@0 | 4072 | } |
michael@0 | 4073 | |
michael@0 | 4074 | // Caller can pass in an object of custom data in lieu of the handler |
michael@0 | 4075 | if ( handler.handler ) { |
michael@0 | 4076 | handleObjIn = handler; |
michael@0 | 4077 | handler = handleObjIn.handler; |
michael@0 | 4078 | selector = handleObjIn.selector; |
michael@0 | 4079 | } |
michael@0 | 4080 | |
michael@0 | 4081 | // Make sure that the handler has a unique ID, used to find/remove it later |
michael@0 | 4082 | if ( !handler.guid ) { |
michael@0 | 4083 | handler.guid = jQuery.guid++; |
michael@0 | 4084 | } |
michael@0 | 4085 | |
michael@0 | 4086 | // Init the element's event structure and main handler, if this is the first |
michael@0 | 4087 | if ( !(events = elemData.events) ) { |
michael@0 | 4088 | events = elemData.events = {}; |
michael@0 | 4089 | } |
michael@0 | 4090 | if ( !(eventHandle = elemData.handle) ) { |
michael@0 | 4091 | eventHandle = elemData.handle = function( e ) { |
michael@0 | 4092 | // Discard the second event of a jQuery.event.trigger() and |
michael@0 | 4093 | // when an event is called after a page has unloaded |
michael@0 | 4094 | return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? |
michael@0 | 4095 | jQuery.event.dispatch.apply( elem, arguments ) : undefined; |
michael@0 | 4096 | }; |
michael@0 | 4097 | } |
michael@0 | 4098 | |
michael@0 | 4099 | // Handle multiple events separated by a space |
michael@0 | 4100 | types = ( types || "" ).match( rnotwhite ) || [ "" ]; |
michael@0 | 4101 | t = types.length; |
michael@0 | 4102 | while ( t-- ) { |
michael@0 | 4103 | tmp = rtypenamespace.exec( types[t] ) || []; |
michael@0 | 4104 | type = origType = tmp[1]; |
michael@0 | 4105 | namespaces = ( tmp[2] || "" ).split( "." ).sort(); |
michael@0 | 4106 | |
michael@0 | 4107 | // There *must* be a type, no attaching namespace-only handlers |
michael@0 | 4108 | if ( !type ) { |
michael@0 | 4109 | continue; |
michael@0 | 4110 | } |
michael@0 | 4111 | |
michael@0 | 4112 | // If event changes its type, use the special event handlers for the changed type |
michael@0 | 4113 | special = jQuery.event.special[ type ] || {}; |
michael@0 | 4114 | |
michael@0 | 4115 | // If selector defined, determine special event api type, otherwise given type |
michael@0 | 4116 | type = ( selector ? special.delegateType : special.bindType ) || type; |
michael@0 | 4117 | |
michael@0 | 4118 | // Update special based on newly reset type |
michael@0 | 4119 | special = jQuery.event.special[ type ] || {}; |
michael@0 | 4120 | |
michael@0 | 4121 | // handleObj is passed to all event handlers |
michael@0 | 4122 | handleObj = jQuery.extend({ |
michael@0 | 4123 | type: type, |
michael@0 | 4124 | origType: origType, |
michael@0 | 4125 | data: data, |
michael@0 | 4126 | handler: handler, |
michael@0 | 4127 | guid: handler.guid, |
michael@0 | 4128 | selector: selector, |
michael@0 | 4129 | needsContext: selector && jQuery.expr.match.needsContext.test( selector ), |
michael@0 | 4130 | namespace: namespaces.join(".") |
michael@0 | 4131 | }, handleObjIn ); |
michael@0 | 4132 | |
michael@0 | 4133 | // Init the event handler queue if we're the first |
michael@0 | 4134 | if ( !(handlers = events[ type ]) ) { |
michael@0 | 4135 | handlers = events[ type ] = []; |
michael@0 | 4136 | handlers.delegateCount = 0; |
michael@0 | 4137 | |
michael@0 | 4138 | // Only use addEventListener if the special events handler returns false |
michael@0 | 4139 | if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { |
michael@0 | 4140 | if ( elem.addEventListener ) { |
michael@0 | 4141 | elem.addEventListener( type, eventHandle, false ); |
michael@0 | 4142 | } |
michael@0 | 4143 | } |
michael@0 | 4144 | } |
michael@0 | 4145 | |
michael@0 | 4146 | if ( special.add ) { |
michael@0 | 4147 | special.add.call( elem, handleObj ); |
michael@0 | 4148 | |
michael@0 | 4149 | if ( !handleObj.handler.guid ) { |
michael@0 | 4150 | handleObj.handler.guid = handler.guid; |
michael@0 | 4151 | } |
michael@0 | 4152 | } |
michael@0 | 4153 | |
michael@0 | 4154 | // Add to the element's handler list, delegates in front |
michael@0 | 4155 | if ( selector ) { |
michael@0 | 4156 | handlers.splice( handlers.delegateCount++, 0, handleObj ); |
michael@0 | 4157 | } else { |
michael@0 | 4158 | handlers.push( handleObj ); |
michael@0 | 4159 | } |
michael@0 | 4160 | |
michael@0 | 4161 | // Keep track of which events have ever been used, for event optimization |
michael@0 | 4162 | jQuery.event.global[ type ] = true; |
michael@0 | 4163 | } |
michael@0 | 4164 | |
michael@0 | 4165 | }, |
michael@0 | 4166 | |
michael@0 | 4167 | // Detach an event or set of events from an element |
michael@0 | 4168 | remove: function( elem, types, handler, selector, mappedTypes ) { |
michael@0 | 4169 | |
michael@0 | 4170 | var j, origCount, tmp, |
michael@0 | 4171 | events, t, handleObj, |
michael@0 | 4172 | special, handlers, type, namespaces, origType, |
michael@0 | 4173 | elemData = data_priv.hasData( elem ) && data_priv.get( elem ); |
michael@0 | 4174 | |
michael@0 | 4175 | if ( !elemData || !(events = elemData.events) ) { |
michael@0 | 4176 | return; |
michael@0 | 4177 | } |
michael@0 | 4178 | |
michael@0 | 4179 | // Once for each type.namespace in types; type may be omitted |
michael@0 | 4180 | types = ( types || "" ).match( rnotwhite ) || [ "" ]; |
michael@0 | 4181 | t = types.length; |
michael@0 | 4182 | while ( t-- ) { |
michael@0 | 4183 | tmp = rtypenamespace.exec( types[t] ) || []; |
michael@0 | 4184 | type = origType = tmp[1]; |
michael@0 | 4185 | namespaces = ( tmp[2] || "" ).split( "." ).sort(); |
michael@0 | 4186 | |
michael@0 | 4187 | // Unbind all events (on this namespace, if provided) for the element |
michael@0 | 4188 | if ( !type ) { |
michael@0 | 4189 | for ( type in events ) { |
michael@0 | 4190 | jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); |
michael@0 | 4191 | } |
michael@0 | 4192 | continue; |
michael@0 | 4193 | } |
michael@0 | 4194 | |
michael@0 | 4195 | special = jQuery.event.special[ type ] || {}; |
michael@0 | 4196 | type = ( selector ? special.delegateType : special.bindType ) || type; |
michael@0 | 4197 | handlers = events[ type ] || []; |
michael@0 | 4198 | tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); |
michael@0 | 4199 | |
michael@0 | 4200 | // Remove matching events |
michael@0 | 4201 | origCount = j = handlers.length; |
michael@0 | 4202 | while ( j-- ) { |
michael@0 | 4203 | handleObj = handlers[ j ]; |
michael@0 | 4204 | |
michael@0 | 4205 | if ( ( mappedTypes || origType === handleObj.origType ) && |
michael@0 | 4206 | ( !handler || handler.guid === handleObj.guid ) && |
michael@0 | 4207 | ( !tmp || tmp.test( handleObj.namespace ) ) && |
michael@0 | 4208 | ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { |
michael@0 | 4209 | handlers.splice( j, 1 ); |
michael@0 | 4210 | |
michael@0 | 4211 | if ( handleObj.selector ) { |
michael@0 | 4212 | handlers.delegateCount--; |
michael@0 | 4213 | } |
michael@0 | 4214 | if ( special.remove ) { |
michael@0 | 4215 | special.remove.call( elem, handleObj ); |
michael@0 | 4216 | } |
michael@0 | 4217 | } |
michael@0 | 4218 | } |
michael@0 | 4219 | |
michael@0 | 4220 | // Remove generic event handler if we removed something and no more handlers exist |
michael@0 | 4221 | // (avoids potential for endless recursion during removal of special event handlers) |
michael@0 | 4222 | if ( origCount && !handlers.length ) { |
michael@0 | 4223 | if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { |
michael@0 | 4224 | jQuery.removeEvent( elem, type, elemData.handle ); |
michael@0 | 4225 | } |
michael@0 | 4226 | |
michael@0 | 4227 | delete events[ type ]; |
michael@0 | 4228 | } |
michael@0 | 4229 | } |
michael@0 | 4230 | |
michael@0 | 4231 | // Remove the expando if it's no longer used |
michael@0 | 4232 | if ( jQuery.isEmptyObject( events ) ) { |
michael@0 | 4233 | delete elemData.handle; |
michael@0 | 4234 | data_priv.remove( elem, "events" ); |
michael@0 | 4235 | } |
michael@0 | 4236 | }, |
michael@0 | 4237 | |
michael@0 | 4238 | trigger: function( event, data, elem, onlyHandlers ) { |
michael@0 | 4239 | |
michael@0 | 4240 | var i, cur, tmp, bubbleType, ontype, handle, special, |
michael@0 | 4241 | eventPath = [ elem || document ], |
michael@0 | 4242 | type = hasOwn.call( event, "type" ) ? event.type : event, |
michael@0 | 4243 | namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; |
michael@0 | 4244 | |
michael@0 | 4245 | cur = tmp = elem = elem || document; |
michael@0 | 4246 | |
michael@0 | 4247 | // Don't do events on text and comment nodes |
michael@0 | 4248 | if ( elem.nodeType === 3 || elem.nodeType === 8 ) { |
michael@0 | 4249 | return; |
michael@0 | 4250 | } |
michael@0 | 4251 | |
michael@0 | 4252 | // focus/blur morphs to focusin/out; ensure we're not firing them right now |
michael@0 | 4253 | if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { |
michael@0 | 4254 | return; |
michael@0 | 4255 | } |
michael@0 | 4256 | |
michael@0 | 4257 | if ( type.indexOf(".") >= 0 ) { |
michael@0 | 4258 | // Namespaced trigger; create a regexp to match event type in handle() |
michael@0 | 4259 | namespaces = type.split("."); |
michael@0 | 4260 | type = namespaces.shift(); |
michael@0 | 4261 | namespaces.sort(); |
michael@0 | 4262 | } |
michael@0 | 4263 | ontype = type.indexOf(":") < 0 && "on" + type; |
michael@0 | 4264 | |
michael@0 | 4265 | // Caller can pass in a jQuery.Event object, Object, or just an event type string |
michael@0 | 4266 | event = event[ jQuery.expando ] ? |
michael@0 | 4267 | event : |
michael@0 | 4268 | new jQuery.Event( type, typeof event === "object" && event ); |
michael@0 | 4269 | |
michael@0 | 4270 | // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) |
michael@0 | 4271 | event.isTrigger = onlyHandlers ? 2 : 3; |
michael@0 | 4272 | event.namespace = namespaces.join("."); |
michael@0 | 4273 | event.namespace_re = event.namespace ? |
michael@0 | 4274 | new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : |
michael@0 | 4275 | null; |
michael@0 | 4276 | |
michael@0 | 4277 | // Clean up the event in case it is being reused |
michael@0 | 4278 | event.result = undefined; |
michael@0 | 4279 | if ( !event.target ) { |
michael@0 | 4280 | event.target = elem; |
michael@0 | 4281 | } |
michael@0 | 4282 | |
michael@0 | 4283 | // Clone any incoming data and prepend the event, creating the handler arg list |
michael@0 | 4284 | data = data == null ? |
michael@0 | 4285 | [ event ] : |
michael@0 | 4286 | jQuery.makeArray( data, [ event ] ); |
michael@0 | 4287 | |
michael@0 | 4288 | // Allow special events to draw outside the lines |
michael@0 | 4289 | special = jQuery.event.special[ type ] || {}; |
michael@0 | 4290 | if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { |
michael@0 | 4291 | return; |
michael@0 | 4292 | } |
michael@0 | 4293 | |
michael@0 | 4294 | // Determine event propagation path in advance, per W3C events spec (#9951) |
michael@0 | 4295 | // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) |
michael@0 | 4296 | if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { |
michael@0 | 4297 | |
michael@0 | 4298 | bubbleType = special.delegateType || type; |
michael@0 | 4299 | if ( !rfocusMorph.test( bubbleType + type ) ) { |
michael@0 | 4300 | cur = cur.parentNode; |
michael@0 | 4301 | } |
michael@0 | 4302 | for ( ; cur; cur = cur.parentNode ) { |
michael@0 | 4303 | eventPath.push( cur ); |
michael@0 | 4304 | tmp = cur; |
michael@0 | 4305 | } |
michael@0 | 4306 | |
michael@0 | 4307 | // Only add window if we got to document (e.g., not plain obj or detached DOM) |
michael@0 | 4308 | if ( tmp === (elem.ownerDocument || document) ) { |
michael@0 | 4309 | eventPath.push( tmp.defaultView || tmp.parentWindow || window ); |
michael@0 | 4310 | } |
michael@0 | 4311 | } |
michael@0 | 4312 | |
michael@0 | 4313 | // Fire handlers on the event path |
michael@0 | 4314 | i = 0; |
michael@0 | 4315 | while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { |
michael@0 | 4316 | |
michael@0 | 4317 | event.type = i > 1 ? |
michael@0 | 4318 | bubbleType : |
michael@0 | 4319 | special.bindType || type; |
michael@0 | 4320 | |
michael@0 | 4321 | // jQuery handler |
michael@0 | 4322 | handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); |
michael@0 | 4323 | if ( handle ) { |
michael@0 | 4324 | handle.apply( cur, data ); |
michael@0 | 4325 | } |
michael@0 | 4326 | |
michael@0 | 4327 | // Native handler |
michael@0 | 4328 | handle = ontype && cur[ ontype ]; |
michael@0 | 4329 | if ( handle && handle.apply && jQuery.acceptData( cur ) ) { |
michael@0 | 4330 | event.result = handle.apply( cur, data ); |
michael@0 | 4331 | if ( event.result === false ) { |
michael@0 | 4332 | event.preventDefault(); |
michael@0 | 4333 | } |
michael@0 | 4334 | } |
michael@0 | 4335 | } |
michael@0 | 4336 | event.type = type; |
michael@0 | 4337 | |
michael@0 | 4338 | // If nobody prevented the default action, do it now |
michael@0 | 4339 | if ( !onlyHandlers && !event.isDefaultPrevented() ) { |
michael@0 | 4340 | |
michael@0 | 4341 | if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && |
michael@0 | 4342 | jQuery.acceptData( elem ) ) { |
michael@0 | 4343 | |
michael@0 | 4344 | // Call a native DOM method on the target with the same name name as the event. |
michael@0 | 4345 | // Don't do default actions on window, that's where global variables be (#6170) |
michael@0 | 4346 | if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { |
michael@0 | 4347 | |
michael@0 | 4348 | // Don't re-trigger an onFOO event when we call its FOO() method |
michael@0 | 4349 | tmp = elem[ ontype ]; |
michael@0 | 4350 | |
michael@0 | 4351 | if ( tmp ) { |
michael@0 | 4352 | elem[ ontype ] = null; |
michael@0 | 4353 | } |
michael@0 | 4354 | |
michael@0 | 4355 | // Prevent re-triggering of the same event, since we already bubbled it above |
michael@0 | 4356 | jQuery.event.triggered = type; |
michael@0 | 4357 | elem[ type ](); |
michael@0 | 4358 | jQuery.event.triggered = undefined; |
michael@0 | 4359 | |
michael@0 | 4360 | if ( tmp ) { |
michael@0 | 4361 | elem[ ontype ] = tmp; |
michael@0 | 4362 | } |
michael@0 | 4363 | } |
michael@0 | 4364 | } |
michael@0 | 4365 | } |
michael@0 | 4366 | |
michael@0 | 4367 | return event.result; |
michael@0 | 4368 | }, |
michael@0 | 4369 | |
michael@0 | 4370 | dispatch: function( event ) { |
michael@0 | 4371 | |
michael@0 | 4372 | // Make a writable jQuery.Event from the native event object |
michael@0 | 4373 | event = jQuery.event.fix( event ); |
michael@0 | 4374 | |
michael@0 | 4375 | var i, j, ret, matched, handleObj, |
michael@0 | 4376 | handlerQueue = [], |
michael@0 | 4377 | args = slice.call( arguments ), |
michael@0 | 4378 | handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], |
michael@0 | 4379 | special = jQuery.event.special[ event.type ] || {}; |
michael@0 | 4380 | |
michael@0 | 4381 | // Use the fix-ed jQuery.Event rather than the (read-only) native event |
michael@0 | 4382 | args[0] = event; |
michael@0 | 4383 | event.delegateTarget = this; |
michael@0 | 4384 | |
michael@0 | 4385 | // Call the preDispatch hook for the mapped type, and let it bail if desired |
michael@0 | 4386 | if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { |
michael@0 | 4387 | return; |
michael@0 | 4388 | } |
michael@0 | 4389 | |
michael@0 | 4390 | // Determine handlers |
michael@0 | 4391 | handlerQueue = jQuery.event.handlers.call( this, event, handlers ); |
michael@0 | 4392 | |
michael@0 | 4393 | // Run delegates first; they may want to stop propagation beneath us |
michael@0 | 4394 | i = 0; |
michael@0 | 4395 | while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { |
michael@0 | 4396 | event.currentTarget = matched.elem; |
michael@0 | 4397 | |
michael@0 | 4398 | j = 0; |
michael@0 | 4399 | while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { |
michael@0 | 4400 | |
michael@0 | 4401 | // Triggered event must either 1) have no namespace, or |
michael@0 | 4402 | // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). |
michael@0 | 4403 | if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { |
michael@0 | 4404 | |
michael@0 | 4405 | event.handleObj = handleObj; |
michael@0 | 4406 | event.data = handleObj.data; |
michael@0 | 4407 | |
michael@0 | 4408 | ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) |
michael@0 | 4409 | .apply( matched.elem, args ); |
michael@0 | 4410 | |
michael@0 | 4411 | if ( ret !== undefined ) { |
michael@0 | 4412 | if ( (event.result = ret) === false ) { |
michael@0 | 4413 | event.preventDefault(); |
michael@0 | 4414 | event.stopPropagation(); |
michael@0 | 4415 | } |
michael@0 | 4416 | } |
michael@0 | 4417 | } |
michael@0 | 4418 | } |
michael@0 | 4419 | } |
michael@0 | 4420 | |
michael@0 | 4421 | // Call the postDispatch hook for the mapped type |
michael@0 | 4422 | if ( special.postDispatch ) { |
michael@0 | 4423 | special.postDispatch.call( this, event ); |
michael@0 | 4424 | } |
michael@0 | 4425 | |
michael@0 | 4426 | return event.result; |
michael@0 | 4427 | }, |
michael@0 | 4428 | |
michael@0 | 4429 | handlers: function( event, handlers ) { |
michael@0 | 4430 | var i, matches, sel, handleObj, |
michael@0 | 4431 | handlerQueue = [], |
michael@0 | 4432 | delegateCount = handlers.delegateCount, |
michael@0 | 4433 | cur = event.target; |
michael@0 | 4434 | |
michael@0 | 4435 | // Find delegate handlers |
michael@0 | 4436 | // Black-hole SVG <use> instance trees (#13180) |
michael@0 | 4437 | // Avoid non-left-click bubbling in Firefox (#3861) |
michael@0 | 4438 | if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { |
michael@0 | 4439 | |
michael@0 | 4440 | for ( ; cur !== this; cur = cur.parentNode || this ) { |
michael@0 | 4441 | |
michael@0 | 4442 | // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) |
michael@0 | 4443 | if ( cur.disabled !== true || event.type !== "click" ) { |
michael@0 | 4444 | matches = []; |
michael@0 | 4445 | for ( i = 0; i < delegateCount; i++ ) { |
michael@0 | 4446 | handleObj = handlers[ i ]; |
michael@0 | 4447 | |
michael@0 | 4448 | // Don't conflict with Object.prototype properties (#13203) |
michael@0 | 4449 | sel = handleObj.selector + " "; |
michael@0 | 4450 | |
michael@0 | 4451 | if ( matches[ sel ] === undefined ) { |
michael@0 | 4452 | matches[ sel ] = handleObj.needsContext ? |
michael@0 | 4453 | jQuery( sel, this ).index( cur ) >= 0 : |
michael@0 | 4454 | jQuery.find( sel, this, null, [ cur ] ).length; |
michael@0 | 4455 | } |
michael@0 | 4456 | if ( matches[ sel ] ) { |
michael@0 | 4457 | matches.push( handleObj ); |
michael@0 | 4458 | } |
michael@0 | 4459 | } |
michael@0 | 4460 | if ( matches.length ) { |
michael@0 | 4461 | handlerQueue.push({ elem: cur, handlers: matches }); |
michael@0 | 4462 | } |
michael@0 | 4463 | } |
michael@0 | 4464 | } |
michael@0 | 4465 | } |
michael@0 | 4466 | |
michael@0 | 4467 | // Add the remaining (directly-bound) handlers |
michael@0 | 4468 | if ( delegateCount < handlers.length ) { |
michael@0 | 4469 | handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); |
michael@0 | 4470 | } |
michael@0 | 4471 | |
michael@0 | 4472 | return handlerQueue; |
michael@0 | 4473 | }, |
michael@0 | 4474 | |
michael@0 | 4475 | // Includes some event props shared by KeyEvent and MouseEvent |
michael@0 | 4476 | props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), |
michael@0 | 4477 | |
michael@0 | 4478 | fixHooks: {}, |
michael@0 | 4479 | |
michael@0 | 4480 | keyHooks: { |
michael@0 | 4481 | props: "char charCode key keyCode".split(" "), |
michael@0 | 4482 | filter: function( event, original ) { |
michael@0 | 4483 | |
michael@0 | 4484 | // Add which for key events |
michael@0 | 4485 | if ( event.which == null ) { |
michael@0 | 4486 | event.which = original.charCode != null ? original.charCode : original.keyCode; |
michael@0 | 4487 | } |
michael@0 | 4488 | |
michael@0 | 4489 | return event; |
michael@0 | 4490 | } |
michael@0 | 4491 | }, |
michael@0 | 4492 | |
michael@0 | 4493 | mouseHooks: { |
michael@0 | 4494 | props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), |
michael@0 | 4495 | filter: function( event, original ) { |
michael@0 | 4496 | var eventDoc, doc, body, |
michael@0 | 4497 | button = original.button; |
michael@0 | 4498 | |
michael@0 | 4499 | // Calculate pageX/Y if missing and clientX/Y available |
michael@0 | 4500 | if ( event.pageX == null && original.clientX != null ) { |
michael@0 | 4501 | eventDoc = event.target.ownerDocument || document; |
michael@0 | 4502 | doc = eventDoc.documentElement; |
michael@0 | 4503 | body = eventDoc.body; |
michael@0 | 4504 | |
michael@0 | 4505 | event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); |
michael@0 | 4506 | event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); |
michael@0 | 4507 | } |
michael@0 | 4508 | |
michael@0 | 4509 | // Add which for click: 1 === left; 2 === middle; 3 === right |
michael@0 | 4510 | // Note: button is not normalized, so don't use it |
michael@0 | 4511 | if ( !event.which && button !== undefined ) { |
michael@0 | 4512 | event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); |
michael@0 | 4513 | } |
michael@0 | 4514 | |
michael@0 | 4515 | return event; |
michael@0 | 4516 | } |
michael@0 | 4517 | }, |
michael@0 | 4518 | |
michael@0 | 4519 | fix: function( event ) { |
michael@0 | 4520 | if ( event[ jQuery.expando ] ) { |
michael@0 | 4521 | return event; |
michael@0 | 4522 | } |
michael@0 | 4523 | |
michael@0 | 4524 | // Create a writable copy of the event object and normalize some properties |
michael@0 | 4525 | var i, prop, copy, |
michael@0 | 4526 | type = event.type, |
michael@0 | 4527 | originalEvent = event, |
michael@0 | 4528 | fixHook = this.fixHooks[ type ]; |
michael@0 | 4529 | |
michael@0 | 4530 | if ( !fixHook ) { |
michael@0 | 4531 | this.fixHooks[ type ] = fixHook = |
michael@0 | 4532 | rmouseEvent.test( type ) ? this.mouseHooks : |
michael@0 | 4533 | rkeyEvent.test( type ) ? this.keyHooks : |
michael@0 | 4534 | {}; |
michael@0 | 4535 | } |
michael@0 | 4536 | copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; |
michael@0 | 4537 | |
michael@0 | 4538 | event = new jQuery.Event( originalEvent ); |
michael@0 | 4539 | |
michael@0 | 4540 | i = copy.length; |
michael@0 | 4541 | while ( i-- ) { |
michael@0 | 4542 | prop = copy[ i ]; |
michael@0 | 4543 | event[ prop ] = originalEvent[ prop ]; |
michael@0 | 4544 | } |
michael@0 | 4545 | |
michael@0 | 4546 | // Support: Cordova 2.5 (WebKit) (#13255) |
michael@0 | 4547 | // All events should have a target; Cordova deviceready doesn't |
michael@0 | 4548 | if ( !event.target ) { |
michael@0 | 4549 | event.target = document; |
michael@0 | 4550 | } |
michael@0 | 4551 | |
michael@0 | 4552 | // Support: Safari 6.0+, Chrome < 28 |
michael@0 | 4553 | // Target should not be a text node (#504, #13143) |
michael@0 | 4554 | if ( event.target.nodeType === 3 ) { |
michael@0 | 4555 | event.target = event.target.parentNode; |
michael@0 | 4556 | } |
michael@0 | 4557 | |
michael@0 | 4558 | return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; |
michael@0 | 4559 | }, |
michael@0 | 4560 | |
michael@0 | 4561 | special: { |
michael@0 | 4562 | load: { |
michael@0 | 4563 | // Prevent triggered image.load events from bubbling to window.load |
michael@0 | 4564 | noBubble: true |
michael@0 | 4565 | }, |
michael@0 | 4566 | focus: { |
michael@0 | 4567 | // Fire native event if possible so blur/focus sequence is correct |
michael@0 | 4568 | trigger: function() { |
michael@0 | 4569 | if ( this !== safeActiveElement() && this.focus ) { |
michael@0 | 4570 | this.focus(); |
michael@0 | 4571 | return false; |
michael@0 | 4572 | } |
michael@0 | 4573 | }, |
michael@0 | 4574 | delegateType: "focusin" |
michael@0 | 4575 | }, |
michael@0 | 4576 | blur: { |
michael@0 | 4577 | trigger: function() { |
michael@0 | 4578 | if ( this === safeActiveElement() && this.blur ) { |
michael@0 | 4579 | this.blur(); |
michael@0 | 4580 | return false; |
michael@0 | 4581 | } |
michael@0 | 4582 | }, |
michael@0 | 4583 | delegateType: "focusout" |
michael@0 | 4584 | }, |
michael@0 | 4585 | click: { |
michael@0 | 4586 | // For checkbox, fire native event so checked state will be right |
michael@0 | 4587 | trigger: function() { |
michael@0 | 4588 | if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { |
michael@0 | 4589 | this.click(); |
michael@0 | 4590 | return false; |
michael@0 | 4591 | } |
michael@0 | 4592 | }, |
michael@0 | 4593 | |
michael@0 | 4594 | // For cross-browser consistency, don't fire native .click() on links |
michael@0 | 4595 | _default: function( event ) { |
michael@0 | 4596 | return jQuery.nodeName( event.target, "a" ); |
michael@0 | 4597 | } |
michael@0 | 4598 | }, |
michael@0 | 4599 | |
michael@0 | 4600 | beforeunload: { |
michael@0 | 4601 | postDispatch: function( event ) { |
michael@0 | 4602 | |
michael@0 | 4603 | // Support: Firefox 20+ |
michael@0 | 4604 | // Firefox doesn't alert if the returnValue field is not set. |
michael@0 | 4605 | if ( event.result !== undefined && event.originalEvent ) { |
michael@0 | 4606 | event.originalEvent.returnValue = event.result; |
michael@0 | 4607 | } |
michael@0 | 4608 | } |
michael@0 | 4609 | } |
michael@0 | 4610 | }, |
michael@0 | 4611 | |
michael@0 | 4612 | simulate: function( type, elem, event, bubble ) { |
michael@0 | 4613 | // Piggyback on a donor event to simulate a different one. |
michael@0 | 4614 | // Fake originalEvent to avoid donor's stopPropagation, but if the |
michael@0 | 4615 | // simulated event prevents default then we do the same on the donor. |
michael@0 | 4616 | var e = jQuery.extend( |
michael@0 | 4617 | new jQuery.Event(), |
michael@0 | 4618 | event, |
michael@0 | 4619 | { |
michael@0 | 4620 | type: type, |
michael@0 | 4621 | isSimulated: true, |
michael@0 | 4622 | originalEvent: {} |
michael@0 | 4623 | } |
michael@0 | 4624 | ); |
michael@0 | 4625 | if ( bubble ) { |
michael@0 | 4626 | jQuery.event.trigger( e, null, elem ); |
michael@0 | 4627 | } else { |
michael@0 | 4628 | jQuery.event.dispatch.call( elem, e ); |
michael@0 | 4629 | } |
michael@0 | 4630 | if ( e.isDefaultPrevented() ) { |
michael@0 | 4631 | event.preventDefault(); |
michael@0 | 4632 | } |
michael@0 | 4633 | } |
michael@0 | 4634 | }; |
michael@0 | 4635 | |
michael@0 | 4636 | jQuery.removeEvent = function( elem, type, handle ) { |
michael@0 | 4637 | if ( elem.removeEventListener ) { |
michael@0 | 4638 | elem.removeEventListener( type, handle, false ); |
michael@0 | 4639 | } |
michael@0 | 4640 | }; |
michael@0 | 4641 | |
michael@0 | 4642 | jQuery.Event = function( src, props ) { |
michael@0 | 4643 | // Allow instantiation without the 'new' keyword |
michael@0 | 4644 | if ( !(this instanceof jQuery.Event) ) { |
michael@0 | 4645 | return new jQuery.Event( src, props ); |
michael@0 | 4646 | } |
michael@0 | 4647 | |
michael@0 | 4648 | // Event object |
michael@0 | 4649 | if ( src && src.type ) { |
michael@0 | 4650 | this.originalEvent = src; |
michael@0 | 4651 | this.type = src.type; |
michael@0 | 4652 | |
michael@0 | 4653 | // Events bubbling up the document may have been marked as prevented |
michael@0 | 4654 | // by a handler lower down the tree; reflect the correct value. |
michael@0 | 4655 | this.isDefaultPrevented = src.defaultPrevented || |
michael@0 | 4656 | src.defaultPrevented === undefined && |
michael@0 | 4657 | // Support: Android < 4.0 |
michael@0 | 4658 | src.returnValue === false ? |
michael@0 | 4659 | returnTrue : |
michael@0 | 4660 | returnFalse; |
michael@0 | 4661 | |
michael@0 | 4662 | // Event type |
michael@0 | 4663 | } else { |
michael@0 | 4664 | this.type = src; |
michael@0 | 4665 | } |
michael@0 | 4666 | |
michael@0 | 4667 | // Put explicitly provided properties onto the event object |
michael@0 | 4668 | if ( props ) { |
michael@0 | 4669 | jQuery.extend( this, props ); |
michael@0 | 4670 | } |
michael@0 | 4671 | |
michael@0 | 4672 | // Create a timestamp if incoming event doesn't have one |
michael@0 | 4673 | this.timeStamp = src && src.timeStamp || jQuery.now(); |
michael@0 | 4674 | |
michael@0 | 4675 | // Mark it as fixed |
michael@0 | 4676 | this[ jQuery.expando ] = true; |
michael@0 | 4677 | }; |
michael@0 | 4678 | |
michael@0 | 4679 | // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding |
michael@0 | 4680 | // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html |
michael@0 | 4681 | jQuery.Event.prototype = { |
michael@0 | 4682 | isDefaultPrevented: returnFalse, |
michael@0 | 4683 | isPropagationStopped: returnFalse, |
michael@0 | 4684 | isImmediatePropagationStopped: returnFalse, |
michael@0 | 4685 | |
michael@0 | 4686 | preventDefault: function() { |
michael@0 | 4687 | var e = this.originalEvent; |
michael@0 | 4688 | |
michael@0 | 4689 | this.isDefaultPrevented = returnTrue; |
michael@0 | 4690 | |
michael@0 | 4691 | if ( e && e.preventDefault ) { |
michael@0 | 4692 | e.preventDefault(); |
michael@0 | 4693 | } |
michael@0 | 4694 | }, |
michael@0 | 4695 | stopPropagation: function() { |
michael@0 | 4696 | var e = this.originalEvent; |
michael@0 | 4697 | |
michael@0 | 4698 | this.isPropagationStopped = returnTrue; |
michael@0 | 4699 | |
michael@0 | 4700 | if ( e && e.stopPropagation ) { |
michael@0 | 4701 | e.stopPropagation(); |
michael@0 | 4702 | } |
michael@0 | 4703 | }, |
michael@0 | 4704 | stopImmediatePropagation: function() { |
michael@0 | 4705 | var e = this.originalEvent; |
michael@0 | 4706 | |
michael@0 | 4707 | this.isImmediatePropagationStopped = returnTrue; |
michael@0 | 4708 | |
michael@0 | 4709 | if ( e && e.stopImmediatePropagation ) { |
michael@0 | 4710 | e.stopImmediatePropagation(); |
michael@0 | 4711 | } |
michael@0 | 4712 | |
michael@0 | 4713 | this.stopPropagation(); |
michael@0 | 4714 | } |
michael@0 | 4715 | }; |
michael@0 | 4716 | |
michael@0 | 4717 | // Create mouseenter/leave events using mouseover/out and event-time checks |
michael@0 | 4718 | // Support: Chrome 15+ |
michael@0 | 4719 | jQuery.each({ |
michael@0 | 4720 | mouseenter: "mouseover", |
michael@0 | 4721 | mouseleave: "mouseout", |
michael@0 | 4722 | pointerenter: "pointerover", |
michael@0 | 4723 | pointerleave: "pointerout" |
michael@0 | 4724 | }, function( orig, fix ) { |
michael@0 | 4725 | jQuery.event.special[ orig ] = { |
michael@0 | 4726 | delegateType: fix, |
michael@0 | 4727 | bindType: fix, |
michael@0 | 4728 | |
michael@0 | 4729 | handle: function( event ) { |
michael@0 | 4730 | var ret, |
michael@0 | 4731 | target = this, |
michael@0 | 4732 | related = event.relatedTarget, |
michael@0 | 4733 | handleObj = event.handleObj; |
michael@0 | 4734 | |
michael@0 | 4735 | // For mousenter/leave call the handler if related is outside the target. |
michael@0 | 4736 | // NB: No relatedTarget if the mouse left/entered the browser window |
michael@0 | 4737 | if ( !related || (related !== target && !jQuery.contains( target, related )) ) { |
michael@0 | 4738 | event.type = handleObj.origType; |
michael@0 | 4739 | ret = handleObj.handler.apply( this, arguments ); |
michael@0 | 4740 | event.type = fix; |
michael@0 | 4741 | } |
michael@0 | 4742 | return ret; |
michael@0 | 4743 | } |
michael@0 | 4744 | }; |
michael@0 | 4745 | }); |
michael@0 | 4746 | |
michael@0 | 4747 | // Create "bubbling" focus and blur events |
michael@0 | 4748 | // Support: Firefox, Chrome, Safari |
michael@0 | 4749 | if ( !support.focusinBubbles ) { |
michael@0 | 4750 | jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { |
michael@0 | 4751 | |
michael@0 | 4752 | // Attach a single capturing handler on the document while someone wants focusin/focusout |
michael@0 | 4753 | var handler = function( event ) { |
michael@0 | 4754 | jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); |
michael@0 | 4755 | }; |
michael@0 | 4756 | |
michael@0 | 4757 | jQuery.event.special[ fix ] = { |
michael@0 | 4758 | setup: function() { |
michael@0 | 4759 | var doc = this.ownerDocument || this, |
michael@0 | 4760 | attaches = data_priv.access( doc, fix ); |
michael@0 | 4761 | |
michael@0 | 4762 | if ( !attaches ) { |
michael@0 | 4763 | doc.addEventListener( orig, handler, true ); |
michael@0 | 4764 | } |
michael@0 | 4765 | data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); |
michael@0 | 4766 | }, |
michael@0 | 4767 | teardown: function() { |
michael@0 | 4768 | var doc = this.ownerDocument || this, |
michael@0 | 4769 | attaches = data_priv.access( doc, fix ) - 1; |
michael@0 | 4770 | |
michael@0 | 4771 | if ( !attaches ) { |
michael@0 | 4772 | doc.removeEventListener( orig, handler, true ); |
michael@0 | 4773 | data_priv.remove( doc, fix ); |
michael@0 | 4774 | |
michael@0 | 4775 | } else { |
michael@0 | 4776 | data_priv.access( doc, fix, attaches ); |
michael@0 | 4777 | } |
michael@0 | 4778 | } |
michael@0 | 4779 | }; |
michael@0 | 4780 | }); |
michael@0 | 4781 | } |
michael@0 | 4782 | |
michael@0 | 4783 | jQuery.fn.extend({ |
michael@0 | 4784 | |
michael@0 | 4785 | on: function( types, selector, data, fn, /*INTERNAL*/ one ) { |
michael@0 | 4786 | var origFn, type; |
michael@0 | 4787 | |
michael@0 | 4788 | // Types can be a map of types/handlers |
michael@0 | 4789 | if ( typeof types === "object" ) { |
michael@0 | 4790 | // ( types-Object, selector, data ) |
michael@0 | 4791 | if ( typeof selector !== "string" ) { |
michael@0 | 4792 | // ( types-Object, data ) |
michael@0 | 4793 | data = data || selector; |
michael@0 | 4794 | selector = undefined; |
michael@0 | 4795 | } |
michael@0 | 4796 | for ( type in types ) { |
michael@0 | 4797 | this.on( type, selector, data, types[ type ], one ); |
michael@0 | 4798 | } |
michael@0 | 4799 | return this; |
michael@0 | 4800 | } |
michael@0 | 4801 | |
michael@0 | 4802 | if ( data == null && fn == null ) { |
michael@0 | 4803 | // ( types, fn ) |
michael@0 | 4804 | fn = selector; |
michael@0 | 4805 | data = selector = undefined; |
michael@0 | 4806 | } else if ( fn == null ) { |
michael@0 | 4807 | if ( typeof selector === "string" ) { |
michael@0 | 4808 | // ( types, selector, fn ) |
michael@0 | 4809 | fn = data; |
michael@0 | 4810 | data = undefined; |
michael@0 | 4811 | } else { |
michael@0 | 4812 | // ( types, data, fn ) |
michael@0 | 4813 | fn = data; |
michael@0 | 4814 | data = selector; |
michael@0 | 4815 | selector = undefined; |
michael@0 | 4816 | } |
michael@0 | 4817 | } |
michael@0 | 4818 | if ( fn === false ) { |
michael@0 | 4819 | fn = returnFalse; |
michael@0 | 4820 | } else if ( !fn ) { |
michael@0 | 4821 | return this; |
michael@0 | 4822 | } |
michael@0 | 4823 | |
michael@0 | 4824 | if ( one === 1 ) { |
michael@0 | 4825 | origFn = fn; |
michael@0 | 4826 | fn = function( event ) { |
michael@0 | 4827 | // Can use an empty set, since event contains the info |
michael@0 | 4828 | jQuery().off( event ); |
michael@0 | 4829 | return origFn.apply( this, arguments ); |
michael@0 | 4830 | }; |
michael@0 | 4831 | // Use same guid so caller can remove using origFn |
michael@0 | 4832 | fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); |
michael@0 | 4833 | } |
michael@0 | 4834 | return this.each( function() { |
michael@0 | 4835 | jQuery.event.add( this, types, fn, data, selector ); |
michael@0 | 4836 | }); |
michael@0 | 4837 | }, |
michael@0 | 4838 | one: function( types, selector, data, fn ) { |
michael@0 | 4839 | return this.on( types, selector, data, fn, 1 ); |
michael@0 | 4840 | }, |
michael@0 | 4841 | off: function( types, selector, fn ) { |
michael@0 | 4842 | var handleObj, type; |
michael@0 | 4843 | if ( types && types.preventDefault && types.handleObj ) { |
michael@0 | 4844 | // ( event ) dispatched jQuery.Event |
michael@0 | 4845 | handleObj = types.handleObj; |
michael@0 | 4846 | jQuery( types.delegateTarget ).off( |
michael@0 | 4847 | handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, |
michael@0 | 4848 | handleObj.selector, |
michael@0 | 4849 | handleObj.handler |
michael@0 | 4850 | ); |
michael@0 | 4851 | return this; |
michael@0 | 4852 | } |
michael@0 | 4853 | if ( typeof types === "object" ) { |
michael@0 | 4854 | // ( types-object [, selector] ) |
michael@0 | 4855 | for ( type in types ) { |
michael@0 | 4856 | this.off( type, selector, types[ type ] ); |
michael@0 | 4857 | } |
michael@0 | 4858 | return this; |
michael@0 | 4859 | } |
michael@0 | 4860 | if ( selector === false || typeof selector === "function" ) { |
michael@0 | 4861 | // ( types [, fn] ) |
michael@0 | 4862 | fn = selector; |
michael@0 | 4863 | selector = undefined; |
michael@0 | 4864 | } |
michael@0 | 4865 | if ( fn === false ) { |
michael@0 | 4866 | fn = returnFalse; |
michael@0 | 4867 | } |
michael@0 | 4868 | return this.each(function() { |
michael@0 | 4869 | jQuery.event.remove( this, types, fn, selector ); |
michael@0 | 4870 | }); |
michael@0 | 4871 | }, |
michael@0 | 4872 | |
michael@0 | 4873 | trigger: function( type, data ) { |
michael@0 | 4874 | return this.each(function() { |
michael@0 | 4875 | jQuery.event.trigger( type, data, this ); |
michael@0 | 4876 | }); |
michael@0 | 4877 | }, |
michael@0 | 4878 | triggerHandler: function( type, data ) { |
michael@0 | 4879 | var elem = this[0]; |
michael@0 | 4880 | if ( elem ) { |
michael@0 | 4881 | return jQuery.event.trigger( type, data, elem, true ); |
michael@0 | 4882 | } |
michael@0 | 4883 | } |
michael@0 | 4884 | }); |
michael@0 | 4885 | |
michael@0 | 4886 | |
michael@0 | 4887 | var |
michael@0 | 4888 | rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, |
michael@0 | 4889 | rtagName = /<([\w:]+)/, |
michael@0 | 4890 | rhtml = /<|&#?\w+;/, |
michael@0 | 4891 | rnoInnerhtml = /<(?:script|style|link)/i, |
michael@0 | 4892 | // checked="checked" or checked |
michael@0 | 4893 | rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, |
michael@0 | 4894 | rscriptType = /^$|\/(?:java|ecma)script/i, |
michael@0 | 4895 | rscriptTypeMasked = /^true\/(.*)/, |
michael@0 | 4896 | rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, |
michael@0 | 4897 | |
michael@0 | 4898 | // We have to close these tags to support XHTML (#13200) |
michael@0 | 4899 | wrapMap = { |
michael@0 | 4900 | |
michael@0 | 4901 | // Support: IE 9 |
michael@0 | 4902 | option: [ 1, "<select multiple='multiple'>", "</select>" ], |
michael@0 | 4903 | |
michael@0 | 4904 | thead: [ 1, "<table>", "</table>" ], |
michael@0 | 4905 | col: [ 2, "<table><colgroup>", "</colgroup></table>" ], |
michael@0 | 4906 | tr: [ 2, "<table><tbody>", "</tbody></table>" ], |
michael@0 | 4907 | td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], |
michael@0 | 4908 | |
michael@0 | 4909 | _default: [ 0, "", "" ] |
michael@0 | 4910 | }; |
michael@0 | 4911 | |
michael@0 | 4912 | // Support: IE 9 |
michael@0 | 4913 | wrapMap.optgroup = wrapMap.option; |
michael@0 | 4914 | |
michael@0 | 4915 | wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; |
michael@0 | 4916 | wrapMap.th = wrapMap.td; |
michael@0 | 4917 | |
michael@0 | 4918 | // Support: 1.x compatibility |
michael@0 | 4919 | // Manipulating tables requires a tbody |
michael@0 | 4920 | function manipulationTarget( elem, content ) { |
michael@0 | 4921 | return jQuery.nodeName( elem, "table" ) && |
michael@0 | 4922 | jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? |
michael@0 | 4923 | |
michael@0 | 4924 | elem.getElementsByTagName("tbody")[0] || |
michael@0 | 4925 | elem.appendChild( elem.ownerDocument.createElement("tbody") ) : |
michael@0 | 4926 | elem; |
michael@0 | 4927 | } |
michael@0 | 4928 | |
michael@0 | 4929 | // Replace/restore the type attribute of script elements for safe DOM manipulation |
michael@0 | 4930 | function disableScript( elem ) { |
michael@0 | 4931 | elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; |
michael@0 | 4932 | return elem; |
michael@0 | 4933 | } |
michael@0 | 4934 | function restoreScript( elem ) { |
michael@0 | 4935 | var match = rscriptTypeMasked.exec( elem.type ); |
michael@0 | 4936 | |
michael@0 | 4937 | if ( match ) { |
michael@0 | 4938 | elem.type = match[ 1 ]; |
michael@0 | 4939 | } else { |
michael@0 | 4940 | elem.removeAttribute("type"); |
michael@0 | 4941 | } |
michael@0 | 4942 | |
michael@0 | 4943 | return elem; |
michael@0 | 4944 | } |
michael@0 | 4945 | |
michael@0 | 4946 | // Mark scripts as having already been evaluated |
michael@0 | 4947 | function setGlobalEval( elems, refElements ) { |
michael@0 | 4948 | var i = 0, |
michael@0 | 4949 | l = elems.length; |
michael@0 | 4950 | |
michael@0 | 4951 | for ( ; i < l; i++ ) { |
michael@0 | 4952 | data_priv.set( |
michael@0 | 4953 | elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) |
michael@0 | 4954 | ); |
michael@0 | 4955 | } |
michael@0 | 4956 | } |
michael@0 | 4957 | |
michael@0 | 4958 | function cloneCopyEvent( src, dest ) { |
michael@0 | 4959 | var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; |
michael@0 | 4960 | |
michael@0 | 4961 | if ( dest.nodeType !== 1 ) { |
michael@0 | 4962 | return; |
michael@0 | 4963 | } |
michael@0 | 4964 | |
michael@0 | 4965 | // 1. Copy private data: events, handlers, etc. |
michael@0 | 4966 | if ( data_priv.hasData( src ) ) { |
michael@0 | 4967 | pdataOld = data_priv.access( src ); |
michael@0 | 4968 | pdataCur = data_priv.set( dest, pdataOld ); |
michael@0 | 4969 | events = pdataOld.events; |
michael@0 | 4970 | |
michael@0 | 4971 | if ( events ) { |
michael@0 | 4972 | delete pdataCur.handle; |
michael@0 | 4973 | pdataCur.events = {}; |
michael@0 | 4974 | |
michael@0 | 4975 | for ( type in events ) { |
michael@0 | 4976 | for ( i = 0, l = events[ type ].length; i < l; i++ ) { |
michael@0 | 4977 | jQuery.event.add( dest, type, events[ type ][ i ] ); |
michael@0 | 4978 | } |
michael@0 | 4979 | } |
michael@0 | 4980 | } |
michael@0 | 4981 | } |
michael@0 | 4982 | |
michael@0 | 4983 | // 2. Copy user data |
michael@0 | 4984 | if ( data_user.hasData( src ) ) { |
michael@0 | 4985 | udataOld = data_user.access( src ); |
michael@0 | 4986 | udataCur = jQuery.extend( {}, udataOld ); |
michael@0 | 4987 | |
michael@0 | 4988 | data_user.set( dest, udataCur ); |
michael@0 | 4989 | } |
michael@0 | 4990 | } |
michael@0 | 4991 | |
michael@0 | 4992 | function getAll( context, tag ) { |
michael@0 | 4993 | var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : |
michael@0 | 4994 | context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : |
michael@0 | 4995 | []; |
michael@0 | 4996 | |
michael@0 | 4997 | return tag === undefined || tag && jQuery.nodeName( context, tag ) ? |
michael@0 | 4998 | jQuery.merge( [ context ], ret ) : |
michael@0 | 4999 | ret; |
michael@0 | 5000 | } |
michael@0 | 5001 | |
michael@0 | 5002 | // Support: IE >= 9 |
michael@0 | 5003 | function fixInput( src, dest ) { |
michael@0 | 5004 | var nodeName = dest.nodeName.toLowerCase(); |
michael@0 | 5005 | |
michael@0 | 5006 | // Fails to persist the checked state of a cloned checkbox or radio button. |
michael@0 | 5007 | if ( nodeName === "input" && rcheckableType.test( src.type ) ) { |
michael@0 | 5008 | dest.checked = src.checked; |
michael@0 | 5009 | |
michael@0 | 5010 | // Fails to return the selected option to the default selected state when cloning options |
michael@0 | 5011 | } else if ( nodeName === "input" || nodeName === "textarea" ) { |
michael@0 | 5012 | dest.defaultValue = src.defaultValue; |
michael@0 | 5013 | } |
michael@0 | 5014 | } |
michael@0 | 5015 | |
michael@0 | 5016 | jQuery.extend({ |
michael@0 | 5017 | clone: function( elem, dataAndEvents, deepDataAndEvents ) { |
michael@0 | 5018 | var i, l, srcElements, destElements, |
michael@0 | 5019 | clone = elem.cloneNode( true ), |
michael@0 | 5020 | inPage = jQuery.contains( elem.ownerDocument, elem ); |
michael@0 | 5021 | |
michael@0 | 5022 | // Support: IE >= 9 |
michael@0 | 5023 | // Fix Cloning issues |
michael@0 | 5024 | if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && |
michael@0 | 5025 | !jQuery.isXMLDoc( elem ) ) { |
michael@0 | 5026 | |
michael@0 | 5027 | // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 |
michael@0 | 5028 | destElements = getAll( clone ); |
michael@0 | 5029 | srcElements = getAll( elem ); |
michael@0 | 5030 | |
michael@0 | 5031 | for ( i = 0, l = srcElements.length; i < l; i++ ) { |
michael@0 | 5032 | fixInput( srcElements[ i ], destElements[ i ] ); |
michael@0 | 5033 | } |
michael@0 | 5034 | } |
michael@0 | 5035 | |
michael@0 | 5036 | // Copy the events from the original to the clone |
michael@0 | 5037 | if ( dataAndEvents ) { |
michael@0 | 5038 | if ( deepDataAndEvents ) { |
michael@0 | 5039 | srcElements = srcElements || getAll( elem ); |
michael@0 | 5040 | destElements = destElements || getAll( clone ); |
michael@0 | 5041 | |
michael@0 | 5042 | for ( i = 0, l = srcElements.length; i < l; i++ ) { |
michael@0 | 5043 | cloneCopyEvent( srcElements[ i ], destElements[ i ] ); |
michael@0 | 5044 | } |
michael@0 | 5045 | } else { |
michael@0 | 5046 | cloneCopyEvent( elem, clone ); |
michael@0 | 5047 | } |
michael@0 | 5048 | } |
michael@0 | 5049 | |
michael@0 | 5050 | // Preserve script evaluation history |
michael@0 | 5051 | destElements = getAll( clone, "script" ); |
michael@0 | 5052 | if ( destElements.length > 0 ) { |
michael@0 | 5053 | setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); |
michael@0 | 5054 | } |
michael@0 | 5055 | |
michael@0 | 5056 | // Return the cloned set |
michael@0 | 5057 | return clone; |
michael@0 | 5058 | }, |
michael@0 | 5059 | |
michael@0 | 5060 | buildFragment: function( elems, context, scripts, selection ) { |
michael@0 | 5061 | var elem, tmp, tag, wrap, contains, j, |
michael@0 | 5062 | fragment = context.createDocumentFragment(), |
michael@0 | 5063 | nodes = [], |
michael@0 | 5064 | i = 0, |
michael@0 | 5065 | l = elems.length; |
michael@0 | 5066 | |
michael@0 | 5067 | for ( ; i < l; i++ ) { |
michael@0 | 5068 | elem = elems[ i ]; |
michael@0 | 5069 | |
michael@0 | 5070 | if ( elem || elem === 0 ) { |
michael@0 | 5071 | |
michael@0 | 5072 | // Add nodes directly |
michael@0 | 5073 | if ( jQuery.type( elem ) === "object" ) { |
michael@0 | 5074 | // Support: QtWebKit |
michael@0 | 5075 | // jQuery.merge because push.apply(_, arraylike) throws |
michael@0 | 5076 | jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); |
michael@0 | 5077 | |
michael@0 | 5078 | // Convert non-html into a text node |
michael@0 | 5079 | } else if ( !rhtml.test( elem ) ) { |
michael@0 | 5080 | nodes.push( context.createTextNode( elem ) ); |
michael@0 | 5081 | |
michael@0 | 5082 | // Convert html into DOM nodes |
michael@0 | 5083 | } else { |
michael@0 | 5084 | tmp = tmp || fragment.appendChild( context.createElement("div") ); |
michael@0 | 5085 | |
michael@0 | 5086 | // Deserialize a standard representation |
michael@0 | 5087 | tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); |
michael@0 | 5088 | wrap = wrapMap[ tag ] || wrapMap._default; |
michael@0 | 5089 | tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ]; |
michael@0 | 5090 | |
michael@0 | 5091 | // Descend through wrappers to the right content |
michael@0 | 5092 | j = wrap[ 0 ]; |
michael@0 | 5093 | while ( j-- ) { |
michael@0 | 5094 | tmp = tmp.lastChild; |
michael@0 | 5095 | } |
michael@0 | 5096 | |
michael@0 | 5097 | // Support: QtWebKit |
michael@0 | 5098 | // jQuery.merge because push.apply(_, arraylike) throws |
michael@0 | 5099 | jQuery.merge( nodes, tmp.childNodes ); |
michael@0 | 5100 | |
michael@0 | 5101 | // Remember the top-level container |
michael@0 | 5102 | tmp = fragment.firstChild; |
michael@0 | 5103 | |
michael@0 | 5104 | // Fixes #12346 |
michael@0 | 5105 | // Support: Webkit, IE |
michael@0 | 5106 | tmp.textContent = ""; |
michael@0 | 5107 | } |
michael@0 | 5108 | } |
michael@0 | 5109 | } |
michael@0 | 5110 | |
michael@0 | 5111 | // Remove wrapper from fragment |
michael@0 | 5112 | fragment.textContent = ""; |
michael@0 | 5113 | |
michael@0 | 5114 | i = 0; |
michael@0 | 5115 | while ( (elem = nodes[ i++ ]) ) { |
michael@0 | 5116 | |
michael@0 | 5117 | // #4087 - If origin and destination elements are the same, and this is |
michael@0 | 5118 | // that element, do not do anything |
michael@0 | 5119 | if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { |
michael@0 | 5120 | continue; |
michael@0 | 5121 | } |
michael@0 | 5122 | |
michael@0 | 5123 | contains = jQuery.contains( elem.ownerDocument, elem ); |
michael@0 | 5124 | |
michael@0 | 5125 | // Append to fragment |
michael@0 | 5126 | tmp = getAll( fragment.appendChild( elem ), "script" ); |
michael@0 | 5127 | |
michael@0 | 5128 | // Preserve script evaluation history |
michael@0 | 5129 | if ( contains ) { |
michael@0 | 5130 | setGlobalEval( tmp ); |
michael@0 | 5131 | } |
michael@0 | 5132 | |
michael@0 | 5133 | // Capture executables |
michael@0 | 5134 | if ( scripts ) { |
michael@0 | 5135 | j = 0; |
michael@0 | 5136 | while ( (elem = tmp[ j++ ]) ) { |
michael@0 | 5137 | if ( rscriptType.test( elem.type || "" ) ) { |
michael@0 | 5138 | scripts.push( elem ); |
michael@0 | 5139 | } |
michael@0 | 5140 | } |
michael@0 | 5141 | } |
michael@0 | 5142 | } |
michael@0 | 5143 | |
michael@0 | 5144 | return fragment; |
michael@0 | 5145 | }, |
michael@0 | 5146 | |
michael@0 | 5147 | cleanData: function( elems ) { |
michael@0 | 5148 | var data, elem, type, key, |
michael@0 | 5149 | special = jQuery.event.special, |
michael@0 | 5150 | i = 0; |
michael@0 | 5151 | |
michael@0 | 5152 | for ( ; (elem = elems[ i ]) !== undefined; i++ ) { |
michael@0 | 5153 | if ( jQuery.acceptData( elem ) ) { |
michael@0 | 5154 | key = elem[ data_priv.expando ]; |
michael@0 | 5155 | |
michael@0 | 5156 | if ( key && (data = data_priv.cache[ key ]) ) { |
michael@0 | 5157 | if ( data.events ) { |
michael@0 | 5158 | for ( type in data.events ) { |
michael@0 | 5159 | if ( special[ type ] ) { |
michael@0 | 5160 | jQuery.event.remove( elem, type ); |
michael@0 | 5161 | |
michael@0 | 5162 | // This is a shortcut to avoid jQuery.event.remove's overhead |
michael@0 | 5163 | } else { |
michael@0 | 5164 | jQuery.removeEvent( elem, type, data.handle ); |
michael@0 | 5165 | } |
michael@0 | 5166 | } |
michael@0 | 5167 | } |
michael@0 | 5168 | if ( data_priv.cache[ key ] ) { |
michael@0 | 5169 | // Discard any remaining `private` data |
michael@0 | 5170 | delete data_priv.cache[ key ]; |
michael@0 | 5171 | } |
michael@0 | 5172 | } |
michael@0 | 5173 | } |
michael@0 | 5174 | // Discard any remaining `user` data |
michael@0 | 5175 | delete data_user.cache[ elem[ data_user.expando ] ]; |
michael@0 | 5176 | } |
michael@0 | 5177 | } |
michael@0 | 5178 | }); |
michael@0 | 5179 | |
michael@0 | 5180 | jQuery.fn.extend({ |
michael@0 | 5181 | text: function( value ) { |
michael@0 | 5182 | return access( this, function( value ) { |
michael@0 | 5183 | return value === undefined ? |
michael@0 | 5184 | jQuery.text( this ) : |
michael@0 | 5185 | this.empty().each(function() { |
michael@0 | 5186 | if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
michael@0 | 5187 | this.textContent = value; |
michael@0 | 5188 | } |
michael@0 | 5189 | }); |
michael@0 | 5190 | }, null, value, arguments.length ); |
michael@0 | 5191 | }, |
michael@0 | 5192 | |
michael@0 | 5193 | append: function() { |
michael@0 | 5194 | return this.domManip( arguments, function( elem ) { |
michael@0 | 5195 | if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
michael@0 | 5196 | var target = manipulationTarget( this, elem ); |
michael@0 | 5197 | target.appendChild( elem ); |
michael@0 | 5198 | } |
michael@0 | 5199 | }); |
michael@0 | 5200 | }, |
michael@0 | 5201 | |
michael@0 | 5202 | prepend: function() { |
michael@0 | 5203 | return this.domManip( arguments, function( elem ) { |
michael@0 | 5204 | if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
michael@0 | 5205 | var target = manipulationTarget( this, elem ); |
michael@0 | 5206 | target.insertBefore( elem, target.firstChild ); |
michael@0 | 5207 | } |
michael@0 | 5208 | }); |
michael@0 | 5209 | }, |
michael@0 | 5210 | |
michael@0 | 5211 | before: function() { |
michael@0 | 5212 | return this.domManip( arguments, function( elem ) { |
michael@0 | 5213 | if ( this.parentNode ) { |
michael@0 | 5214 | this.parentNode.insertBefore( elem, this ); |
michael@0 | 5215 | } |
michael@0 | 5216 | }); |
michael@0 | 5217 | }, |
michael@0 | 5218 | |
michael@0 | 5219 | after: function() { |
michael@0 | 5220 | return this.domManip( arguments, function( elem ) { |
michael@0 | 5221 | if ( this.parentNode ) { |
michael@0 | 5222 | this.parentNode.insertBefore( elem, this.nextSibling ); |
michael@0 | 5223 | } |
michael@0 | 5224 | }); |
michael@0 | 5225 | }, |
michael@0 | 5226 | |
michael@0 | 5227 | remove: function( selector, keepData /* Internal Use Only */ ) { |
michael@0 | 5228 | var elem, |
michael@0 | 5229 | elems = selector ? jQuery.filter( selector, this ) : this, |
michael@0 | 5230 | i = 0; |
michael@0 | 5231 | |
michael@0 | 5232 | for ( ; (elem = elems[i]) != null; i++ ) { |
michael@0 | 5233 | if ( !keepData && elem.nodeType === 1 ) { |
michael@0 | 5234 | jQuery.cleanData( getAll( elem ) ); |
michael@0 | 5235 | } |
michael@0 | 5236 | |
michael@0 | 5237 | if ( elem.parentNode ) { |
michael@0 | 5238 | if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { |
michael@0 | 5239 | setGlobalEval( getAll( elem, "script" ) ); |
michael@0 | 5240 | } |
michael@0 | 5241 | elem.parentNode.removeChild( elem ); |
michael@0 | 5242 | } |
michael@0 | 5243 | } |
michael@0 | 5244 | |
michael@0 | 5245 | return this; |
michael@0 | 5246 | }, |
michael@0 | 5247 | |
michael@0 | 5248 | empty: function() { |
michael@0 | 5249 | var elem, |
michael@0 | 5250 | i = 0; |
michael@0 | 5251 | |
michael@0 | 5252 | for ( ; (elem = this[i]) != null; i++ ) { |
michael@0 | 5253 | if ( elem.nodeType === 1 ) { |
michael@0 | 5254 | |
michael@0 | 5255 | // Prevent memory leaks |
michael@0 | 5256 | jQuery.cleanData( getAll( elem, false ) ); |
michael@0 | 5257 | |
michael@0 | 5258 | // Remove any remaining nodes |
michael@0 | 5259 | elem.textContent = ""; |
michael@0 | 5260 | } |
michael@0 | 5261 | } |
michael@0 | 5262 | |
michael@0 | 5263 | return this; |
michael@0 | 5264 | }, |
michael@0 | 5265 | |
michael@0 | 5266 | clone: function( dataAndEvents, deepDataAndEvents ) { |
michael@0 | 5267 | dataAndEvents = dataAndEvents == null ? false : dataAndEvents; |
michael@0 | 5268 | deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; |
michael@0 | 5269 | |
michael@0 | 5270 | return this.map(function() { |
michael@0 | 5271 | return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); |
michael@0 | 5272 | }); |
michael@0 | 5273 | }, |
michael@0 | 5274 | |
michael@0 | 5275 | html: function( value ) { |
michael@0 | 5276 | return access( this, function( value ) { |
michael@0 | 5277 | var elem = this[ 0 ] || {}, |
michael@0 | 5278 | i = 0, |
michael@0 | 5279 | l = this.length; |
michael@0 | 5280 | |
michael@0 | 5281 | if ( value === undefined && elem.nodeType === 1 ) { |
michael@0 | 5282 | return elem.innerHTML; |
michael@0 | 5283 | } |
michael@0 | 5284 | |
michael@0 | 5285 | // See if we can take a shortcut and just use innerHTML |
michael@0 | 5286 | if ( typeof value === "string" && !rnoInnerhtml.test( value ) && |
michael@0 | 5287 | !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { |
michael@0 | 5288 | |
michael@0 | 5289 | value = value.replace( rxhtmlTag, "<$1></$2>" ); |
michael@0 | 5290 | |
michael@0 | 5291 | try { |
michael@0 | 5292 | for ( ; i < l; i++ ) { |
michael@0 | 5293 | elem = this[ i ] || {}; |
michael@0 | 5294 | |
michael@0 | 5295 | // Remove element nodes and prevent memory leaks |
michael@0 | 5296 | if ( elem.nodeType === 1 ) { |
michael@0 | 5297 | jQuery.cleanData( getAll( elem, false ) ); |
michael@0 | 5298 | elem.innerHTML = value; |
michael@0 | 5299 | } |
michael@0 | 5300 | } |
michael@0 | 5301 | |
michael@0 | 5302 | elem = 0; |
michael@0 | 5303 | |
michael@0 | 5304 | // If using innerHTML throws an exception, use the fallback method |
michael@0 | 5305 | } catch( e ) {} |
michael@0 | 5306 | } |
michael@0 | 5307 | |
michael@0 | 5308 | if ( elem ) { |
michael@0 | 5309 | this.empty().append( value ); |
michael@0 | 5310 | } |
michael@0 | 5311 | }, null, value, arguments.length ); |
michael@0 | 5312 | }, |
michael@0 | 5313 | |
michael@0 | 5314 | replaceWith: function() { |
michael@0 | 5315 | var arg = arguments[ 0 ]; |
michael@0 | 5316 | |
michael@0 | 5317 | // Make the changes, replacing each context element with the new content |
michael@0 | 5318 | this.domManip( arguments, function( elem ) { |
michael@0 | 5319 | arg = this.parentNode; |
michael@0 | 5320 | |
michael@0 | 5321 | jQuery.cleanData( getAll( this ) ); |
michael@0 | 5322 | |
michael@0 | 5323 | if ( arg ) { |
michael@0 | 5324 | arg.replaceChild( elem, this ); |
michael@0 | 5325 | } |
michael@0 | 5326 | }); |
michael@0 | 5327 | |
michael@0 | 5328 | // Force removal if there was no new content (e.g., from empty arguments) |
michael@0 | 5329 | return arg && (arg.length || arg.nodeType) ? this : this.remove(); |
michael@0 | 5330 | }, |
michael@0 | 5331 | |
michael@0 | 5332 | detach: function( selector ) { |
michael@0 | 5333 | return this.remove( selector, true ); |
michael@0 | 5334 | }, |
michael@0 | 5335 | |
michael@0 | 5336 | domManip: function( args, callback ) { |
michael@0 | 5337 | |
michael@0 | 5338 | // Flatten any nested arrays |
michael@0 | 5339 | args = concat.apply( [], args ); |
michael@0 | 5340 | |
michael@0 | 5341 | var fragment, first, scripts, hasScripts, node, doc, |
michael@0 | 5342 | i = 0, |
michael@0 | 5343 | l = this.length, |
michael@0 | 5344 | set = this, |
michael@0 | 5345 | iNoClone = l - 1, |
michael@0 | 5346 | value = args[ 0 ], |
michael@0 | 5347 | isFunction = jQuery.isFunction( value ); |
michael@0 | 5348 | |
michael@0 | 5349 | // We can't cloneNode fragments that contain checked, in WebKit |
michael@0 | 5350 | if ( isFunction || |
michael@0 | 5351 | ( l > 1 && typeof value === "string" && |
michael@0 | 5352 | !support.checkClone && rchecked.test( value ) ) ) { |
michael@0 | 5353 | return this.each(function( index ) { |
michael@0 | 5354 | var self = set.eq( index ); |
michael@0 | 5355 | if ( isFunction ) { |
michael@0 | 5356 | args[ 0 ] = value.call( this, index, self.html() ); |
michael@0 | 5357 | } |
michael@0 | 5358 | self.domManip( args, callback ); |
michael@0 | 5359 | }); |
michael@0 | 5360 | } |
michael@0 | 5361 | |
michael@0 | 5362 | if ( l ) { |
michael@0 | 5363 | fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); |
michael@0 | 5364 | first = fragment.firstChild; |
michael@0 | 5365 | |
michael@0 | 5366 | if ( fragment.childNodes.length === 1 ) { |
michael@0 | 5367 | fragment = first; |
michael@0 | 5368 | } |
michael@0 | 5369 | |
michael@0 | 5370 | if ( first ) { |
michael@0 | 5371 | scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); |
michael@0 | 5372 | hasScripts = scripts.length; |
michael@0 | 5373 | |
michael@0 | 5374 | // Use the original fragment for the last item instead of the first because it can end up |
michael@0 | 5375 | // being emptied incorrectly in certain situations (#8070). |
michael@0 | 5376 | for ( ; i < l; i++ ) { |
michael@0 | 5377 | node = fragment; |
michael@0 | 5378 | |
michael@0 | 5379 | if ( i !== iNoClone ) { |
michael@0 | 5380 | node = jQuery.clone( node, true, true ); |
michael@0 | 5381 | |
michael@0 | 5382 | // Keep references to cloned scripts for later restoration |
michael@0 | 5383 | if ( hasScripts ) { |
michael@0 | 5384 | // Support: QtWebKit |
michael@0 | 5385 | // jQuery.merge because push.apply(_, arraylike) throws |
michael@0 | 5386 | jQuery.merge( scripts, getAll( node, "script" ) ); |
michael@0 | 5387 | } |
michael@0 | 5388 | } |
michael@0 | 5389 | |
michael@0 | 5390 | callback.call( this[ i ], node, i ); |
michael@0 | 5391 | } |
michael@0 | 5392 | |
michael@0 | 5393 | if ( hasScripts ) { |
michael@0 | 5394 | doc = scripts[ scripts.length - 1 ].ownerDocument; |
michael@0 | 5395 | |
michael@0 | 5396 | // Reenable scripts |
michael@0 | 5397 | jQuery.map( scripts, restoreScript ); |
michael@0 | 5398 | |
michael@0 | 5399 | // Evaluate executable scripts on first document insertion |
michael@0 | 5400 | for ( i = 0; i < hasScripts; i++ ) { |
michael@0 | 5401 | node = scripts[ i ]; |
michael@0 | 5402 | if ( rscriptType.test( node.type || "" ) && |
michael@0 | 5403 | !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { |
michael@0 | 5404 | |
michael@0 | 5405 | if ( node.src ) { |
michael@0 | 5406 | // Optional AJAX dependency, but won't run scripts if not present |
michael@0 | 5407 | if ( jQuery._evalUrl ) { |
michael@0 | 5408 | jQuery._evalUrl( node.src ); |
michael@0 | 5409 | } |
michael@0 | 5410 | } else { |
michael@0 | 5411 | jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); |
michael@0 | 5412 | } |
michael@0 | 5413 | } |
michael@0 | 5414 | } |
michael@0 | 5415 | } |
michael@0 | 5416 | } |
michael@0 | 5417 | } |
michael@0 | 5418 | |
michael@0 | 5419 | return this; |
michael@0 | 5420 | } |
michael@0 | 5421 | }); |
michael@0 | 5422 | |
michael@0 | 5423 | jQuery.each({ |
michael@0 | 5424 | appendTo: "append", |
michael@0 | 5425 | prependTo: "prepend", |
michael@0 | 5426 | insertBefore: "before", |
michael@0 | 5427 | insertAfter: "after", |
michael@0 | 5428 | replaceAll: "replaceWith" |
michael@0 | 5429 | }, function( name, original ) { |
michael@0 | 5430 | jQuery.fn[ name ] = function( selector ) { |
michael@0 | 5431 | var elems, |
michael@0 | 5432 | ret = [], |
michael@0 | 5433 | insert = jQuery( selector ), |
michael@0 | 5434 | last = insert.length - 1, |
michael@0 | 5435 | i = 0; |
michael@0 | 5436 | |
michael@0 | 5437 | for ( ; i <= last; i++ ) { |
michael@0 | 5438 | elems = i === last ? this : this.clone( true ); |
michael@0 | 5439 | jQuery( insert[ i ] )[ original ]( elems ); |
michael@0 | 5440 | |
michael@0 | 5441 | // Support: QtWebKit |
michael@0 | 5442 | // .get() because push.apply(_, arraylike) throws |
michael@0 | 5443 | push.apply( ret, elems.get() ); |
michael@0 | 5444 | } |
michael@0 | 5445 | |
michael@0 | 5446 | return this.pushStack( ret ); |
michael@0 | 5447 | }; |
michael@0 | 5448 | }); |
michael@0 | 5449 | |
michael@0 | 5450 | |
michael@0 | 5451 | var iframe, |
michael@0 | 5452 | elemdisplay = {}; |
michael@0 | 5453 | |
michael@0 | 5454 | /** |
michael@0 | 5455 | * Retrieve the actual display of a element |
michael@0 | 5456 | * @param {String} name nodeName of the element |
michael@0 | 5457 | * @param {Object} doc Document object |
michael@0 | 5458 | */ |
michael@0 | 5459 | // Called only from within defaultDisplay |
michael@0 | 5460 | function actualDisplay( name, doc ) { |
michael@0 | 5461 | var style, |
michael@0 | 5462 | elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), |
michael@0 | 5463 | |
michael@0 | 5464 | // getDefaultComputedStyle might be reliably used only on attached element |
michael@0 | 5465 | display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? |
michael@0 | 5466 | |
michael@0 | 5467 | // Use of this method is a temporary fix (more like optmization) until something better comes along, |
michael@0 | 5468 | // since it was removed from specification and supported only in FF |
michael@0 | 5469 | style.display : jQuery.css( elem[ 0 ], "display" ); |
michael@0 | 5470 | |
michael@0 | 5471 | // We don't have any data stored on the element, |
michael@0 | 5472 | // so use "detach" method as fast way to get rid of the element |
michael@0 | 5473 | elem.detach(); |
michael@0 | 5474 | |
michael@0 | 5475 | return display; |
michael@0 | 5476 | } |
michael@0 | 5477 | |
michael@0 | 5478 | /** |
michael@0 | 5479 | * Try to determine the default display value of an element |
michael@0 | 5480 | * @param {String} nodeName |
michael@0 | 5481 | */ |
michael@0 | 5482 | function defaultDisplay( nodeName ) { |
michael@0 | 5483 | var doc = document, |
michael@0 | 5484 | display = elemdisplay[ nodeName ]; |
michael@0 | 5485 | |
michael@0 | 5486 | if ( !display ) { |
michael@0 | 5487 | display = actualDisplay( nodeName, doc ); |
michael@0 | 5488 | |
michael@0 | 5489 | // If the simple way fails, read from inside an iframe |
michael@0 | 5490 | if ( display === "none" || !display ) { |
michael@0 | 5491 | |
michael@0 | 5492 | // Use the already-created iframe if possible |
michael@0 | 5493 | iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); |
michael@0 | 5494 | |
michael@0 | 5495 | // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse |
michael@0 | 5496 | doc = iframe[ 0 ].contentDocument; |
michael@0 | 5497 | |
michael@0 | 5498 | // Support: IE |
michael@0 | 5499 | doc.write(); |
michael@0 | 5500 | doc.close(); |
michael@0 | 5501 | |
michael@0 | 5502 | display = actualDisplay( nodeName, doc ); |
michael@0 | 5503 | iframe.detach(); |
michael@0 | 5504 | } |
michael@0 | 5505 | |
michael@0 | 5506 | // Store the correct default display |
michael@0 | 5507 | elemdisplay[ nodeName ] = display; |
michael@0 | 5508 | } |
michael@0 | 5509 | |
michael@0 | 5510 | return display; |
michael@0 | 5511 | } |
michael@0 | 5512 | var rmargin = (/^margin/); |
michael@0 | 5513 | |
michael@0 | 5514 | var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); |
michael@0 | 5515 | |
michael@0 | 5516 | var getStyles = function( elem ) { |
michael@0 | 5517 | return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); |
michael@0 | 5518 | }; |
michael@0 | 5519 | |
michael@0 | 5520 | |
michael@0 | 5521 | |
michael@0 | 5522 | function curCSS( elem, name, computed ) { |
michael@0 | 5523 | var width, minWidth, maxWidth, ret, |
michael@0 | 5524 | style = elem.style; |
michael@0 | 5525 | |
michael@0 | 5526 | computed = computed || getStyles( elem ); |
michael@0 | 5527 | |
michael@0 | 5528 | // Support: IE9 |
michael@0 | 5529 | // getPropertyValue is only needed for .css('filter') in IE9, see #12537 |
michael@0 | 5530 | if ( computed ) { |
michael@0 | 5531 | ret = computed.getPropertyValue( name ) || computed[ name ]; |
michael@0 | 5532 | } |
michael@0 | 5533 | |
michael@0 | 5534 | if ( computed ) { |
michael@0 | 5535 | |
michael@0 | 5536 | if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { |
michael@0 | 5537 | ret = jQuery.style( elem, name ); |
michael@0 | 5538 | } |
michael@0 | 5539 | |
michael@0 | 5540 | // Support: iOS < 6 |
michael@0 | 5541 | // A tribute to the "awesome hack by Dean Edwards" |
michael@0 | 5542 | // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels |
michael@0 | 5543 | // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values |
michael@0 | 5544 | if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { |
michael@0 | 5545 | |
michael@0 | 5546 | // Remember the original values |
michael@0 | 5547 | width = style.width; |
michael@0 | 5548 | minWidth = style.minWidth; |
michael@0 | 5549 | maxWidth = style.maxWidth; |
michael@0 | 5550 | |
michael@0 | 5551 | // Put in the new values to get a computed value out |
michael@0 | 5552 | style.minWidth = style.maxWidth = style.width = ret; |
michael@0 | 5553 | ret = computed.width; |
michael@0 | 5554 | |
michael@0 | 5555 | // Revert the changed values |
michael@0 | 5556 | style.width = width; |
michael@0 | 5557 | style.minWidth = minWidth; |
michael@0 | 5558 | style.maxWidth = maxWidth; |
michael@0 | 5559 | } |
michael@0 | 5560 | } |
michael@0 | 5561 | |
michael@0 | 5562 | return ret !== undefined ? |
michael@0 | 5563 | // Support: IE |
michael@0 | 5564 | // IE returns zIndex value as an integer. |
michael@0 | 5565 | ret + "" : |
michael@0 | 5566 | ret; |
michael@0 | 5567 | } |
michael@0 | 5568 | |
michael@0 | 5569 | |
michael@0 | 5570 | function addGetHookIf( conditionFn, hookFn ) { |
michael@0 | 5571 | // Define the hook, we'll check on the first run if it's really needed. |
michael@0 | 5572 | return { |
michael@0 | 5573 | get: function() { |
michael@0 | 5574 | if ( conditionFn() ) { |
michael@0 | 5575 | // Hook not needed (or it's not possible to use it due to missing dependency), |
michael@0 | 5576 | // remove it. |
michael@0 | 5577 | // Since there are no other hooks for marginRight, remove the whole object. |
michael@0 | 5578 | delete this.get; |
michael@0 | 5579 | return; |
michael@0 | 5580 | } |
michael@0 | 5581 | |
michael@0 | 5582 | // Hook needed; redefine it so that the support test is not executed again. |
michael@0 | 5583 | |
michael@0 | 5584 | return (this.get = hookFn).apply( this, arguments ); |
michael@0 | 5585 | } |
michael@0 | 5586 | }; |
michael@0 | 5587 | } |
michael@0 | 5588 | |
michael@0 | 5589 | |
michael@0 | 5590 | (function() { |
michael@0 | 5591 | var pixelPositionVal, boxSizingReliableVal, |
michael@0 | 5592 | docElem = document.documentElement, |
michael@0 | 5593 | container = document.createElement( "div" ), |
michael@0 | 5594 | div = document.createElement( "div" ); |
michael@0 | 5595 | |
michael@0 | 5596 | if ( !div.style ) { |
michael@0 | 5597 | return; |
michael@0 | 5598 | } |
michael@0 | 5599 | |
michael@0 | 5600 | div.style.backgroundClip = "content-box"; |
michael@0 | 5601 | div.cloneNode( true ).style.backgroundClip = ""; |
michael@0 | 5602 | support.clearCloneStyle = div.style.backgroundClip === "content-box"; |
michael@0 | 5603 | |
michael@0 | 5604 | container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" + |
michael@0 | 5605 | "position:absolute"; |
michael@0 | 5606 | container.appendChild( div ); |
michael@0 | 5607 | |
michael@0 | 5608 | // Executing both pixelPosition & boxSizingReliable tests require only one layout |
michael@0 | 5609 | // so they're executed at the same time to save the second computation. |
michael@0 | 5610 | function computePixelPositionAndBoxSizingReliable() { |
michael@0 | 5611 | div.style.cssText = |
michael@0 | 5612 | // Support: Firefox<29, Android 2.3 |
michael@0 | 5613 | // Vendor-prefix box-sizing |
michael@0 | 5614 | "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + |
michael@0 | 5615 | "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + |
michael@0 | 5616 | "border:1px;padding:1px;width:4px;position:absolute"; |
michael@0 | 5617 | div.innerHTML = ""; |
michael@0 | 5618 | docElem.appendChild( container ); |
michael@0 | 5619 | |
michael@0 | 5620 | var divStyle = window.getComputedStyle( div, null ); |
michael@0 | 5621 | pixelPositionVal = divStyle.top !== "1%"; |
michael@0 | 5622 | boxSizingReliableVal = divStyle.width === "4px"; |
michael@0 | 5623 | |
michael@0 | 5624 | docElem.removeChild( container ); |
michael@0 | 5625 | } |
michael@0 | 5626 | |
michael@0 | 5627 | // Support: node.js jsdom |
michael@0 | 5628 | // Don't assume that getComputedStyle is a property of the global object |
michael@0 | 5629 | if ( window.getComputedStyle ) { |
michael@0 | 5630 | jQuery.extend( support, { |
michael@0 | 5631 | pixelPosition: function() { |
michael@0 | 5632 | // This test is executed only once but we still do memoizing |
michael@0 | 5633 | // since we can use the boxSizingReliable pre-computing. |
michael@0 | 5634 | // No need to check if the test was already performed, though. |
michael@0 | 5635 | computePixelPositionAndBoxSizingReliable(); |
michael@0 | 5636 | return pixelPositionVal; |
michael@0 | 5637 | }, |
michael@0 | 5638 | boxSizingReliable: function() { |
michael@0 | 5639 | if ( boxSizingReliableVal == null ) { |
michael@0 | 5640 | computePixelPositionAndBoxSizingReliable(); |
michael@0 | 5641 | } |
michael@0 | 5642 | return boxSizingReliableVal; |
michael@0 | 5643 | }, |
michael@0 | 5644 | reliableMarginRight: function() { |
michael@0 | 5645 | // Support: Android 2.3 |
michael@0 | 5646 | // Check if div with explicit width and no margin-right incorrectly |
michael@0 | 5647 | // gets computed margin-right based on width of container. (#3333) |
michael@0 | 5648 | // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right |
michael@0 | 5649 | // This support function is only executed once so no memoizing is needed. |
michael@0 | 5650 | var ret, |
michael@0 | 5651 | marginDiv = div.appendChild( document.createElement( "div" ) ); |
michael@0 | 5652 | |
michael@0 | 5653 | // Reset CSS: box-sizing; display; margin; border; padding |
michael@0 | 5654 | marginDiv.style.cssText = div.style.cssText = |
michael@0 | 5655 | // Support: Firefox<29, Android 2.3 |
michael@0 | 5656 | // Vendor-prefix box-sizing |
michael@0 | 5657 | "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + |
michael@0 | 5658 | "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; |
michael@0 | 5659 | marginDiv.style.marginRight = marginDiv.style.width = "0"; |
michael@0 | 5660 | div.style.width = "1px"; |
michael@0 | 5661 | docElem.appendChild( container ); |
michael@0 | 5662 | |
michael@0 | 5663 | ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight ); |
michael@0 | 5664 | |
michael@0 | 5665 | docElem.removeChild( container ); |
michael@0 | 5666 | |
michael@0 | 5667 | return ret; |
michael@0 | 5668 | } |
michael@0 | 5669 | }); |
michael@0 | 5670 | } |
michael@0 | 5671 | })(); |
michael@0 | 5672 | |
michael@0 | 5673 | |
michael@0 | 5674 | // A method for quickly swapping in/out CSS properties to get correct calculations. |
michael@0 | 5675 | jQuery.swap = function( elem, options, callback, args ) { |
michael@0 | 5676 | var ret, name, |
michael@0 | 5677 | old = {}; |
michael@0 | 5678 | |
michael@0 | 5679 | // Remember the old values, and insert the new ones |
michael@0 | 5680 | for ( name in options ) { |
michael@0 | 5681 | old[ name ] = elem.style[ name ]; |
michael@0 | 5682 | elem.style[ name ] = options[ name ]; |
michael@0 | 5683 | } |
michael@0 | 5684 | |
michael@0 | 5685 | ret = callback.apply( elem, args || [] ); |
michael@0 | 5686 | |
michael@0 | 5687 | // Revert the old values |
michael@0 | 5688 | for ( name in options ) { |
michael@0 | 5689 | elem.style[ name ] = old[ name ]; |
michael@0 | 5690 | } |
michael@0 | 5691 | |
michael@0 | 5692 | return ret; |
michael@0 | 5693 | }; |
michael@0 | 5694 | |
michael@0 | 5695 | |
michael@0 | 5696 | var |
michael@0 | 5697 | // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" |
michael@0 | 5698 | // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display |
michael@0 | 5699 | rdisplayswap = /^(none|table(?!-c[ea]).+)/, |
michael@0 | 5700 | rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), |
michael@0 | 5701 | rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), |
michael@0 | 5702 | |
michael@0 | 5703 | cssShow = { position: "absolute", visibility: "hidden", display: "block" }, |
michael@0 | 5704 | cssNormalTransform = { |
michael@0 | 5705 | letterSpacing: "0", |
michael@0 | 5706 | fontWeight: "400" |
michael@0 | 5707 | }, |
michael@0 | 5708 | |
michael@0 | 5709 | cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; |
michael@0 | 5710 | |
michael@0 | 5711 | // return a css property mapped to a potentially vendor prefixed property |
michael@0 | 5712 | function vendorPropName( style, name ) { |
michael@0 | 5713 | |
michael@0 | 5714 | // shortcut for names that are not vendor prefixed |
michael@0 | 5715 | if ( name in style ) { |
michael@0 | 5716 | return name; |
michael@0 | 5717 | } |
michael@0 | 5718 | |
michael@0 | 5719 | // check for vendor prefixed names |
michael@0 | 5720 | var capName = name[0].toUpperCase() + name.slice(1), |
michael@0 | 5721 | origName = name, |
michael@0 | 5722 | i = cssPrefixes.length; |
michael@0 | 5723 | |
michael@0 | 5724 | while ( i-- ) { |
michael@0 | 5725 | name = cssPrefixes[ i ] + capName; |
michael@0 | 5726 | if ( name in style ) { |
michael@0 | 5727 | return name; |
michael@0 | 5728 | } |
michael@0 | 5729 | } |
michael@0 | 5730 | |
michael@0 | 5731 | return origName; |
michael@0 | 5732 | } |
michael@0 | 5733 | |
michael@0 | 5734 | function setPositiveNumber( elem, value, subtract ) { |
michael@0 | 5735 | var matches = rnumsplit.exec( value ); |
michael@0 | 5736 | return matches ? |
michael@0 | 5737 | // Guard against undefined "subtract", e.g., when used as in cssHooks |
michael@0 | 5738 | Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : |
michael@0 | 5739 | value; |
michael@0 | 5740 | } |
michael@0 | 5741 | |
michael@0 | 5742 | function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { |
michael@0 | 5743 | var i = extra === ( isBorderBox ? "border" : "content" ) ? |
michael@0 | 5744 | // If we already have the right measurement, avoid augmentation |
michael@0 | 5745 | 4 : |
michael@0 | 5746 | // Otherwise initialize for horizontal or vertical properties |
michael@0 | 5747 | name === "width" ? 1 : 0, |
michael@0 | 5748 | |
michael@0 | 5749 | val = 0; |
michael@0 | 5750 | |
michael@0 | 5751 | for ( ; i < 4; i += 2 ) { |
michael@0 | 5752 | // both box models exclude margin, so add it if we want it |
michael@0 | 5753 | if ( extra === "margin" ) { |
michael@0 | 5754 | val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); |
michael@0 | 5755 | } |
michael@0 | 5756 | |
michael@0 | 5757 | if ( isBorderBox ) { |
michael@0 | 5758 | // border-box includes padding, so remove it if we want content |
michael@0 | 5759 | if ( extra === "content" ) { |
michael@0 | 5760 | val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); |
michael@0 | 5761 | } |
michael@0 | 5762 | |
michael@0 | 5763 | // at this point, extra isn't border nor margin, so remove border |
michael@0 | 5764 | if ( extra !== "margin" ) { |
michael@0 | 5765 | val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); |
michael@0 | 5766 | } |
michael@0 | 5767 | } else { |
michael@0 | 5768 | // at this point, extra isn't content, so add padding |
michael@0 | 5769 | val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); |
michael@0 | 5770 | |
michael@0 | 5771 | // at this point, extra isn't content nor padding, so add border |
michael@0 | 5772 | if ( extra !== "padding" ) { |
michael@0 | 5773 | val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); |
michael@0 | 5774 | } |
michael@0 | 5775 | } |
michael@0 | 5776 | } |
michael@0 | 5777 | |
michael@0 | 5778 | return val; |
michael@0 | 5779 | } |
michael@0 | 5780 | |
michael@0 | 5781 | function getWidthOrHeight( elem, name, extra ) { |
michael@0 | 5782 | |
michael@0 | 5783 | // Start with offset property, which is equivalent to the border-box value |
michael@0 | 5784 | var valueIsBorderBox = true, |
michael@0 | 5785 | val = name === "width" ? elem.offsetWidth : elem.offsetHeight, |
michael@0 | 5786 | styles = getStyles( elem ), |
michael@0 | 5787 | isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; |
michael@0 | 5788 | |
michael@0 | 5789 | // some non-html elements return undefined for offsetWidth, so check for null/undefined |
michael@0 | 5790 | // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 |
michael@0 | 5791 | // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 |
michael@0 | 5792 | if ( val <= 0 || val == null ) { |
michael@0 | 5793 | // Fall back to computed then uncomputed css if necessary |
michael@0 | 5794 | val = curCSS( elem, name, styles ); |
michael@0 | 5795 | if ( val < 0 || val == null ) { |
michael@0 | 5796 | val = elem.style[ name ]; |
michael@0 | 5797 | } |
michael@0 | 5798 | |
michael@0 | 5799 | // Computed unit is not pixels. Stop here and return. |
michael@0 | 5800 | if ( rnumnonpx.test(val) ) { |
michael@0 | 5801 | return val; |
michael@0 | 5802 | } |
michael@0 | 5803 | |
michael@0 | 5804 | // we need the check for style in case a browser which returns unreliable values |
michael@0 | 5805 | // for getComputedStyle silently falls back to the reliable elem.style |
michael@0 | 5806 | valueIsBorderBox = isBorderBox && |
michael@0 | 5807 | ( support.boxSizingReliable() || val === elem.style[ name ] ); |
michael@0 | 5808 | |
michael@0 | 5809 | // Normalize "", auto, and prepare for extra |
michael@0 | 5810 | val = parseFloat( val ) || 0; |
michael@0 | 5811 | } |
michael@0 | 5812 | |
michael@0 | 5813 | // use the active box-sizing model to add/subtract irrelevant styles |
michael@0 | 5814 | return ( val + |
michael@0 | 5815 | augmentWidthOrHeight( |
michael@0 | 5816 | elem, |
michael@0 | 5817 | name, |
michael@0 | 5818 | extra || ( isBorderBox ? "border" : "content" ), |
michael@0 | 5819 | valueIsBorderBox, |
michael@0 | 5820 | styles |
michael@0 | 5821 | ) |
michael@0 | 5822 | ) + "px"; |
michael@0 | 5823 | } |
michael@0 | 5824 | |
michael@0 | 5825 | function showHide( elements, show ) { |
michael@0 | 5826 | var display, elem, hidden, |
michael@0 | 5827 | values = [], |
michael@0 | 5828 | index = 0, |
michael@0 | 5829 | length = elements.length; |
michael@0 | 5830 | |
michael@0 | 5831 | for ( ; index < length; index++ ) { |
michael@0 | 5832 | elem = elements[ index ]; |
michael@0 | 5833 | if ( !elem.style ) { |
michael@0 | 5834 | continue; |
michael@0 | 5835 | } |
michael@0 | 5836 | |
michael@0 | 5837 | values[ index ] = data_priv.get( elem, "olddisplay" ); |
michael@0 | 5838 | display = elem.style.display; |
michael@0 | 5839 | if ( show ) { |
michael@0 | 5840 | // Reset the inline display of this element to learn if it is |
michael@0 | 5841 | // being hidden by cascaded rules or not |
michael@0 | 5842 | if ( !values[ index ] && display === "none" ) { |
michael@0 | 5843 | elem.style.display = ""; |
michael@0 | 5844 | } |
michael@0 | 5845 | |
michael@0 | 5846 | // Set elements which have been overridden with display: none |
michael@0 | 5847 | // in a stylesheet to whatever the default browser style is |
michael@0 | 5848 | // for such an element |
michael@0 | 5849 | if ( elem.style.display === "" && isHidden( elem ) ) { |
michael@0 | 5850 | values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) ); |
michael@0 | 5851 | } |
michael@0 | 5852 | } else { |
michael@0 | 5853 | hidden = isHidden( elem ); |
michael@0 | 5854 | |
michael@0 | 5855 | if ( display !== "none" || !hidden ) { |
michael@0 | 5856 | data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); |
michael@0 | 5857 | } |
michael@0 | 5858 | } |
michael@0 | 5859 | } |
michael@0 | 5860 | |
michael@0 | 5861 | // Set the display of most of the elements in a second loop |
michael@0 | 5862 | // to avoid the constant reflow |
michael@0 | 5863 | for ( index = 0; index < length; index++ ) { |
michael@0 | 5864 | elem = elements[ index ]; |
michael@0 | 5865 | if ( !elem.style ) { |
michael@0 | 5866 | continue; |
michael@0 | 5867 | } |
michael@0 | 5868 | if ( !show || elem.style.display === "none" || elem.style.display === "" ) { |
michael@0 | 5869 | elem.style.display = show ? values[ index ] || "" : "none"; |
michael@0 | 5870 | } |
michael@0 | 5871 | } |
michael@0 | 5872 | |
michael@0 | 5873 | return elements; |
michael@0 | 5874 | } |
michael@0 | 5875 | |
michael@0 | 5876 | jQuery.extend({ |
michael@0 | 5877 | // Add in style property hooks for overriding the default |
michael@0 | 5878 | // behavior of getting and setting a style property |
michael@0 | 5879 | cssHooks: { |
michael@0 | 5880 | opacity: { |
michael@0 | 5881 | get: function( elem, computed ) { |
michael@0 | 5882 | if ( computed ) { |
michael@0 | 5883 | // We should always get a number back from opacity |
michael@0 | 5884 | var ret = curCSS( elem, "opacity" ); |
michael@0 | 5885 | return ret === "" ? "1" : ret; |
michael@0 | 5886 | } |
michael@0 | 5887 | } |
michael@0 | 5888 | } |
michael@0 | 5889 | }, |
michael@0 | 5890 | |
michael@0 | 5891 | // Don't automatically add "px" to these possibly-unitless properties |
michael@0 | 5892 | cssNumber: { |
michael@0 | 5893 | "columnCount": true, |
michael@0 | 5894 | "fillOpacity": true, |
michael@0 | 5895 | "flexGrow": true, |
michael@0 | 5896 | "flexShrink": true, |
michael@0 | 5897 | "fontWeight": true, |
michael@0 | 5898 | "lineHeight": true, |
michael@0 | 5899 | "opacity": true, |
michael@0 | 5900 | "order": true, |
michael@0 | 5901 | "orphans": true, |
michael@0 | 5902 | "widows": true, |
michael@0 | 5903 | "zIndex": true, |
michael@0 | 5904 | "zoom": true |
michael@0 | 5905 | }, |
michael@0 | 5906 | |
michael@0 | 5907 | // Add in properties whose names you wish to fix before |
michael@0 | 5908 | // setting or getting the value |
michael@0 | 5909 | cssProps: { |
michael@0 | 5910 | // normalize float css property |
michael@0 | 5911 | "float": "cssFloat" |
michael@0 | 5912 | }, |
michael@0 | 5913 | |
michael@0 | 5914 | // Get and set the style property on a DOM Node |
michael@0 | 5915 | style: function( elem, name, value, extra ) { |
michael@0 | 5916 | // Don't set styles on text and comment nodes |
michael@0 | 5917 | if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { |
michael@0 | 5918 | return; |
michael@0 | 5919 | } |
michael@0 | 5920 | |
michael@0 | 5921 | // Make sure that we're working with the right name |
michael@0 | 5922 | var ret, type, hooks, |
michael@0 | 5923 | origName = jQuery.camelCase( name ), |
michael@0 | 5924 | style = elem.style; |
michael@0 | 5925 | |
michael@0 | 5926 | name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); |
michael@0 | 5927 | |
michael@0 | 5928 | // gets hook for the prefixed version |
michael@0 | 5929 | // followed by the unprefixed version |
michael@0 | 5930 | hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; |
michael@0 | 5931 | |
michael@0 | 5932 | // Check if we're setting a value |
michael@0 | 5933 | if ( value !== undefined ) { |
michael@0 | 5934 | type = typeof value; |
michael@0 | 5935 | |
michael@0 | 5936 | // convert relative number strings (+= or -=) to relative numbers. #7345 |
michael@0 | 5937 | if ( type === "string" && (ret = rrelNum.exec( value )) ) { |
michael@0 | 5938 | value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); |
michael@0 | 5939 | // Fixes bug #9237 |
michael@0 | 5940 | type = "number"; |
michael@0 | 5941 | } |
michael@0 | 5942 | |
michael@0 | 5943 | // Make sure that null and NaN values aren't set. See: #7116 |
michael@0 | 5944 | if ( value == null || value !== value ) { |
michael@0 | 5945 | return; |
michael@0 | 5946 | } |
michael@0 | 5947 | |
michael@0 | 5948 | // If a number was passed in, add 'px' to the (except for certain CSS properties) |
michael@0 | 5949 | if ( type === "number" && !jQuery.cssNumber[ origName ] ) { |
michael@0 | 5950 | value += "px"; |
michael@0 | 5951 | } |
michael@0 | 5952 | |
michael@0 | 5953 | // Fixes #8908, it can be done more correctly by specifying setters in cssHooks, |
michael@0 | 5954 | // but it would mean to define eight (for every problematic property) identical functions |
michael@0 | 5955 | if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { |
michael@0 | 5956 | style[ name ] = "inherit"; |
michael@0 | 5957 | } |
michael@0 | 5958 | |
michael@0 | 5959 | // If a hook was provided, use that value, otherwise just set the specified value |
michael@0 | 5960 | if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { |
michael@0 | 5961 | style[ name ] = value; |
michael@0 | 5962 | } |
michael@0 | 5963 | |
michael@0 | 5964 | } else { |
michael@0 | 5965 | // If a hook was provided get the non-computed value from there |
michael@0 | 5966 | if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { |
michael@0 | 5967 | return ret; |
michael@0 | 5968 | } |
michael@0 | 5969 | |
michael@0 | 5970 | // Otherwise just get the value from the style object |
michael@0 | 5971 | return style[ name ]; |
michael@0 | 5972 | } |
michael@0 | 5973 | }, |
michael@0 | 5974 | |
michael@0 | 5975 | css: function( elem, name, extra, styles ) { |
michael@0 | 5976 | var val, num, hooks, |
michael@0 | 5977 | origName = jQuery.camelCase( name ); |
michael@0 | 5978 | |
michael@0 | 5979 | // Make sure that we're working with the right name |
michael@0 | 5980 | name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); |
michael@0 | 5981 | |
michael@0 | 5982 | // gets hook for the prefixed version |
michael@0 | 5983 | // followed by the unprefixed version |
michael@0 | 5984 | hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; |
michael@0 | 5985 | |
michael@0 | 5986 | // If a hook was provided get the computed value from there |
michael@0 | 5987 | if ( hooks && "get" in hooks ) { |
michael@0 | 5988 | val = hooks.get( elem, true, extra ); |
michael@0 | 5989 | } |
michael@0 | 5990 | |
michael@0 | 5991 | // Otherwise, if a way to get the computed value exists, use that |
michael@0 | 5992 | if ( val === undefined ) { |
michael@0 | 5993 | val = curCSS( elem, name, styles ); |
michael@0 | 5994 | } |
michael@0 | 5995 | |
michael@0 | 5996 | //convert "normal" to computed value |
michael@0 | 5997 | if ( val === "normal" && name in cssNormalTransform ) { |
michael@0 | 5998 | val = cssNormalTransform[ name ]; |
michael@0 | 5999 | } |
michael@0 | 6000 | |
michael@0 | 6001 | // Return, converting to number if forced or a qualifier was provided and val looks numeric |
michael@0 | 6002 | if ( extra === "" || extra ) { |
michael@0 | 6003 | num = parseFloat( val ); |
michael@0 | 6004 | return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; |
michael@0 | 6005 | } |
michael@0 | 6006 | return val; |
michael@0 | 6007 | } |
michael@0 | 6008 | }); |
michael@0 | 6009 | |
michael@0 | 6010 | jQuery.each([ "height", "width" ], function( i, name ) { |
michael@0 | 6011 | jQuery.cssHooks[ name ] = { |
michael@0 | 6012 | get: function( elem, computed, extra ) { |
michael@0 | 6013 | if ( computed ) { |
michael@0 | 6014 | // certain elements can have dimension info if we invisibly show them |
michael@0 | 6015 | // however, it must have a current display style that would benefit from this |
michael@0 | 6016 | return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? |
michael@0 | 6017 | jQuery.swap( elem, cssShow, function() { |
michael@0 | 6018 | return getWidthOrHeight( elem, name, extra ); |
michael@0 | 6019 | }) : |
michael@0 | 6020 | getWidthOrHeight( elem, name, extra ); |
michael@0 | 6021 | } |
michael@0 | 6022 | }, |
michael@0 | 6023 | |
michael@0 | 6024 | set: function( elem, value, extra ) { |
michael@0 | 6025 | var styles = extra && getStyles( elem ); |
michael@0 | 6026 | return setPositiveNumber( elem, value, extra ? |
michael@0 | 6027 | augmentWidthOrHeight( |
michael@0 | 6028 | elem, |
michael@0 | 6029 | name, |
michael@0 | 6030 | extra, |
michael@0 | 6031 | jQuery.css( elem, "boxSizing", false, styles ) === "border-box", |
michael@0 | 6032 | styles |
michael@0 | 6033 | ) : 0 |
michael@0 | 6034 | ); |
michael@0 | 6035 | } |
michael@0 | 6036 | }; |
michael@0 | 6037 | }); |
michael@0 | 6038 | |
michael@0 | 6039 | // Support: Android 2.3 |
michael@0 | 6040 | jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, |
michael@0 | 6041 | function( elem, computed ) { |
michael@0 | 6042 | if ( computed ) { |
michael@0 | 6043 | // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right |
michael@0 | 6044 | // Work around by temporarily setting element display to inline-block |
michael@0 | 6045 | return jQuery.swap( elem, { "display": "inline-block" }, |
michael@0 | 6046 | curCSS, [ elem, "marginRight" ] ); |
michael@0 | 6047 | } |
michael@0 | 6048 | } |
michael@0 | 6049 | ); |
michael@0 | 6050 | |
michael@0 | 6051 | // These hooks are used by animate to expand properties |
michael@0 | 6052 | jQuery.each({ |
michael@0 | 6053 | margin: "", |
michael@0 | 6054 | padding: "", |
michael@0 | 6055 | border: "Width" |
michael@0 | 6056 | }, function( prefix, suffix ) { |
michael@0 | 6057 | jQuery.cssHooks[ prefix + suffix ] = { |
michael@0 | 6058 | expand: function( value ) { |
michael@0 | 6059 | var i = 0, |
michael@0 | 6060 | expanded = {}, |
michael@0 | 6061 | |
michael@0 | 6062 | // assumes a single number if not a string |
michael@0 | 6063 | parts = typeof value === "string" ? value.split(" ") : [ value ]; |
michael@0 | 6064 | |
michael@0 | 6065 | for ( ; i < 4; i++ ) { |
michael@0 | 6066 | expanded[ prefix + cssExpand[ i ] + suffix ] = |
michael@0 | 6067 | parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; |
michael@0 | 6068 | } |
michael@0 | 6069 | |
michael@0 | 6070 | return expanded; |
michael@0 | 6071 | } |
michael@0 | 6072 | }; |
michael@0 | 6073 | |
michael@0 | 6074 | if ( !rmargin.test( prefix ) ) { |
michael@0 | 6075 | jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; |
michael@0 | 6076 | } |
michael@0 | 6077 | }); |
michael@0 | 6078 | |
michael@0 | 6079 | jQuery.fn.extend({ |
michael@0 | 6080 | css: function( name, value ) { |
michael@0 | 6081 | return access( this, function( elem, name, value ) { |
michael@0 | 6082 | var styles, len, |
michael@0 | 6083 | map = {}, |
michael@0 | 6084 | i = 0; |
michael@0 | 6085 | |
michael@0 | 6086 | if ( jQuery.isArray( name ) ) { |
michael@0 | 6087 | styles = getStyles( elem ); |
michael@0 | 6088 | len = name.length; |
michael@0 | 6089 | |
michael@0 | 6090 | for ( ; i < len; i++ ) { |
michael@0 | 6091 | map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); |
michael@0 | 6092 | } |
michael@0 | 6093 | |
michael@0 | 6094 | return map; |
michael@0 | 6095 | } |
michael@0 | 6096 | |
michael@0 | 6097 | return value !== undefined ? |
michael@0 | 6098 | jQuery.style( elem, name, value ) : |
michael@0 | 6099 | jQuery.css( elem, name ); |
michael@0 | 6100 | }, name, value, arguments.length > 1 ); |
michael@0 | 6101 | }, |
michael@0 | 6102 | show: function() { |
michael@0 | 6103 | return showHide( this, true ); |
michael@0 | 6104 | }, |
michael@0 | 6105 | hide: function() { |
michael@0 | 6106 | return showHide( this ); |
michael@0 | 6107 | }, |
michael@0 | 6108 | toggle: function( state ) { |
michael@0 | 6109 | if ( typeof state === "boolean" ) { |
michael@0 | 6110 | return state ? this.show() : this.hide(); |
michael@0 | 6111 | } |
michael@0 | 6112 | |
michael@0 | 6113 | return this.each(function() { |
michael@0 | 6114 | if ( isHidden( this ) ) { |
michael@0 | 6115 | jQuery( this ).show(); |
michael@0 | 6116 | } else { |
michael@0 | 6117 | jQuery( this ).hide(); |
michael@0 | 6118 | } |
michael@0 | 6119 | }); |
michael@0 | 6120 | } |
michael@0 | 6121 | }); |
michael@0 | 6122 | |
michael@0 | 6123 | |
michael@0 | 6124 | function Tween( elem, options, prop, end, easing ) { |
michael@0 | 6125 | return new Tween.prototype.init( elem, options, prop, end, easing ); |
michael@0 | 6126 | } |
michael@0 | 6127 | jQuery.Tween = Tween; |
michael@0 | 6128 | |
michael@0 | 6129 | Tween.prototype = { |
michael@0 | 6130 | constructor: Tween, |
michael@0 | 6131 | init: function( elem, options, prop, end, easing, unit ) { |
michael@0 | 6132 | this.elem = elem; |
michael@0 | 6133 | this.prop = prop; |
michael@0 | 6134 | this.easing = easing || "swing"; |
michael@0 | 6135 | this.options = options; |
michael@0 | 6136 | this.start = this.now = this.cur(); |
michael@0 | 6137 | this.end = end; |
michael@0 | 6138 | this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); |
michael@0 | 6139 | }, |
michael@0 | 6140 | cur: function() { |
michael@0 | 6141 | var hooks = Tween.propHooks[ this.prop ]; |
michael@0 | 6142 | |
michael@0 | 6143 | return hooks && hooks.get ? |
michael@0 | 6144 | hooks.get( this ) : |
michael@0 | 6145 | Tween.propHooks._default.get( this ); |
michael@0 | 6146 | }, |
michael@0 | 6147 | run: function( percent ) { |
michael@0 | 6148 | var eased, |
michael@0 | 6149 | hooks = Tween.propHooks[ this.prop ]; |
michael@0 | 6150 | |
michael@0 | 6151 | if ( this.options.duration ) { |
michael@0 | 6152 | this.pos = eased = jQuery.easing[ this.easing ]( |
michael@0 | 6153 | percent, this.options.duration * percent, 0, 1, this.options.duration |
michael@0 | 6154 | ); |
michael@0 | 6155 | } else { |
michael@0 | 6156 | this.pos = eased = percent; |
michael@0 | 6157 | } |
michael@0 | 6158 | this.now = ( this.end - this.start ) * eased + this.start; |
michael@0 | 6159 | |
michael@0 | 6160 | if ( this.options.step ) { |
michael@0 | 6161 | this.options.step.call( this.elem, this.now, this ); |
michael@0 | 6162 | } |
michael@0 | 6163 | |
michael@0 | 6164 | if ( hooks && hooks.set ) { |
michael@0 | 6165 | hooks.set( this ); |
michael@0 | 6166 | } else { |
michael@0 | 6167 | Tween.propHooks._default.set( this ); |
michael@0 | 6168 | } |
michael@0 | 6169 | return this; |
michael@0 | 6170 | } |
michael@0 | 6171 | }; |
michael@0 | 6172 | |
michael@0 | 6173 | Tween.prototype.init.prototype = Tween.prototype; |
michael@0 | 6174 | |
michael@0 | 6175 | Tween.propHooks = { |
michael@0 | 6176 | _default: { |
michael@0 | 6177 | get: function( tween ) { |
michael@0 | 6178 | var result; |
michael@0 | 6179 | |
michael@0 | 6180 | if ( tween.elem[ tween.prop ] != null && |
michael@0 | 6181 | (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { |
michael@0 | 6182 | return tween.elem[ tween.prop ]; |
michael@0 | 6183 | } |
michael@0 | 6184 | |
michael@0 | 6185 | // passing an empty string as a 3rd parameter to .css will automatically |
michael@0 | 6186 | // attempt a parseFloat and fallback to a string if the parse fails |
michael@0 | 6187 | // so, simple values such as "10px" are parsed to Float. |
michael@0 | 6188 | // complex values such as "rotate(1rad)" are returned as is. |
michael@0 | 6189 | result = jQuery.css( tween.elem, tween.prop, "" ); |
michael@0 | 6190 | // Empty strings, null, undefined and "auto" are converted to 0. |
michael@0 | 6191 | return !result || result === "auto" ? 0 : result; |
michael@0 | 6192 | }, |
michael@0 | 6193 | set: function( tween ) { |
michael@0 | 6194 | // use step hook for back compat - use cssHook if its there - use .style if its |
michael@0 | 6195 | // available and use plain properties where available |
michael@0 | 6196 | if ( jQuery.fx.step[ tween.prop ] ) { |
michael@0 | 6197 | jQuery.fx.step[ tween.prop ]( tween ); |
michael@0 | 6198 | } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { |
michael@0 | 6199 | jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); |
michael@0 | 6200 | } else { |
michael@0 | 6201 | tween.elem[ tween.prop ] = tween.now; |
michael@0 | 6202 | } |
michael@0 | 6203 | } |
michael@0 | 6204 | } |
michael@0 | 6205 | }; |
michael@0 | 6206 | |
michael@0 | 6207 | // Support: IE9 |
michael@0 | 6208 | // Panic based approach to setting things on disconnected nodes |
michael@0 | 6209 | |
michael@0 | 6210 | Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { |
michael@0 | 6211 | set: function( tween ) { |
michael@0 | 6212 | if ( tween.elem.nodeType && tween.elem.parentNode ) { |
michael@0 | 6213 | tween.elem[ tween.prop ] = tween.now; |
michael@0 | 6214 | } |
michael@0 | 6215 | } |
michael@0 | 6216 | }; |
michael@0 | 6217 | |
michael@0 | 6218 | jQuery.easing = { |
michael@0 | 6219 | linear: function( p ) { |
michael@0 | 6220 | return p; |
michael@0 | 6221 | }, |
michael@0 | 6222 | swing: function( p ) { |
michael@0 | 6223 | return 0.5 - Math.cos( p * Math.PI ) / 2; |
michael@0 | 6224 | } |
michael@0 | 6225 | }; |
michael@0 | 6226 | |
michael@0 | 6227 | jQuery.fx = Tween.prototype.init; |
michael@0 | 6228 | |
michael@0 | 6229 | // Back Compat <1.8 extension point |
michael@0 | 6230 | jQuery.fx.step = {}; |
michael@0 | 6231 | |
michael@0 | 6232 | |
michael@0 | 6233 | |
michael@0 | 6234 | |
michael@0 | 6235 | var |
michael@0 | 6236 | fxNow, timerId, |
michael@0 | 6237 | rfxtypes = /^(?:toggle|show|hide)$/, |
michael@0 | 6238 | rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), |
michael@0 | 6239 | rrun = /queueHooks$/, |
michael@0 | 6240 | animationPrefilters = [ defaultPrefilter ], |
michael@0 | 6241 | tweeners = { |
michael@0 | 6242 | "*": [ function( prop, value ) { |
michael@0 | 6243 | var tween = this.createTween( prop, value ), |
michael@0 | 6244 | target = tween.cur(), |
michael@0 | 6245 | parts = rfxnum.exec( value ), |
michael@0 | 6246 | unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), |
michael@0 | 6247 | |
michael@0 | 6248 | // Starting value computation is required for potential unit mismatches |
michael@0 | 6249 | start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && |
michael@0 | 6250 | rfxnum.exec( jQuery.css( tween.elem, prop ) ), |
michael@0 | 6251 | scale = 1, |
michael@0 | 6252 | maxIterations = 20; |
michael@0 | 6253 | |
michael@0 | 6254 | if ( start && start[ 3 ] !== unit ) { |
michael@0 | 6255 | // Trust units reported by jQuery.css |
michael@0 | 6256 | unit = unit || start[ 3 ]; |
michael@0 | 6257 | |
michael@0 | 6258 | // Make sure we update the tween properties later on |
michael@0 | 6259 | parts = parts || []; |
michael@0 | 6260 | |
michael@0 | 6261 | // Iteratively approximate from a nonzero starting point |
michael@0 | 6262 | start = +target || 1; |
michael@0 | 6263 | |
michael@0 | 6264 | do { |
michael@0 | 6265 | // If previous iteration zeroed out, double until we get *something* |
michael@0 | 6266 | // Use a string for doubling factor so we don't accidentally see scale as unchanged below |
michael@0 | 6267 | scale = scale || ".5"; |
michael@0 | 6268 | |
michael@0 | 6269 | // Adjust and apply |
michael@0 | 6270 | start = start / scale; |
michael@0 | 6271 | jQuery.style( tween.elem, prop, start + unit ); |
michael@0 | 6272 | |
michael@0 | 6273 | // Update scale, tolerating zero or NaN from tween.cur() |
michael@0 | 6274 | // And breaking the loop if scale is unchanged or perfect, or if we've just had enough |
michael@0 | 6275 | } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); |
michael@0 | 6276 | } |
michael@0 | 6277 | |
michael@0 | 6278 | // Update tween properties |
michael@0 | 6279 | if ( parts ) { |
michael@0 | 6280 | start = tween.start = +start || +target || 0; |
michael@0 | 6281 | tween.unit = unit; |
michael@0 | 6282 | // If a +=/-= token was provided, we're doing a relative animation |
michael@0 | 6283 | tween.end = parts[ 1 ] ? |
michael@0 | 6284 | start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : |
michael@0 | 6285 | +parts[ 2 ]; |
michael@0 | 6286 | } |
michael@0 | 6287 | |
michael@0 | 6288 | return tween; |
michael@0 | 6289 | } ] |
michael@0 | 6290 | }; |
michael@0 | 6291 | |
michael@0 | 6292 | // Animations created synchronously will run synchronously |
michael@0 | 6293 | function createFxNow() { |
michael@0 | 6294 | setTimeout(function() { |
michael@0 | 6295 | fxNow = undefined; |
michael@0 | 6296 | }); |
michael@0 | 6297 | return ( fxNow = jQuery.now() ); |
michael@0 | 6298 | } |
michael@0 | 6299 | |
michael@0 | 6300 | // Generate parameters to create a standard animation |
michael@0 | 6301 | function genFx( type, includeWidth ) { |
michael@0 | 6302 | var which, |
michael@0 | 6303 | i = 0, |
michael@0 | 6304 | attrs = { height: type }; |
michael@0 | 6305 | |
michael@0 | 6306 | // if we include width, step value is 1 to do all cssExpand values, |
michael@0 | 6307 | // if we don't include width, step value is 2 to skip over Left and Right |
michael@0 | 6308 | includeWidth = includeWidth ? 1 : 0; |
michael@0 | 6309 | for ( ; i < 4 ; i += 2 - includeWidth ) { |
michael@0 | 6310 | which = cssExpand[ i ]; |
michael@0 | 6311 | attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; |
michael@0 | 6312 | } |
michael@0 | 6313 | |
michael@0 | 6314 | if ( includeWidth ) { |
michael@0 | 6315 | attrs.opacity = attrs.width = type; |
michael@0 | 6316 | } |
michael@0 | 6317 | |
michael@0 | 6318 | return attrs; |
michael@0 | 6319 | } |
michael@0 | 6320 | |
michael@0 | 6321 | function createTween( value, prop, animation ) { |
michael@0 | 6322 | var tween, |
michael@0 | 6323 | collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), |
michael@0 | 6324 | index = 0, |
michael@0 | 6325 | length = collection.length; |
michael@0 | 6326 | for ( ; index < length; index++ ) { |
michael@0 | 6327 | if ( (tween = collection[ index ].call( animation, prop, value )) ) { |
michael@0 | 6328 | |
michael@0 | 6329 | // we're done with this property |
michael@0 | 6330 | return tween; |
michael@0 | 6331 | } |
michael@0 | 6332 | } |
michael@0 | 6333 | } |
michael@0 | 6334 | |
michael@0 | 6335 | function defaultPrefilter( elem, props, opts ) { |
michael@0 | 6336 | /* jshint validthis: true */ |
michael@0 | 6337 | var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, |
michael@0 | 6338 | anim = this, |
michael@0 | 6339 | orig = {}, |
michael@0 | 6340 | style = elem.style, |
michael@0 | 6341 | hidden = elem.nodeType && isHidden( elem ), |
michael@0 | 6342 | dataShow = data_priv.get( elem, "fxshow" ); |
michael@0 | 6343 | |
michael@0 | 6344 | // handle queue: false promises |
michael@0 | 6345 | if ( !opts.queue ) { |
michael@0 | 6346 | hooks = jQuery._queueHooks( elem, "fx" ); |
michael@0 | 6347 | if ( hooks.unqueued == null ) { |
michael@0 | 6348 | hooks.unqueued = 0; |
michael@0 | 6349 | oldfire = hooks.empty.fire; |
michael@0 | 6350 | hooks.empty.fire = function() { |
michael@0 | 6351 | if ( !hooks.unqueued ) { |
michael@0 | 6352 | oldfire(); |
michael@0 | 6353 | } |
michael@0 | 6354 | }; |
michael@0 | 6355 | } |
michael@0 | 6356 | hooks.unqueued++; |
michael@0 | 6357 | |
michael@0 | 6358 | anim.always(function() { |
michael@0 | 6359 | // doing this makes sure that the complete handler will be called |
michael@0 | 6360 | // before this completes |
michael@0 | 6361 | anim.always(function() { |
michael@0 | 6362 | hooks.unqueued--; |
michael@0 | 6363 | if ( !jQuery.queue( elem, "fx" ).length ) { |
michael@0 | 6364 | hooks.empty.fire(); |
michael@0 | 6365 | } |
michael@0 | 6366 | }); |
michael@0 | 6367 | }); |
michael@0 | 6368 | } |
michael@0 | 6369 | |
michael@0 | 6370 | // height/width overflow pass |
michael@0 | 6371 | if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { |
michael@0 | 6372 | // Make sure that nothing sneaks out |
michael@0 | 6373 | // Record all 3 overflow attributes because IE9-10 do not |
michael@0 | 6374 | // change the overflow attribute when overflowX and |
michael@0 | 6375 | // overflowY are set to the same value |
michael@0 | 6376 | opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; |
michael@0 | 6377 | |
michael@0 | 6378 | // Set display property to inline-block for height/width |
michael@0 | 6379 | // animations on inline elements that are having width/height animated |
michael@0 | 6380 | display = jQuery.css( elem, "display" ); |
michael@0 | 6381 | |
michael@0 | 6382 | // Test default display if display is currently "none" |
michael@0 | 6383 | checkDisplay = display === "none" ? |
michael@0 | 6384 | data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; |
michael@0 | 6385 | |
michael@0 | 6386 | if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { |
michael@0 | 6387 | style.display = "inline-block"; |
michael@0 | 6388 | } |
michael@0 | 6389 | } |
michael@0 | 6390 | |
michael@0 | 6391 | if ( opts.overflow ) { |
michael@0 | 6392 | style.overflow = "hidden"; |
michael@0 | 6393 | anim.always(function() { |
michael@0 | 6394 | style.overflow = opts.overflow[ 0 ]; |
michael@0 | 6395 | style.overflowX = opts.overflow[ 1 ]; |
michael@0 | 6396 | style.overflowY = opts.overflow[ 2 ]; |
michael@0 | 6397 | }); |
michael@0 | 6398 | } |
michael@0 | 6399 | |
michael@0 | 6400 | // show/hide pass |
michael@0 | 6401 | for ( prop in props ) { |
michael@0 | 6402 | value = props[ prop ]; |
michael@0 | 6403 | if ( rfxtypes.exec( value ) ) { |
michael@0 | 6404 | delete props[ prop ]; |
michael@0 | 6405 | toggle = toggle || value === "toggle"; |
michael@0 | 6406 | if ( value === ( hidden ? "hide" : "show" ) ) { |
michael@0 | 6407 | |
michael@0 | 6408 | // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden |
michael@0 | 6409 | if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { |
michael@0 | 6410 | hidden = true; |
michael@0 | 6411 | } else { |
michael@0 | 6412 | continue; |
michael@0 | 6413 | } |
michael@0 | 6414 | } |
michael@0 | 6415 | orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); |
michael@0 | 6416 | |
michael@0 | 6417 | // Any non-fx value stops us from restoring the original display value |
michael@0 | 6418 | } else { |
michael@0 | 6419 | display = undefined; |
michael@0 | 6420 | } |
michael@0 | 6421 | } |
michael@0 | 6422 | |
michael@0 | 6423 | if ( !jQuery.isEmptyObject( orig ) ) { |
michael@0 | 6424 | if ( dataShow ) { |
michael@0 | 6425 | if ( "hidden" in dataShow ) { |
michael@0 | 6426 | hidden = dataShow.hidden; |
michael@0 | 6427 | } |
michael@0 | 6428 | } else { |
michael@0 | 6429 | dataShow = data_priv.access( elem, "fxshow", {} ); |
michael@0 | 6430 | } |
michael@0 | 6431 | |
michael@0 | 6432 | // store state if its toggle - enables .stop().toggle() to "reverse" |
michael@0 | 6433 | if ( toggle ) { |
michael@0 | 6434 | dataShow.hidden = !hidden; |
michael@0 | 6435 | } |
michael@0 | 6436 | if ( hidden ) { |
michael@0 | 6437 | jQuery( elem ).show(); |
michael@0 | 6438 | } else { |
michael@0 | 6439 | anim.done(function() { |
michael@0 | 6440 | jQuery( elem ).hide(); |
michael@0 | 6441 | }); |
michael@0 | 6442 | } |
michael@0 | 6443 | anim.done(function() { |
michael@0 | 6444 | var prop; |
michael@0 | 6445 | |
michael@0 | 6446 | data_priv.remove( elem, "fxshow" ); |
michael@0 | 6447 | for ( prop in orig ) { |
michael@0 | 6448 | jQuery.style( elem, prop, orig[ prop ] ); |
michael@0 | 6449 | } |
michael@0 | 6450 | }); |
michael@0 | 6451 | for ( prop in orig ) { |
michael@0 | 6452 | tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); |
michael@0 | 6453 | |
michael@0 | 6454 | if ( !( prop in dataShow ) ) { |
michael@0 | 6455 | dataShow[ prop ] = tween.start; |
michael@0 | 6456 | if ( hidden ) { |
michael@0 | 6457 | tween.end = tween.start; |
michael@0 | 6458 | tween.start = prop === "width" || prop === "height" ? 1 : 0; |
michael@0 | 6459 | } |
michael@0 | 6460 | } |
michael@0 | 6461 | } |
michael@0 | 6462 | |
michael@0 | 6463 | // If this is a noop like .hide().hide(), restore an overwritten display value |
michael@0 | 6464 | } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { |
michael@0 | 6465 | style.display = display; |
michael@0 | 6466 | } |
michael@0 | 6467 | } |
michael@0 | 6468 | |
michael@0 | 6469 | function propFilter( props, specialEasing ) { |
michael@0 | 6470 | var index, name, easing, value, hooks; |
michael@0 | 6471 | |
michael@0 | 6472 | // camelCase, specialEasing and expand cssHook pass |
michael@0 | 6473 | for ( index in props ) { |
michael@0 | 6474 | name = jQuery.camelCase( index ); |
michael@0 | 6475 | easing = specialEasing[ name ]; |
michael@0 | 6476 | value = props[ index ]; |
michael@0 | 6477 | if ( jQuery.isArray( value ) ) { |
michael@0 | 6478 | easing = value[ 1 ]; |
michael@0 | 6479 | value = props[ index ] = value[ 0 ]; |
michael@0 | 6480 | } |
michael@0 | 6481 | |
michael@0 | 6482 | if ( index !== name ) { |
michael@0 | 6483 | props[ name ] = value; |
michael@0 | 6484 | delete props[ index ]; |
michael@0 | 6485 | } |
michael@0 | 6486 | |
michael@0 | 6487 | hooks = jQuery.cssHooks[ name ]; |
michael@0 | 6488 | if ( hooks && "expand" in hooks ) { |
michael@0 | 6489 | value = hooks.expand( value ); |
michael@0 | 6490 | delete props[ name ]; |
michael@0 | 6491 | |
michael@0 | 6492 | // not quite $.extend, this wont overwrite keys already present. |
michael@0 | 6493 | // also - reusing 'index' from above because we have the correct "name" |
michael@0 | 6494 | for ( index in value ) { |
michael@0 | 6495 | if ( !( index in props ) ) { |
michael@0 | 6496 | props[ index ] = value[ index ]; |
michael@0 | 6497 | specialEasing[ index ] = easing; |
michael@0 | 6498 | } |
michael@0 | 6499 | } |
michael@0 | 6500 | } else { |
michael@0 | 6501 | specialEasing[ name ] = easing; |
michael@0 | 6502 | } |
michael@0 | 6503 | } |
michael@0 | 6504 | } |
michael@0 | 6505 | |
michael@0 | 6506 | function Animation( elem, properties, options ) { |
michael@0 | 6507 | var result, |
michael@0 | 6508 | stopped, |
michael@0 | 6509 | index = 0, |
michael@0 | 6510 | length = animationPrefilters.length, |
michael@0 | 6511 | deferred = jQuery.Deferred().always( function() { |
michael@0 | 6512 | // don't match elem in the :animated selector |
michael@0 | 6513 | delete tick.elem; |
michael@0 | 6514 | }), |
michael@0 | 6515 | tick = function() { |
michael@0 | 6516 | if ( stopped ) { |
michael@0 | 6517 | return false; |
michael@0 | 6518 | } |
michael@0 | 6519 | var currentTime = fxNow || createFxNow(), |
michael@0 | 6520 | remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), |
michael@0 | 6521 | // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) |
michael@0 | 6522 | temp = remaining / animation.duration || 0, |
michael@0 | 6523 | percent = 1 - temp, |
michael@0 | 6524 | index = 0, |
michael@0 | 6525 | length = animation.tweens.length; |
michael@0 | 6526 | |
michael@0 | 6527 | for ( ; index < length ; index++ ) { |
michael@0 | 6528 | animation.tweens[ index ].run( percent ); |
michael@0 | 6529 | } |
michael@0 | 6530 | |
michael@0 | 6531 | deferred.notifyWith( elem, [ animation, percent, remaining ]); |
michael@0 | 6532 | |
michael@0 | 6533 | if ( percent < 1 && length ) { |
michael@0 | 6534 | return remaining; |
michael@0 | 6535 | } else { |
michael@0 | 6536 | deferred.resolveWith( elem, [ animation ] ); |
michael@0 | 6537 | return false; |
michael@0 | 6538 | } |
michael@0 | 6539 | }, |
michael@0 | 6540 | animation = deferred.promise({ |
michael@0 | 6541 | elem: elem, |
michael@0 | 6542 | props: jQuery.extend( {}, properties ), |
michael@0 | 6543 | opts: jQuery.extend( true, { specialEasing: {} }, options ), |
michael@0 | 6544 | originalProperties: properties, |
michael@0 | 6545 | originalOptions: options, |
michael@0 | 6546 | startTime: fxNow || createFxNow(), |
michael@0 | 6547 | duration: options.duration, |
michael@0 | 6548 | tweens: [], |
michael@0 | 6549 | createTween: function( prop, end ) { |
michael@0 | 6550 | var tween = jQuery.Tween( elem, animation.opts, prop, end, |
michael@0 | 6551 | animation.opts.specialEasing[ prop ] || animation.opts.easing ); |
michael@0 | 6552 | animation.tweens.push( tween ); |
michael@0 | 6553 | return tween; |
michael@0 | 6554 | }, |
michael@0 | 6555 | stop: function( gotoEnd ) { |
michael@0 | 6556 | var index = 0, |
michael@0 | 6557 | // if we are going to the end, we want to run all the tweens |
michael@0 | 6558 | // otherwise we skip this part |
michael@0 | 6559 | length = gotoEnd ? animation.tweens.length : 0; |
michael@0 | 6560 | if ( stopped ) { |
michael@0 | 6561 | return this; |
michael@0 | 6562 | } |
michael@0 | 6563 | stopped = true; |
michael@0 | 6564 | for ( ; index < length ; index++ ) { |
michael@0 | 6565 | animation.tweens[ index ].run( 1 ); |
michael@0 | 6566 | } |
michael@0 | 6567 | |
michael@0 | 6568 | // resolve when we played the last frame |
michael@0 | 6569 | // otherwise, reject |
michael@0 | 6570 | if ( gotoEnd ) { |
michael@0 | 6571 | deferred.resolveWith( elem, [ animation, gotoEnd ] ); |
michael@0 | 6572 | } else { |
michael@0 | 6573 | deferred.rejectWith( elem, [ animation, gotoEnd ] ); |
michael@0 | 6574 | } |
michael@0 | 6575 | return this; |
michael@0 | 6576 | } |
michael@0 | 6577 | }), |
michael@0 | 6578 | props = animation.props; |
michael@0 | 6579 | |
michael@0 | 6580 | propFilter( props, animation.opts.specialEasing ); |
michael@0 | 6581 | |
michael@0 | 6582 | for ( ; index < length ; index++ ) { |
michael@0 | 6583 | result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); |
michael@0 | 6584 | if ( result ) { |
michael@0 | 6585 | return result; |
michael@0 | 6586 | } |
michael@0 | 6587 | } |
michael@0 | 6588 | |
michael@0 | 6589 | jQuery.map( props, createTween, animation ); |
michael@0 | 6590 | |
michael@0 | 6591 | if ( jQuery.isFunction( animation.opts.start ) ) { |
michael@0 | 6592 | animation.opts.start.call( elem, animation ); |
michael@0 | 6593 | } |
michael@0 | 6594 | |
michael@0 | 6595 | jQuery.fx.timer( |
michael@0 | 6596 | jQuery.extend( tick, { |
michael@0 | 6597 | elem: elem, |
michael@0 | 6598 | anim: animation, |
michael@0 | 6599 | queue: animation.opts.queue |
michael@0 | 6600 | }) |
michael@0 | 6601 | ); |
michael@0 | 6602 | |
michael@0 | 6603 | // attach callbacks from options |
michael@0 | 6604 | return animation.progress( animation.opts.progress ) |
michael@0 | 6605 | .done( animation.opts.done, animation.opts.complete ) |
michael@0 | 6606 | .fail( animation.opts.fail ) |
michael@0 | 6607 | .always( animation.opts.always ); |
michael@0 | 6608 | } |
michael@0 | 6609 | |
michael@0 | 6610 | jQuery.Animation = jQuery.extend( Animation, { |
michael@0 | 6611 | |
michael@0 | 6612 | tweener: function( props, callback ) { |
michael@0 | 6613 | if ( jQuery.isFunction( props ) ) { |
michael@0 | 6614 | callback = props; |
michael@0 | 6615 | props = [ "*" ]; |
michael@0 | 6616 | } else { |
michael@0 | 6617 | props = props.split(" "); |
michael@0 | 6618 | } |
michael@0 | 6619 | |
michael@0 | 6620 | var prop, |
michael@0 | 6621 | index = 0, |
michael@0 | 6622 | length = props.length; |
michael@0 | 6623 | |
michael@0 | 6624 | for ( ; index < length ; index++ ) { |
michael@0 | 6625 | prop = props[ index ]; |
michael@0 | 6626 | tweeners[ prop ] = tweeners[ prop ] || []; |
michael@0 | 6627 | tweeners[ prop ].unshift( callback ); |
michael@0 | 6628 | } |
michael@0 | 6629 | }, |
michael@0 | 6630 | |
michael@0 | 6631 | prefilter: function( callback, prepend ) { |
michael@0 | 6632 | if ( prepend ) { |
michael@0 | 6633 | animationPrefilters.unshift( callback ); |
michael@0 | 6634 | } else { |
michael@0 | 6635 | animationPrefilters.push( callback ); |
michael@0 | 6636 | } |
michael@0 | 6637 | } |
michael@0 | 6638 | }); |
michael@0 | 6639 | |
michael@0 | 6640 | jQuery.speed = function( speed, easing, fn ) { |
michael@0 | 6641 | var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { |
michael@0 | 6642 | complete: fn || !fn && easing || |
michael@0 | 6643 | jQuery.isFunction( speed ) && speed, |
michael@0 | 6644 | duration: speed, |
michael@0 | 6645 | easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing |
michael@0 | 6646 | }; |
michael@0 | 6647 | |
michael@0 | 6648 | opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : |
michael@0 | 6649 | opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; |
michael@0 | 6650 | |
michael@0 | 6651 | // normalize opt.queue - true/undefined/null -> "fx" |
michael@0 | 6652 | if ( opt.queue == null || opt.queue === true ) { |
michael@0 | 6653 | opt.queue = "fx"; |
michael@0 | 6654 | } |
michael@0 | 6655 | |
michael@0 | 6656 | // Queueing |
michael@0 | 6657 | opt.old = opt.complete; |
michael@0 | 6658 | |
michael@0 | 6659 | opt.complete = function() { |
michael@0 | 6660 | if ( jQuery.isFunction( opt.old ) ) { |
michael@0 | 6661 | opt.old.call( this ); |
michael@0 | 6662 | } |
michael@0 | 6663 | |
michael@0 | 6664 | if ( opt.queue ) { |
michael@0 | 6665 | jQuery.dequeue( this, opt.queue ); |
michael@0 | 6666 | } |
michael@0 | 6667 | }; |
michael@0 | 6668 | |
michael@0 | 6669 | return opt; |
michael@0 | 6670 | }; |
michael@0 | 6671 | |
michael@0 | 6672 | jQuery.fn.extend({ |
michael@0 | 6673 | fadeTo: function( speed, to, easing, callback ) { |
michael@0 | 6674 | |
michael@0 | 6675 | // show any hidden elements after setting opacity to 0 |
michael@0 | 6676 | return this.filter( isHidden ).css( "opacity", 0 ).show() |
michael@0 | 6677 | |
michael@0 | 6678 | // animate to the value specified |
michael@0 | 6679 | .end().animate({ opacity: to }, speed, easing, callback ); |
michael@0 | 6680 | }, |
michael@0 | 6681 | animate: function( prop, speed, easing, callback ) { |
michael@0 | 6682 | var empty = jQuery.isEmptyObject( prop ), |
michael@0 | 6683 | optall = jQuery.speed( speed, easing, callback ), |
michael@0 | 6684 | doAnimation = function() { |
michael@0 | 6685 | // Operate on a copy of prop so per-property easing won't be lost |
michael@0 | 6686 | var anim = Animation( this, jQuery.extend( {}, prop ), optall ); |
michael@0 | 6687 | |
michael@0 | 6688 | // Empty animations, or finishing resolves immediately |
michael@0 | 6689 | if ( empty || data_priv.get( this, "finish" ) ) { |
michael@0 | 6690 | anim.stop( true ); |
michael@0 | 6691 | } |
michael@0 | 6692 | }; |
michael@0 | 6693 | doAnimation.finish = doAnimation; |
michael@0 | 6694 | |
michael@0 | 6695 | return empty || optall.queue === false ? |
michael@0 | 6696 | this.each( doAnimation ) : |
michael@0 | 6697 | this.queue( optall.queue, doAnimation ); |
michael@0 | 6698 | }, |
michael@0 | 6699 | stop: function( type, clearQueue, gotoEnd ) { |
michael@0 | 6700 | var stopQueue = function( hooks ) { |
michael@0 | 6701 | var stop = hooks.stop; |
michael@0 | 6702 | delete hooks.stop; |
michael@0 | 6703 | stop( gotoEnd ); |
michael@0 | 6704 | }; |
michael@0 | 6705 | |
michael@0 | 6706 | if ( typeof type !== "string" ) { |
michael@0 | 6707 | gotoEnd = clearQueue; |
michael@0 | 6708 | clearQueue = type; |
michael@0 | 6709 | type = undefined; |
michael@0 | 6710 | } |
michael@0 | 6711 | if ( clearQueue && type !== false ) { |
michael@0 | 6712 | this.queue( type || "fx", [] ); |
michael@0 | 6713 | } |
michael@0 | 6714 | |
michael@0 | 6715 | return this.each(function() { |
michael@0 | 6716 | var dequeue = true, |
michael@0 | 6717 | index = type != null && type + "queueHooks", |
michael@0 | 6718 | timers = jQuery.timers, |
michael@0 | 6719 | data = data_priv.get( this ); |
michael@0 | 6720 | |
michael@0 | 6721 | if ( index ) { |
michael@0 | 6722 | if ( data[ index ] && data[ index ].stop ) { |
michael@0 | 6723 | stopQueue( data[ index ] ); |
michael@0 | 6724 | } |
michael@0 | 6725 | } else { |
michael@0 | 6726 | for ( index in data ) { |
michael@0 | 6727 | if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { |
michael@0 | 6728 | stopQueue( data[ index ] ); |
michael@0 | 6729 | } |
michael@0 | 6730 | } |
michael@0 | 6731 | } |
michael@0 | 6732 | |
michael@0 | 6733 | for ( index = timers.length; index--; ) { |
michael@0 | 6734 | if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { |
michael@0 | 6735 | timers[ index ].anim.stop( gotoEnd ); |
michael@0 | 6736 | dequeue = false; |
michael@0 | 6737 | timers.splice( index, 1 ); |
michael@0 | 6738 | } |
michael@0 | 6739 | } |
michael@0 | 6740 | |
michael@0 | 6741 | // start the next in the queue if the last step wasn't forced |
michael@0 | 6742 | // timers currently will call their complete callbacks, which will dequeue |
michael@0 | 6743 | // but only if they were gotoEnd |
michael@0 | 6744 | if ( dequeue || !gotoEnd ) { |
michael@0 | 6745 | jQuery.dequeue( this, type ); |
michael@0 | 6746 | } |
michael@0 | 6747 | }); |
michael@0 | 6748 | }, |
michael@0 | 6749 | finish: function( type ) { |
michael@0 | 6750 | if ( type !== false ) { |
michael@0 | 6751 | type = type || "fx"; |
michael@0 | 6752 | } |
michael@0 | 6753 | return this.each(function() { |
michael@0 | 6754 | var index, |
michael@0 | 6755 | data = data_priv.get( this ), |
michael@0 | 6756 | queue = data[ type + "queue" ], |
michael@0 | 6757 | hooks = data[ type + "queueHooks" ], |
michael@0 | 6758 | timers = jQuery.timers, |
michael@0 | 6759 | length = queue ? queue.length : 0; |
michael@0 | 6760 | |
michael@0 | 6761 | // enable finishing flag on private data |
michael@0 | 6762 | data.finish = true; |
michael@0 | 6763 | |
michael@0 | 6764 | // empty the queue first |
michael@0 | 6765 | jQuery.queue( this, type, [] ); |
michael@0 | 6766 | |
michael@0 | 6767 | if ( hooks && hooks.stop ) { |
michael@0 | 6768 | hooks.stop.call( this, true ); |
michael@0 | 6769 | } |
michael@0 | 6770 | |
michael@0 | 6771 | // look for any active animations, and finish them |
michael@0 | 6772 | for ( index = timers.length; index--; ) { |
michael@0 | 6773 | if ( timers[ index ].elem === this && timers[ index ].queue === type ) { |
michael@0 | 6774 | timers[ index ].anim.stop( true ); |
michael@0 | 6775 | timers.splice( index, 1 ); |
michael@0 | 6776 | } |
michael@0 | 6777 | } |
michael@0 | 6778 | |
michael@0 | 6779 | // look for any animations in the old queue and finish them |
michael@0 | 6780 | for ( index = 0; index < length; index++ ) { |
michael@0 | 6781 | if ( queue[ index ] && queue[ index ].finish ) { |
michael@0 | 6782 | queue[ index ].finish.call( this ); |
michael@0 | 6783 | } |
michael@0 | 6784 | } |
michael@0 | 6785 | |
michael@0 | 6786 | // turn off finishing flag |
michael@0 | 6787 | delete data.finish; |
michael@0 | 6788 | }); |
michael@0 | 6789 | } |
michael@0 | 6790 | }); |
michael@0 | 6791 | |
michael@0 | 6792 | jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { |
michael@0 | 6793 | var cssFn = jQuery.fn[ name ]; |
michael@0 | 6794 | jQuery.fn[ name ] = function( speed, easing, callback ) { |
michael@0 | 6795 | return speed == null || typeof speed === "boolean" ? |
michael@0 | 6796 | cssFn.apply( this, arguments ) : |
michael@0 | 6797 | this.animate( genFx( name, true ), speed, easing, callback ); |
michael@0 | 6798 | }; |
michael@0 | 6799 | }); |
michael@0 | 6800 | |
michael@0 | 6801 | // Generate shortcuts for custom animations |
michael@0 | 6802 | jQuery.each({ |
michael@0 | 6803 | slideDown: genFx("show"), |
michael@0 | 6804 | slideUp: genFx("hide"), |
michael@0 | 6805 | slideToggle: genFx("toggle"), |
michael@0 | 6806 | fadeIn: { opacity: "show" }, |
michael@0 | 6807 | fadeOut: { opacity: "hide" }, |
michael@0 | 6808 | fadeToggle: { opacity: "toggle" } |
michael@0 | 6809 | }, function( name, props ) { |
michael@0 | 6810 | jQuery.fn[ name ] = function( speed, easing, callback ) { |
michael@0 | 6811 | return this.animate( props, speed, easing, callback ); |
michael@0 | 6812 | }; |
michael@0 | 6813 | }); |
michael@0 | 6814 | |
michael@0 | 6815 | jQuery.timers = []; |
michael@0 | 6816 | jQuery.fx.tick = function() { |
michael@0 | 6817 | var timer, |
michael@0 | 6818 | i = 0, |
michael@0 | 6819 | timers = jQuery.timers; |
michael@0 | 6820 | |
michael@0 | 6821 | fxNow = jQuery.now(); |
michael@0 | 6822 | |
michael@0 | 6823 | for ( ; i < timers.length; i++ ) { |
michael@0 | 6824 | timer = timers[ i ]; |
michael@0 | 6825 | // Checks the timer has not already been removed |
michael@0 | 6826 | if ( !timer() && timers[ i ] === timer ) { |
michael@0 | 6827 | timers.splice( i--, 1 ); |
michael@0 | 6828 | } |
michael@0 | 6829 | } |
michael@0 | 6830 | |
michael@0 | 6831 | if ( !timers.length ) { |
michael@0 | 6832 | jQuery.fx.stop(); |
michael@0 | 6833 | } |
michael@0 | 6834 | fxNow = undefined; |
michael@0 | 6835 | }; |
michael@0 | 6836 | |
michael@0 | 6837 | jQuery.fx.timer = function( timer ) { |
michael@0 | 6838 | jQuery.timers.push( timer ); |
michael@0 | 6839 | if ( timer() ) { |
michael@0 | 6840 | jQuery.fx.start(); |
michael@0 | 6841 | } else { |
michael@0 | 6842 | jQuery.timers.pop(); |
michael@0 | 6843 | } |
michael@0 | 6844 | }; |
michael@0 | 6845 | |
michael@0 | 6846 | jQuery.fx.interval = 13; |
michael@0 | 6847 | |
michael@0 | 6848 | jQuery.fx.start = function() { |
michael@0 | 6849 | if ( !timerId ) { |
michael@0 | 6850 | timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); |
michael@0 | 6851 | } |
michael@0 | 6852 | }; |
michael@0 | 6853 | |
michael@0 | 6854 | jQuery.fx.stop = function() { |
michael@0 | 6855 | clearInterval( timerId ); |
michael@0 | 6856 | timerId = null; |
michael@0 | 6857 | }; |
michael@0 | 6858 | |
michael@0 | 6859 | jQuery.fx.speeds = { |
michael@0 | 6860 | slow: 600, |
michael@0 | 6861 | fast: 200, |
michael@0 | 6862 | // Default speed |
michael@0 | 6863 | _default: 400 |
michael@0 | 6864 | }; |
michael@0 | 6865 | |
michael@0 | 6866 | |
michael@0 | 6867 | // Based off of the plugin by Clint Helfers, with permission. |
michael@0 | 6868 | // http://blindsignals.com/index.php/2009/07/jquery-delay/ |
michael@0 | 6869 | jQuery.fn.delay = function( time, type ) { |
michael@0 | 6870 | time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; |
michael@0 | 6871 | type = type || "fx"; |
michael@0 | 6872 | |
michael@0 | 6873 | return this.queue( type, function( next, hooks ) { |
michael@0 | 6874 | var timeout = setTimeout( next, time ); |
michael@0 | 6875 | hooks.stop = function() { |
michael@0 | 6876 | clearTimeout( timeout ); |
michael@0 | 6877 | }; |
michael@0 | 6878 | }); |
michael@0 | 6879 | }; |
michael@0 | 6880 | |
michael@0 | 6881 | |
michael@0 | 6882 | (function() { |
michael@0 | 6883 | var input = document.createElement( "input" ), |
michael@0 | 6884 | select = document.createElement( "select" ), |
michael@0 | 6885 | opt = select.appendChild( document.createElement( "option" ) ); |
michael@0 | 6886 | |
michael@0 | 6887 | input.type = "checkbox"; |
michael@0 | 6888 | |
michael@0 | 6889 | // Support: iOS 5.1, Android 4.x, Android 2.3 |
michael@0 | 6890 | // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere) |
michael@0 | 6891 | support.checkOn = input.value !== ""; |
michael@0 | 6892 | |
michael@0 | 6893 | // Must access the parent to make an option select properly |
michael@0 | 6894 | // Support: IE9, IE10 |
michael@0 | 6895 | support.optSelected = opt.selected; |
michael@0 | 6896 | |
michael@0 | 6897 | // Make sure that the options inside disabled selects aren't marked as disabled |
michael@0 | 6898 | // (WebKit marks them as disabled) |
michael@0 | 6899 | select.disabled = true; |
michael@0 | 6900 | support.optDisabled = !opt.disabled; |
michael@0 | 6901 | |
michael@0 | 6902 | // Check if an input maintains its value after becoming a radio |
michael@0 | 6903 | // Support: IE9, IE10 |
michael@0 | 6904 | input = document.createElement( "input" ); |
michael@0 | 6905 | input.value = "t"; |
michael@0 | 6906 | input.type = "radio"; |
michael@0 | 6907 | support.radioValue = input.value === "t"; |
michael@0 | 6908 | })(); |
michael@0 | 6909 | |
michael@0 | 6910 | |
michael@0 | 6911 | var nodeHook, boolHook, |
michael@0 | 6912 | attrHandle = jQuery.expr.attrHandle; |
michael@0 | 6913 | |
michael@0 | 6914 | jQuery.fn.extend({ |
michael@0 | 6915 | attr: function( name, value ) { |
michael@0 | 6916 | return access( this, jQuery.attr, name, value, arguments.length > 1 ); |
michael@0 | 6917 | }, |
michael@0 | 6918 | |
michael@0 | 6919 | removeAttr: function( name ) { |
michael@0 | 6920 | return this.each(function() { |
michael@0 | 6921 | jQuery.removeAttr( this, name ); |
michael@0 | 6922 | }); |
michael@0 | 6923 | } |
michael@0 | 6924 | }); |
michael@0 | 6925 | |
michael@0 | 6926 | jQuery.extend({ |
michael@0 | 6927 | attr: function( elem, name, value ) { |
michael@0 | 6928 | var hooks, ret, |
michael@0 | 6929 | nType = elem.nodeType; |
michael@0 | 6930 | |
michael@0 | 6931 | // don't get/set attributes on text, comment and attribute nodes |
michael@0 | 6932 | if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { |
michael@0 | 6933 | return; |
michael@0 | 6934 | } |
michael@0 | 6935 | |
michael@0 | 6936 | // Fallback to prop when attributes are not supported |
michael@0 | 6937 | if ( typeof elem.getAttribute === strundefined ) { |
michael@0 | 6938 | return jQuery.prop( elem, name, value ); |
michael@0 | 6939 | } |
michael@0 | 6940 | |
michael@0 | 6941 | // All attributes are lowercase |
michael@0 | 6942 | // Grab necessary hook if one is defined |
michael@0 | 6943 | if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { |
michael@0 | 6944 | name = name.toLowerCase(); |
michael@0 | 6945 | hooks = jQuery.attrHooks[ name ] || |
michael@0 | 6946 | ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); |
michael@0 | 6947 | } |
michael@0 | 6948 | |
michael@0 | 6949 | if ( value !== undefined ) { |
michael@0 | 6950 | |
michael@0 | 6951 | if ( value === null ) { |
michael@0 | 6952 | jQuery.removeAttr( elem, name ); |
michael@0 | 6953 | |
michael@0 | 6954 | } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { |
michael@0 | 6955 | return ret; |
michael@0 | 6956 | |
michael@0 | 6957 | } else { |
michael@0 | 6958 | elem.setAttribute( name, value + "" ); |
michael@0 | 6959 | return value; |
michael@0 | 6960 | } |
michael@0 | 6961 | |
michael@0 | 6962 | } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { |
michael@0 | 6963 | return ret; |
michael@0 | 6964 | |
michael@0 | 6965 | } else { |
michael@0 | 6966 | ret = jQuery.find.attr( elem, name ); |
michael@0 | 6967 | |
michael@0 | 6968 | // Non-existent attributes return null, we normalize to undefined |
michael@0 | 6969 | return ret == null ? |
michael@0 | 6970 | undefined : |
michael@0 | 6971 | ret; |
michael@0 | 6972 | } |
michael@0 | 6973 | }, |
michael@0 | 6974 | |
michael@0 | 6975 | removeAttr: function( elem, value ) { |
michael@0 | 6976 | var name, propName, |
michael@0 | 6977 | i = 0, |
michael@0 | 6978 | attrNames = value && value.match( rnotwhite ); |
michael@0 | 6979 | |
michael@0 | 6980 | if ( attrNames && elem.nodeType === 1 ) { |
michael@0 | 6981 | while ( (name = attrNames[i++]) ) { |
michael@0 | 6982 | propName = jQuery.propFix[ name ] || name; |
michael@0 | 6983 | |
michael@0 | 6984 | // Boolean attributes get special treatment (#10870) |
michael@0 | 6985 | if ( jQuery.expr.match.bool.test( name ) ) { |
michael@0 | 6986 | // Set corresponding property to false |
michael@0 | 6987 | elem[ propName ] = false; |
michael@0 | 6988 | } |
michael@0 | 6989 | |
michael@0 | 6990 | elem.removeAttribute( name ); |
michael@0 | 6991 | } |
michael@0 | 6992 | } |
michael@0 | 6993 | }, |
michael@0 | 6994 | |
michael@0 | 6995 | attrHooks: { |
michael@0 | 6996 | type: { |
michael@0 | 6997 | set: function( elem, value ) { |
michael@0 | 6998 | if ( !support.radioValue && value === "radio" && |
michael@0 | 6999 | jQuery.nodeName( elem, "input" ) ) { |
michael@0 | 7000 | // Setting the type on a radio button after the value resets the value in IE6-9 |
michael@0 | 7001 | // Reset value to default in case type is set after value during creation |
michael@0 | 7002 | var val = elem.value; |
michael@0 | 7003 | elem.setAttribute( "type", value ); |
michael@0 | 7004 | if ( val ) { |
michael@0 | 7005 | elem.value = val; |
michael@0 | 7006 | } |
michael@0 | 7007 | return value; |
michael@0 | 7008 | } |
michael@0 | 7009 | } |
michael@0 | 7010 | } |
michael@0 | 7011 | } |
michael@0 | 7012 | }); |
michael@0 | 7013 | |
michael@0 | 7014 | // Hooks for boolean attributes |
michael@0 | 7015 | boolHook = { |
michael@0 | 7016 | set: function( elem, value, name ) { |
michael@0 | 7017 | if ( value === false ) { |
michael@0 | 7018 | // Remove boolean attributes when set to false |
michael@0 | 7019 | jQuery.removeAttr( elem, name ); |
michael@0 | 7020 | } else { |
michael@0 | 7021 | elem.setAttribute( name, name ); |
michael@0 | 7022 | } |
michael@0 | 7023 | return name; |
michael@0 | 7024 | } |
michael@0 | 7025 | }; |
michael@0 | 7026 | jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { |
michael@0 | 7027 | var getter = attrHandle[ name ] || jQuery.find.attr; |
michael@0 | 7028 | |
michael@0 | 7029 | attrHandle[ name ] = function( elem, name, isXML ) { |
michael@0 | 7030 | var ret, handle; |
michael@0 | 7031 | if ( !isXML ) { |
michael@0 | 7032 | // Avoid an infinite loop by temporarily removing this function from the getter |
michael@0 | 7033 | handle = attrHandle[ name ]; |
michael@0 | 7034 | attrHandle[ name ] = ret; |
michael@0 | 7035 | ret = getter( elem, name, isXML ) != null ? |
michael@0 | 7036 | name.toLowerCase() : |
michael@0 | 7037 | null; |
michael@0 | 7038 | attrHandle[ name ] = handle; |
michael@0 | 7039 | } |
michael@0 | 7040 | return ret; |
michael@0 | 7041 | }; |
michael@0 | 7042 | }); |
michael@0 | 7043 | |
michael@0 | 7044 | |
michael@0 | 7045 | |
michael@0 | 7046 | |
michael@0 | 7047 | var rfocusable = /^(?:input|select|textarea|button)$/i; |
michael@0 | 7048 | |
michael@0 | 7049 | jQuery.fn.extend({ |
michael@0 | 7050 | prop: function( name, value ) { |
michael@0 | 7051 | return access( this, jQuery.prop, name, value, arguments.length > 1 ); |
michael@0 | 7052 | }, |
michael@0 | 7053 | |
michael@0 | 7054 | removeProp: function( name ) { |
michael@0 | 7055 | return this.each(function() { |
michael@0 | 7056 | delete this[ jQuery.propFix[ name ] || name ]; |
michael@0 | 7057 | }); |
michael@0 | 7058 | } |
michael@0 | 7059 | }); |
michael@0 | 7060 | |
michael@0 | 7061 | jQuery.extend({ |
michael@0 | 7062 | propFix: { |
michael@0 | 7063 | "for": "htmlFor", |
michael@0 | 7064 | "class": "className" |
michael@0 | 7065 | }, |
michael@0 | 7066 | |
michael@0 | 7067 | prop: function( elem, name, value ) { |
michael@0 | 7068 | var ret, hooks, notxml, |
michael@0 | 7069 | nType = elem.nodeType; |
michael@0 | 7070 | |
michael@0 | 7071 | // don't get/set properties on text, comment and attribute nodes |
michael@0 | 7072 | if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { |
michael@0 | 7073 | return; |
michael@0 | 7074 | } |
michael@0 | 7075 | |
michael@0 | 7076 | notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); |
michael@0 | 7077 | |
michael@0 | 7078 | if ( notxml ) { |
michael@0 | 7079 | // Fix name and attach hooks |
michael@0 | 7080 | name = jQuery.propFix[ name ] || name; |
michael@0 | 7081 | hooks = jQuery.propHooks[ name ]; |
michael@0 | 7082 | } |
michael@0 | 7083 | |
michael@0 | 7084 | if ( value !== undefined ) { |
michael@0 | 7085 | return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? |
michael@0 | 7086 | ret : |
michael@0 | 7087 | ( elem[ name ] = value ); |
michael@0 | 7088 | |
michael@0 | 7089 | } else { |
michael@0 | 7090 | return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? |
michael@0 | 7091 | ret : |
michael@0 | 7092 | elem[ name ]; |
michael@0 | 7093 | } |
michael@0 | 7094 | }, |
michael@0 | 7095 | |
michael@0 | 7096 | propHooks: { |
michael@0 | 7097 | tabIndex: { |
michael@0 | 7098 | get: function( elem ) { |
michael@0 | 7099 | return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ? |
michael@0 | 7100 | elem.tabIndex : |
michael@0 | 7101 | -1; |
michael@0 | 7102 | } |
michael@0 | 7103 | } |
michael@0 | 7104 | } |
michael@0 | 7105 | }); |
michael@0 | 7106 | |
michael@0 | 7107 | // Support: IE9+ |
michael@0 | 7108 | // Selectedness for an option in an optgroup can be inaccurate |
michael@0 | 7109 | if ( !support.optSelected ) { |
michael@0 | 7110 | jQuery.propHooks.selected = { |
michael@0 | 7111 | get: function( elem ) { |
michael@0 | 7112 | var parent = elem.parentNode; |
michael@0 | 7113 | if ( parent && parent.parentNode ) { |
michael@0 | 7114 | parent.parentNode.selectedIndex; |
michael@0 | 7115 | } |
michael@0 | 7116 | return null; |
michael@0 | 7117 | } |
michael@0 | 7118 | }; |
michael@0 | 7119 | } |
michael@0 | 7120 | |
michael@0 | 7121 | jQuery.each([ |
michael@0 | 7122 | "tabIndex", |
michael@0 | 7123 | "readOnly", |
michael@0 | 7124 | "maxLength", |
michael@0 | 7125 | "cellSpacing", |
michael@0 | 7126 | "cellPadding", |
michael@0 | 7127 | "rowSpan", |
michael@0 | 7128 | "colSpan", |
michael@0 | 7129 | "useMap", |
michael@0 | 7130 | "frameBorder", |
michael@0 | 7131 | "contentEditable" |
michael@0 | 7132 | ], function() { |
michael@0 | 7133 | jQuery.propFix[ this.toLowerCase() ] = this; |
michael@0 | 7134 | }); |
michael@0 | 7135 | |
michael@0 | 7136 | |
michael@0 | 7137 | |
michael@0 | 7138 | |
michael@0 | 7139 | var rclass = /[\t\r\n\f]/g; |
michael@0 | 7140 | |
michael@0 | 7141 | jQuery.fn.extend({ |
michael@0 | 7142 | addClass: function( value ) { |
michael@0 | 7143 | var classes, elem, cur, clazz, j, finalValue, |
michael@0 | 7144 | proceed = typeof value === "string" && value, |
michael@0 | 7145 | i = 0, |
michael@0 | 7146 | len = this.length; |
michael@0 | 7147 | |
michael@0 | 7148 | if ( jQuery.isFunction( value ) ) { |
michael@0 | 7149 | return this.each(function( j ) { |
michael@0 | 7150 | jQuery( this ).addClass( value.call( this, j, this.className ) ); |
michael@0 | 7151 | }); |
michael@0 | 7152 | } |
michael@0 | 7153 | |
michael@0 | 7154 | if ( proceed ) { |
michael@0 | 7155 | // The disjunction here is for better compressibility (see removeClass) |
michael@0 | 7156 | classes = ( value || "" ).match( rnotwhite ) || []; |
michael@0 | 7157 | |
michael@0 | 7158 | for ( ; i < len; i++ ) { |
michael@0 | 7159 | elem = this[ i ]; |
michael@0 | 7160 | cur = elem.nodeType === 1 && ( elem.className ? |
michael@0 | 7161 | ( " " + elem.className + " " ).replace( rclass, " " ) : |
michael@0 | 7162 | " " |
michael@0 | 7163 | ); |
michael@0 | 7164 | |
michael@0 | 7165 | if ( cur ) { |
michael@0 | 7166 | j = 0; |
michael@0 | 7167 | while ( (clazz = classes[j++]) ) { |
michael@0 | 7168 | if ( cur.indexOf( " " + clazz + " " ) < 0 ) { |
michael@0 | 7169 | cur += clazz + " "; |
michael@0 | 7170 | } |
michael@0 | 7171 | } |
michael@0 | 7172 | |
michael@0 | 7173 | // only assign if different to avoid unneeded rendering. |
michael@0 | 7174 | finalValue = jQuery.trim( cur ); |
michael@0 | 7175 | if ( elem.className !== finalValue ) { |
michael@0 | 7176 | elem.className = finalValue; |
michael@0 | 7177 | } |
michael@0 | 7178 | } |
michael@0 | 7179 | } |
michael@0 | 7180 | } |
michael@0 | 7181 | |
michael@0 | 7182 | return this; |
michael@0 | 7183 | }, |
michael@0 | 7184 | |
michael@0 | 7185 | removeClass: function( value ) { |
michael@0 | 7186 | var classes, elem, cur, clazz, j, finalValue, |
michael@0 | 7187 | proceed = arguments.length === 0 || typeof value === "string" && value, |
michael@0 | 7188 | i = 0, |
michael@0 | 7189 | len = this.length; |
michael@0 | 7190 | |
michael@0 | 7191 | if ( jQuery.isFunction( value ) ) { |
michael@0 | 7192 | return this.each(function( j ) { |
michael@0 | 7193 | jQuery( this ).removeClass( value.call( this, j, this.className ) ); |
michael@0 | 7194 | }); |
michael@0 | 7195 | } |
michael@0 | 7196 | if ( proceed ) { |
michael@0 | 7197 | classes = ( value || "" ).match( rnotwhite ) || []; |
michael@0 | 7198 | |
michael@0 | 7199 | for ( ; i < len; i++ ) { |
michael@0 | 7200 | elem = this[ i ]; |
michael@0 | 7201 | // This expression is here for better compressibility (see addClass) |
michael@0 | 7202 | cur = elem.nodeType === 1 && ( elem.className ? |
michael@0 | 7203 | ( " " + elem.className + " " ).replace( rclass, " " ) : |
michael@0 | 7204 | "" |
michael@0 | 7205 | ); |
michael@0 | 7206 | |
michael@0 | 7207 | if ( cur ) { |
michael@0 | 7208 | j = 0; |
michael@0 | 7209 | while ( (clazz = classes[j++]) ) { |
michael@0 | 7210 | // Remove *all* instances |
michael@0 | 7211 | while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { |
michael@0 | 7212 | cur = cur.replace( " " + clazz + " ", " " ); |
michael@0 | 7213 | } |
michael@0 | 7214 | } |
michael@0 | 7215 | |
michael@0 | 7216 | // only assign if different to avoid unneeded rendering. |
michael@0 | 7217 | finalValue = value ? jQuery.trim( cur ) : ""; |
michael@0 | 7218 | if ( elem.className !== finalValue ) { |
michael@0 | 7219 | elem.className = finalValue; |
michael@0 | 7220 | } |
michael@0 | 7221 | } |
michael@0 | 7222 | } |
michael@0 | 7223 | } |
michael@0 | 7224 | |
michael@0 | 7225 | return this; |
michael@0 | 7226 | }, |
michael@0 | 7227 | |
michael@0 | 7228 | toggleClass: function( value, stateVal ) { |
michael@0 | 7229 | var type = typeof value; |
michael@0 | 7230 | |
michael@0 | 7231 | if ( typeof stateVal === "boolean" && type === "string" ) { |
michael@0 | 7232 | return stateVal ? this.addClass( value ) : this.removeClass( value ); |
michael@0 | 7233 | } |
michael@0 | 7234 | |
michael@0 | 7235 | if ( jQuery.isFunction( value ) ) { |
michael@0 | 7236 | return this.each(function( i ) { |
michael@0 | 7237 | jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); |
michael@0 | 7238 | }); |
michael@0 | 7239 | } |
michael@0 | 7240 | |
michael@0 | 7241 | return this.each(function() { |
michael@0 | 7242 | if ( type === "string" ) { |
michael@0 | 7243 | // toggle individual class names |
michael@0 | 7244 | var className, |
michael@0 | 7245 | i = 0, |
michael@0 | 7246 | self = jQuery( this ), |
michael@0 | 7247 | classNames = value.match( rnotwhite ) || []; |
michael@0 | 7248 | |
michael@0 | 7249 | while ( (className = classNames[ i++ ]) ) { |
michael@0 | 7250 | // check each className given, space separated list |
michael@0 | 7251 | if ( self.hasClass( className ) ) { |
michael@0 | 7252 | self.removeClass( className ); |
michael@0 | 7253 | } else { |
michael@0 | 7254 | self.addClass( className ); |
michael@0 | 7255 | } |
michael@0 | 7256 | } |
michael@0 | 7257 | |
michael@0 | 7258 | // Toggle whole class name |
michael@0 | 7259 | } else if ( type === strundefined || type === "boolean" ) { |
michael@0 | 7260 | if ( this.className ) { |
michael@0 | 7261 | // store className if set |
michael@0 | 7262 | data_priv.set( this, "__className__", this.className ); |
michael@0 | 7263 | } |
michael@0 | 7264 | |
michael@0 | 7265 | // If the element has a class name or if we're passed "false", |
michael@0 | 7266 | // then remove the whole classname (if there was one, the above saved it). |
michael@0 | 7267 | // Otherwise bring back whatever was previously saved (if anything), |
michael@0 | 7268 | // falling back to the empty string if nothing was stored. |
michael@0 | 7269 | this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || ""; |
michael@0 | 7270 | } |
michael@0 | 7271 | }); |
michael@0 | 7272 | }, |
michael@0 | 7273 | |
michael@0 | 7274 | hasClass: function( selector ) { |
michael@0 | 7275 | var className = " " + selector + " ", |
michael@0 | 7276 | i = 0, |
michael@0 | 7277 | l = this.length; |
michael@0 | 7278 | for ( ; i < l; i++ ) { |
michael@0 | 7279 | if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { |
michael@0 | 7280 | return true; |
michael@0 | 7281 | } |
michael@0 | 7282 | } |
michael@0 | 7283 | |
michael@0 | 7284 | return false; |
michael@0 | 7285 | } |
michael@0 | 7286 | }); |
michael@0 | 7287 | |
michael@0 | 7288 | |
michael@0 | 7289 | |
michael@0 | 7290 | |
michael@0 | 7291 | var rreturn = /\r/g; |
michael@0 | 7292 | |
michael@0 | 7293 | jQuery.fn.extend({ |
michael@0 | 7294 | val: function( value ) { |
michael@0 | 7295 | var hooks, ret, isFunction, |
michael@0 | 7296 | elem = this[0]; |
michael@0 | 7297 | |
michael@0 | 7298 | if ( !arguments.length ) { |
michael@0 | 7299 | if ( elem ) { |
michael@0 | 7300 | hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; |
michael@0 | 7301 | |
michael@0 | 7302 | if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { |
michael@0 | 7303 | return ret; |
michael@0 | 7304 | } |
michael@0 | 7305 | |
michael@0 | 7306 | ret = elem.value; |
michael@0 | 7307 | |
michael@0 | 7308 | return typeof ret === "string" ? |
michael@0 | 7309 | // handle most common string cases |
michael@0 | 7310 | ret.replace(rreturn, "") : |
michael@0 | 7311 | // handle cases where value is null/undef or number |
michael@0 | 7312 | ret == null ? "" : ret; |
michael@0 | 7313 | } |
michael@0 | 7314 | |
michael@0 | 7315 | return; |
michael@0 | 7316 | } |
michael@0 | 7317 | |
michael@0 | 7318 | isFunction = jQuery.isFunction( value ); |
michael@0 | 7319 | |
michael@0 | 7320 | return this.each(function( i ) { |
michael@0 | 7321 | var val; |
michael@0 | 7322 | |
michael@0 | 7323 | if ( this.nodeType !== 1 ) { |
michael@0 | 7324 | return; |
michael@0 | 7325 | } |
michael@0 | 7326 | |
michael@0 | 7327 | if ( isFunction ) { |
michael@0 | 7328 | val = value.call( this, i, jQuery( this ).val() ); |
michael@0 | 7329 | } else { |
michael@0 | 7330 | val = value; |
michael@0 | 7331 | } |
michael@0 | 7332 | |
michael@0 | 7333 | // Treat null/undefined as ""; convert numbers to string |
michael@0 | 7334 | if ( val == null ) { |
michael@0 | 7335 | val = ""; |
michael@0 | 7336 | |
michael@0 | 7337 | } else if ( typeof val === "number" ) { |
michael@0 | 7338 | val += ""; |
michael@0 | 7339 | |
michael@0 | 7340 | } else if ( jQuery.isArray( val ) ) { |
michael@0 | 7341 | val = jQuery.map( val, function( value ) { |
michael@0 | 7342 | return value == null ? "" : value + ""; |
michael@0 | 7343 | }); |
michael@0 | 7344 | } |
michael@0 | 7345 | |
michael@0 | 7346 | hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; |
michael@0 | 7347 | |
michael@0 | 7348 | // If set returns undefined, fall back to normal setting |
michael@0 | 7349 | if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { |
michael@0 | 7350 | this.value = val; |
michael@0 | 7351 | } |
michael@0 | 7352 | }); |
michael@0 | 7353 | } |
michael@0 | 7354 | }); |
michael@0 | 7355 | |
michael@0 | 7356 | jQuery.extend({ |
michael@0 | 7357 | valHooks: { |
michael@0 | 7358 | option: { |
michael@0 | 7359 | get: function( elem ) { |
michael@0 | 7360 | var val = jQuery.find.attr( elem, "value" ); |
michael@0 | 7361 | return val != null ? |
michael@0 | 7362 | val : |
michael@0 | 7363 | // Support: IE10-11+ |
michael@0 | 7364 | // option.text throws exceptions (#14686, #14858) |
michael@0 | 7365 | jQuery.trim( jQuery.text( elem ) ); |
michael@0 | 7366 | } |
michael@0 | 7367 | }, |
michael@0 | 7368 | select: { |
michael@0 | 7369 | get: function( elem ) { |
michael@0 | 7370 | var value, option, |
michael@0 | 7371 | options = elem.options, |
michael@0 | 7372 | index = elem.selectedIndex, |
michael@0 | 7373 | one = elem.type === "select-one" || index < 0, |
michael@0 | 7374 | values = one ? null : [], |
michael@0 | 7375 | max = one ? index + 1 : options.length, |
michael@0 | 7376 | i = index < 0 ? |
michael@0 | 7377 | max : |
michael@0 | 7378 | one ? index : 0; |
michael@0 | 7379 | |
michael@0 | 7380 | // Loop through all the selected options |
michael@0 | 7381 | for ( ; i < max; i++ ) { |
michael@0 | 7382 | option = options[ i ]; |
michael@0 | 7383 | |
michael@0 | 7384 | // IE6-9 doesn't update selected after form reset (#2551) |
michael@0 | 7385 | if ( ( option.selected || i === index ) && |
michael@0 | 7386 | // Don't return options that are disabled or in a disabled optgroup |
michael@0 | 7387 | ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) && |
michael@0 | 7388 | ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { |
michael@0 | 7389 | |
michael@0 | 7390 | // Get the specific value for the option |
michael@0 | 7391 | value = jQuery( option ).val(); |
michael@0 | 7392 | |
michael@0 | 7393 | // We don't need an array for one selects |
michael@0 | 7394 | if ( one ) { |
michael@0 | 7395 | return value; |
michael@0 | 7396 | } |
michael@0 | 7397 | |
michael@0 | 7398 | // Multi-Selects return an array |
michael@0 | 7399 | values.push( value ); |
michael@0 | 7400 | } |
michael@0 | 7401 | } |
michael@0 | 7402 | |
michael@0 | 7403 | return values; |
michael@0 | 7404 | }, |
michael@0 | 7405 | |
michael@0 | 7406 | set: function( elem, value ) { |
michael@0 | 7407 | var optionSet, option, |
michael@0 | 7408 | options = elem.options, |
michael@0 | 7409 | values = jQuery.makeArray( value ), |
michael@0 | 7410 | i = options.length; |
michael@0 | 7411 | |
michael@0 | 7412 | while ( i-- ) { |
michael@0 | 7413 | option = options[ i ]; |
michael@0 | 7414 | if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) { |
michael@0 | 7415 | optionSet = true; |
michael@0 | 7416 | } |
michael@0 | 7417 | } |
michael@0 | 7418 | |
michael@0 | 7419 | // force browsers to behave consistently when non-matching value is set |
michael@0 | 7420 | if ( !optionSet ) { |
michael@0 | 7421 | elem.selectedIndex = -1; |
michael@0 | 7422 | } |
michael@0 | 7423 | return values; |
michael@0 | 7424 | } |
michael@0 | 7425 | } |
michael@0 | 7426 | } |
michael@0 | 7427 | }); |
michael@0 | 7428 | |
michael@0 | 7429 | // Radios and checkboxes getter/setter |
michael@0 | 7430 | jQuery.each([ "radio", "checkbox" ], function() { |
michael@0 | 7431 | jQuery.valHooks[ this ] = { |
michael@0 | 7432 | set: function( elem, value ) { |
michael@0 | 7433 | if ( jQuery.isArray( value ) ) { |
michael@0 | 7434 | return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); |
michael@0 | 7435 | } |
michael@0 | 7436 | } |
michael@0 | 7437 | }; |
michael@0 | 7438 | if ( !support.checkOn ) { |
michael@0 | 7439 | jQuery.valHooks[ this ].get = function( elem ) { |
michael@0 | 7440 | // Support: Webkit |
michael@0 | 7441 | // "" is returned instead of "on" if a value isn't specified |
michael@0 | 7442 | return elem.getAttribute("value") === null ? "on" : elem.value; |
michael@0 | 7443 | }; |
michael@0 | 7444 | } |
michael@0 | 7445 | }); |
michael@0 | 7446 | |
michael@0 | 7447 | |
michael@0 | 7448 | |
michael@0 | 7449 | |
michael@0 | 7450 | // Return jQuery for attributes-only inclusion |
michael@0 | 7451 | |
michael@0 | 7452 | |
michael@0 | 7453 | jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + |
michael@0 | 7454 | "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + |
michael@0 | 7455 | "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { |
michael@0 | 7456 | |
michael@0 | 7457 | // Handle event binding |
michael@0 | 7458 | jQuery.fn[ name ] = function( data, fn ) { |
michael@0 | 7459 | return arguments.length > 0 ? |
michael@0 | 7460 | this.on( name, null, data, fn ) : |
michael@0 | 7461 | this.trigger( name ); |
michael@0 | 7462 | }; |
michael@0 | 7463 | }); |
michael@0 | 7464 | |
michael@0 | 7465 | jQuery.fn.extend({ |
michael@0 | 7466 | hover: function( fnOver, fnOut ) { |
michael@0 | 7467 | return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); |
michael@0 | 7468 | }, |
michael@0 | 7469 | |
michael@0 | 7470 | bind: function( types, data, fn ) { |
michael@0 | 7471 | return this.on( types, null, data, fn ); |
michael@0 | 7472 | }, |
michael@0 | 7473 | unbind: function( types, fn ) { |
michael@0 | 7474 | return this.off( types, null, fn ); |
michael@0 | 7475 | }, |
michael@0 | 7476 | |
michael@0 | 7477 | delegate: function( selector, types, data, fn ) { |
michael@0 | 7478 | return this.on( types, selector, data, fn ); |
michael@0 | 7479 | }, |
michael@0 | 7480 | undelegate: function( selector, types, fn ) { |
michael@0 | 7481 | // ( namespace ) or ( selector, types [, fn] ) |
michael@0 | 7482 | return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); |
michael@0 | 7483 | } |
michael@0 | 7484 | }); |
michael@0 | 7485 | |
michael@0 | 7486 | |
michael@0 | 7487 | var nonce = jQuery.now(); |
michael@0 | 7488 | |
michael@0 | 7489 | var rquery = (/\?/); |
michael@0 | 7490 | |
michael@0 | 7491 | |
michael@0 | 7492 | |
michael@0 | 7493 | // Support: Android 2.3 |
michael@0 | 7494 | // Workaround failure to string-cast null input |
michael@0 | 7495 | jQuery.parseJSON = function( data ) { |
michael@0 | 7496 | return JSON.parse( data + "" ); |
michael@0 | 7497 | }; |
michael@0 | 7498 | |
michael@0 | 7499 | |
michael@0 | 7500 | // Cross-browser xml parsing |
michael@0 | 7501 | jQuery.parseXML = function( data ) { |
michael@0 | 7502 | var xml, tmp; |
michael@0 | 7503 | if ( !data || typeof data !== "string" ) { |
michael@0 | 7504 | return null; |
michael@0 | 7505 | } |
michael@0 | 7506 | |
michael@0 | 7507 | // Support: IE9 |
michael@0 | 7508 | try { |
michael@0 | 7509 | tmp = new DOMParser(); |
michael@0 | 7510 | xml = tmp.parseFromString( data, "text/xml" ); |
michael@0 | 7511 | } catch ( e ) { |
michael@0 | 7512 | xml = undefined; |
michael@0 | 7513 | } |
michael@0 | 7514 | |
michael@0 | 7515 | if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { |
michael@0 | 7516 | jQuery.error( "Invalid XML: " + data ); |
michael@0 | 7517 | } |
michael@0 | 7518 | return xml; |
michael@0 | 7519 | }; |
michael@0 | 7520 | |
michael@0 | 7521 | |
michael@0 | 7522 | var |
michael@0 | 7523 | // Document location |
michael@0 | 7524 | ajaxLocParts, |
michael@0 | 7525 | ajaxLocation, |
michael@0 | 7526 | |
michael@0 | 7527 | rhash = /#.*$/, |
michael@0 | 7528 | rts = /([?&])_=[^&]*/, |
michael@0 | 7529 | rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, |
michael@0 | 7530 | // #7653, #8125, #8152: local protocol detection |
michael@0 | 7531 | rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, |
michael@0 | 7532 | rnoContent = /^(?:GET|HEAD)$/, |
michael@0 | 7533 | rprotocol = /^\/\//, |
michael@0 | 7534 | rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, |
michael@0 | 7535 | |
michael@0 | 7536 | /* Prefilters |
michael@0 | 7537 | * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) |
michael@0 | 7538 | * 2) These are called: |
michael@0 | 7539 | * - BEFORE asking for a transport |
michael@0 | 7540 | * - AFTER param serialization (s.data is a string if s.processData is true) |
michael@0 | 7541 | * 3) key is the dataType |
michael@0 | 7542 | * 4) the catchall symbol "*" can be used |
michael@0 | 7543 | * 5) execution will start with transport dataType and THEN continue down to "*" if needed |
michael@0 | 7544 | */ |
michael@0 | 7545 | prefilters = {}, |
michael@0 | 7546 | |
michael@0 | 7547 | /* Transports bindings |
michael@0 | 7548 | * 1) key is the dataType |
michael@0 | 7549 | * 2) the catchall symbol "*" can be used |
michael@0 | 7550 | * 3) selection will start with transport dataType and THEN go to "*" if needed |
michael@0 | 7551 | */ |
michael@0 | 7552 | transports = {}, |
michael@0 | 7553 | |
michael@0 | 7554 | // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression |
michael@0 | 7555 | allTypes = "*/".concat("*"); |
michael@0 | 7556 | |
michael@0 | 7557 | // #8138, IE may throw an exception when accessing |
michael@0 | 7558 | // a field from window.location if document.domain has been set |
michael@0 | 7559 | try { |
michael@0 | 7560 | ajaxLocation = location.href; |
michael@0 | 7561 | } catch( e ) { |
michael@0 | 7562 | // Use the href attribute of an A element |
michael@0 | 7563 | // since IE will modify it given document.location |
michael@0 | 7564 | ajaxLocation = document.createElement( "a" ); |
michael@0 | 7565 | ajaxLocation.href = ""; |
michael@0 | 7566 | ajaxLocation = ajaxLocation.href; |
michael@0 | 7567 | } |
michael@0 | 7568 | |
michael@0 | 7569 | // Segment location into parts |
michael@0 | 7570 | ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; |
michael@0 | 7571 | |
michael@0 | 7572 | // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport |
michael@0 | 7573 | function addToPrefiltersOrTransports( structure ) { |
michael@0 | 7574 | |
michael@0 | 7575 | // dataTypeExpression is optional and defaults to "*" |
michael@0 | 7576 | return function( dataTypeExpression, func ) { |
michael@0 | 7577 | |
michael@0 | 7578 | if ( typeof dataTypeExpression !== "string" ) { |
michael@0 | 7579 | func = dataTypeExpression; |
michael@0 | 7580 | dataTypeExpression = "*"; |
michael@0 | 7581 | } |
michael@0 | 7582 | |
michael@0 | 7583 | var dataType, |
michael@0 | 7584 | i = 0, |
michael@0 | 7585 | dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; |
michael@0 | 7586 | |
michael@0 | 7587 | if ( jQuery.isFunction( func ) ) { |
michael@0 | 7588 | // For each dataType in the dataTypeExpression |
michael@0 | 7589 | while ( (dataType = dataTypes[i++]) ) { |
michael@0 | 7590 | // Prepend if requested |
michael@0 | 7591 | if ( dataType[0] === "+" ) { |
michael@0 | 7592 | dataType = dataType.slice( 1 ) || "*"; |
michael@0 | 7593 | (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); |
michael@0 | 7594 | |
michael@0 | 7595 | // Otherwise append |
michael@0 | 7596 | } else { |
michael@0 | 7597 | (structure[ dataType ] = structure[ dataType ] || []).push( func ); |
michael@0 | 7598 | } |
michael@0 | 7599 | } |
michael@0 | 7600 | } |
michael@0 | 7601 | }; |
michael@0 | 7602 | } |
michael@0 | 7603 | |
michael@0 | 7604 | // Base inspection function for prefilters and transports |
michael@0 | 7605 | function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { |
michael@0 | 7606 | |
michael@0 | 7607 | var inspected = {}, |
michael@0 | 7608 | seekingTransport = ( structure === transports ); |
michael@0 | 7609 | |
michael@0 | 7610 | function inspect( dataType ) { |
michael@0 | 7611 | var selected; |
michael@0 | 7612 | inspected[ dataType ] = true; |
michael@0 | 7613 | jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { |
michael@0 | 7614 | var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); |
michael@0 | 7615 | if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { |
michael@0 | 7616 | options.dataTypes.unshift( dataTypeOrTransport ); |
michael@0 | 7617 | inspect( dataTypeOrTransport ); |
michael@0 | 7618 | return false; |
michael@0 | 7619 | } else if ( seekingTransport ) { |
michael@0 | 7620 | return !( selected = dataTypeOrTransport ); |
michael@0 | 7621 | } |
michael@0 | 7622 | }); |
michael@0 | 7623 | return selected; |
michael@0 | 7624 | } |
michael@0 | 7625 | |
michael@0 | 7626 | return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); |
michael@0 | 7627 | } |
michael@0 | 7628 | |
michael@0 | 7629 | // A special extend for ajax options |
michael@0 | 7630 | // that takes "flat" options (not to be deep extended) |
michael@0 | 7631 | // Fixes #9887 |
michael@0 | 7632 | function ajaxExtend( target, src ) { |
michael@0 | 7633 | var key, deep, |
michael@0 | 7634 | flatOptions = jQuery.ajaxSettings.flatOptions || {}; |
michael@0 | 7635 | |
michael@0 | 7636 | for ( key in src ) { |
michael@0 | 7637 | if ( src[ key ] !== undefined ) { |
michael@0 | 7638 | ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; |
michael@0 | 7639 | } |
michael@0 | 7640 | } |
michael@0 | 7641 | if ( deep ) { |
michael@0 | 7642 | jQuery.extend( true, target, deep ); |
michael@0 | 7643 | } |
michael@0 | 7644 | |
michael@0 | 7645 | return target; |
michael@0 | 7646 | } |
michael@0 | 7647 | |
michael@0 | 7648 | /* Handles responses to an ajax request: |
michael@0 | 7649 | * - finds the right dataType (mediates between content-type and expected dataType) |
michael@0 | 7650 | * - returns the corresponding response |
michael@0 | 7651 | */ |
michael@0 | 7652 | function ajaxHandleResponses( s, jqXHR, responses ) { |
michael@0 | 7653 | |
michael@0 | 7654 | var ct, type, finalDataType, firstDataType, |
michael@0 | 7655 | contents = s.contents, |
michael@0 | 7656 | dataTypes = s.dataTypes; |
michael@0 | 7657 | |
michael@0 | 7658 | // Remove auto dataType and get content-type in the process |
michael@0 | 7659 | while ( dataTypes[ 0 ] === "*" ) { |
michael@0 | 7660 | dataTypes.shift(); |
michael@0 | 7661 | if ( ct === undefined ) { |
michael@0 | 7662 | ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); |
michael@0 | 7663 | } |
michael@0 | 7664 | } |
michael@0 | 7665 | |
michael@0 | 7666 | // Check if we're dealing with a known content-type |
michael@0 | 7667 | if ( ct ) { |
michael@0 | 7668 | for ( type in contents ) { |
michael@0 | 7669 | if ( contents[ type ] && contents[ type ].test( ct ) ) { |
michael@0 | 7670 | dataTypes.unshift( type ); |
michael@0 | 7671 | break; |
michael@0 | 7672 | } |
michael@0 | 7673 | } |
michael@0 | 7674 | } |
michael@0 | 7675 | |
michael@0 | 7676 | // Check to see if we have a response for the expected dataType |
michael@0 | 7677 | if ( dataTypes[ 0 ] in responses ) { |
michael@0 | 7678 | finalDataType = dataTypes[ 0 ]; |
michael@0 | 7679 | } else { |
michael@0 | 7680 | // Try convertible dataTypes |
michael@0 | 7681 | for ( type in responses ) { |
michael@0 | 7682 | if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { |
michael@0 | 7683 | finalDataType = type; |
michael@0 | 7684 | break; |
michael@0 | 7685 | } |
michael@0 | 7686 | if ( !firstDataType ) { |
michael@0 | 7687 | firstDataType = type; |
michael@0 | 7688 | } |
michael@0 | 7689 | } |
michael@0 | 7690 | // Or just use first one |
michael@0 | 7691 | finalDataType = finalDataType || firstDataType; |
michael@0 | 7692 | } |
michael@0 | 7693 | |
michael@0 | 7694 | // If we found a dataType |
michael@0 | 7695 | // We add the dataType to the list if needed |
michael@0 | 7696 | // and return the corresponding response |
michael@0 | 7697 | if ( finalDataType ) { |
michael@0 | 7698 | if ( finalDataType !== dataTypes[ 0 ] ) { |
michael@0 | 7699 | dataTypes.unshift( finalDataType ); |
michael@0 | 7700 | } |
michael@0 | 7701 | return responses[ finalDataType ]; |
michael@0 | 7702 | } |
michael@0 | 7703 | } |
michael@0 | 7704 | |
michael@0 | 7705 | /* Chain conversions given the request and the original response |
michael@0 | 7706 | * Also sets the responseXXX fields on the jqXHR instance |
michael@0 | 7707 | */ |
michael@0 | 7708 | function ajaxConvert( s, response, jqXHR, isSuccess ) { |
michael@0 | 7709 | var conv2, current, conv, tmp, prev, |
michael@0 | 7710 | converters = {}, |
michael@0 | 7711 | // Work with a copy of dataTypes in case we need to modify it for conversion |
michael@0 | 7712 | dataTypes = s.dataTypes.slice(); |
michael@0 | 7713 | |
michael@0 | 7714 | // Create converters map with lowercased keys |
michael@0 | 7715 | if ( dataTypes[ 1 ] ) { |
michael@0 | 7716 | for ( conv in s.converters ) { |
michael@0 | 7717 | converters[ conv.toLowerCase() ] = s.converters[ conv ]; |
michael@0 | 7718 | } |
michael@0 | 7719 | } |
michael@0 | 7720 | |
michael@0 | 7721 | current = dataTypes.shift(); |
michael@0 | 7722 | |
michael@0 | 7723 | // Convert to each sequential dataType |
michael@0 | 7724 | while ( current ) { |
michael@0 | 7725 | |
michael@0 | 7726 | if ( s.responseFields[ current ] ) { |
michael@0 | 7727 | jqXHR[ s.responseFields[ current ] ] = response; |
michael@0 | 7728 | } |
michael@0 | 7729 | |
michael@0 | 7730 | // Apply the dataFilter if provided |
michael@0 | 7731 | if ( !prev && isSuccess && s.dataFilter ) { |
michael@0 | 7732 | response = s.dataFilter( response, s.dataType ); |
michael@0 | 7733 | } |
michael@0 | 7734 | |
michael@0 | 7735 | prev = current; |
michael@0 | 7736 | current = dataTypes.shift(); |
michael@0 | 7737 | |
michael@0 | 7738 | if ( current ) { |
michael@0 | 7739 | |
michael@0 | 7740 | // There's only work to do if current dataType is non-auto |
michael@0 | 7741 | if ( current === "*" ) { |
michael@0 | 7742 | |
michael@0 | 7743 | current = prev; |
michael@0 | 7744 | |
michael@0 | 7745 | // Convert response if prev dataType is non-auto and differs from current |
michael@0 | 7746 | } else if ( prev !== "*" && prev !== current ) { |
michael@0 | 7747 | |
michael@0 | 7748 | // Seek a direct converter |
michael@0 | 7749 | conv = converters[ prev + " " + current ] || converters[ "* " + current ]; |
michael@0 | 7750 | |
michael@0 | 7751 | // If none found, seek a pair |
michael@0 | 7752 | if ( !conv ) { |
michael@0 | 7753 | for ( conv2 in converters ) { |
michael@0 | 7754 | |
michael@0 | 7755 | // If conv2 outputs current |
michael@0 | 7756 | tmp = conv2.split( " " ); |
michael@0 | 7757 | if ( tmp[ 1 ] === current ) { |
michael@0 | 7758 | |
michael@0 | 7759 | // If prev can be converted to accepted input |
michael@0 | 7760 | conv = converters[ prev + " " + tmp[ 0 ] ] || |
michael@0 | 7761 | converters[ "* " + tmp[ 0 ] ]; |
michael@0 | 7762 | if ( conv ) { |
michael@0 | 7763 | // Condense equivalence converters |
michael@0 | 7764 | if ( conv === true ) { |
michael@0 | 7765 | conv = converters[ conv2 ]; |
michael@0 | 7766 | |
michael@0 | 7767 | // Otherwise, insert the intermediate dataType |
michael@0 | 7768 | } else if ( converters[ conv2 ] !== true ) { |
michael@0 | 7769 | current = tmp[ 0 ]; |
michael@0 | 7770 | dataTypes.unshift( tmp[ 1 ] ); |
michael@0 | 7771 | } |
michael@0 | 7772 | break; |
michael@0 | 7773 | } |
michael@0 | 7774 | } |
michael@0 | 7775 | } |
michael@0 | 7776 | } |
michael@0 | 7777 | |
michael@0 | 7778 | // Apply converter (if not an equivalence) |
michael@0 | 7779 | if ( conv !== true ) { |
michael@0 | 7780 | |
michael@0 | 7781 | // Unless errors are allowed to bubble, catch and return them |
michael@0 | 7782 | if ( conv && s[ "throws" ] ) { |
michael@0 | 7783 | response = conv( response ); |
michael@0 | 7784 | } else { |
michael@0 | 7785 | try { |
michael@0 | 7786 | response = conv( response ); |
michael@0 | 7787 | } catch ( e ) { |
michael@0 | 7788 | return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; |
michael@0 | 7789 | } |
michael@0 | 7790 | } |
michael@0 | 7791 | } |
michael@0 | 7792 | } |
michael@0 | 7793 | } |
michael@0 | 7794 | } |
michael@0 | 7795 | |
michael@0 | 7796 | return { state: "success", data: response }; |
michael@0 | 7797 | } |
michael@0 | 7798 | |
michael@0 | 7799 | jQuery.extend({ |
michael@0 | 7800 | |
michael@0 | 7801 | // Counter for holding the number of active queries |
michael@0 | 7802 | active: 0, |
michael@0 | 7803 | |
michael@0 | 7804 | // Last-Modified header cache for next request |
michael@0 | 7805 | lastModified: {}, |
michael@0 | 7806 | etag: {}, |
michael@0 | 7807 | |
michael@0 | 7808 | ajaxSettings: { |
michael@0 | 7809 | url: ajaxLocation, |
michael@0 | 7810 | type: "GET", |
michael@0 | 7811 | isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), |
michael@0 | 7812 | global: true, |
michael@0 | 7813 | processData: true, |
michael@0 | 7814 | async: true, |
michael@0 | 7815 | contentType: "application/x-www-form-urlencoded; charset=UTF-8", |
michael@0 | 7816 | /* |
michael@0 | 7817 | timeout: 0, |
michael@0 | 7818 | data: null, |
michael@0 | 7819 | dataType: null, |
michael@0 | 7820 | username: null, |
michael@0 | 7821 | password: null, |
michael@0 | 7822 | cache: null, |
michael@0 | 7823 | throws: false, |
michael@0 | 7824 | traditional: false, |
michael@0 | 7825 | headers: {}, |
michael@0 | 7826 | */ |
michael@0 | 7827 | |
michael@0 | 7828 | accepts: { |
michael@0 | 7829 | "*": allTypes, |
michael@0 | 7830 | text: "text/plain", |
michael@0 | 7831 | html: "text/html", |
michael@0 | 7832 | xml: "application/xml, text/xml", |
michael@0 | 7833 | json: "application/json, text/javascript" |
michael@0 | 7834 | }, |
michael@0 | 7835 | |
michael@0 | 7836 | contents: { |
michael@0 | 7837 | xml: /xml/, |
michael@0 | 7838 | html: /html/, |
michael@0 | 7839 | json: /json/ |
michael@0 | 7840 | }, |
michael@0 | 7841 | |
michael@0 | 7842 | responseFields: { |
michael@0 | 7843 | xml: "responseXML", |
michael@0 | 7844 | text: "responseText", |
michael@0 | 7845 | json: "responseJSON" |
michael@0 | 7846 | }, |
michael@0 | 7847 | |
michael@0 | 7848 | // Data converters |
michael@0 | 7849 | // Keys separate source (or catchall "*") and destination types with a single space |
michael@0 | 7850 | converters: { |
michael@0 | 7851 | |
michael@0 | 7852 | // Convert anything to text |
michael@0 | 7853 | "* text": String, |
michael@0 | 7854 | |
michael@0 | 7855 | // Text to html (true = no transformation) |
michael@0 | 7856 | "text html": true, |
michael@0 | 7857 | |
michael@0 | 7858 | // Evaluate text as a json expression |
michael@0 | 7859 | "text json": jQuery.parseJSON, |
michael@0 | 7860 | |
michael@0 | 7861 | // Parse text as xml |
michael@0 | 7862 | "text xml": jQuery.parseXML |
michael@0 | 7863 | }, |
michael@0 | 7864 | |
michael@0 | 7865 | // For options that shouldn't be deep extended: |
michael@0 | 7866 | // you can add your own custom options here if |
michael@0 | 7867 | // and when you create one that shouldn't be |
michael@0 | 7868 | // deep extended (see ajaxExtend) |
michael@0 | 7869 | flatOptions: { |
michael@0 | 7870 | url: true, |
michael@0 | 7871 | context: true |
michael@0 | 7872 | } |
michael@0 | 7873 | }, |
michael@0 | 7874 | |
michael@0 | 7875 | // Creates a full fledged settings object into target |
michael@0 | 7876 | // with both ajaxSettings and settings fields. |
michael@0 | 7877 | // If target is omitted, writes into ajaxSettings. |
michael@0 | 7878 | ajaxSetup: function( target, settings ) { |
michael@0 | 7879 | return settings ? |
michael@0 | 7880 | |
michael@0 | 7881 | // Building a settings object |
michael@0 | 7882 | ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : |
michael@0 | 7883 | |
michael@0 | 7884 | // Extending ajaxSettings |
michael@0 | 7885 | ajaxExtend( jQuery.ajaxSettings, target ); |
michael@0 | 7886 | }, |
michael@0 | 7887 | |
michael@0 | 7888 | ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), |
michael@0 | 7889 | ajaxTransport: addToPrefiltersOrTransports( transports ), |
michael@0 | 7890 | |
michael@0 | 7891 | // Main method |
michael@0 | 7892 | ajax: function( url, options ) { |
michael@0 | 7893 | |
michael@0 | 7894 | // If url is an object, simulate pre-1.5 signature |
michael@0 | 7895 | if ( typeof url === "object" ) { |
michael@0 | 7896 | options = url; |
michael@0 | 7897 | url = undefined; |
michael@0 | 7898 | } |
michael@0 | 7899 | |
michael@0 | 7900 | // Force options to be an object |
michael@0 | 7901 | options = options || {}; |
michael@0 | 7902 | |
michael@0 | 7903 | var transport, |
michael@0 | 7904 | // URL without anti-cache param |
michael@0 | 7905 | cacheURL, |
michael@0 | 7906 | // Response headers |
michael@0 | 7907 | responseHeadersString, |
michael@0 | 7908 | responseHeaders, |
michael@0 | 7909 | // timeout handle |
michael@0 | 7910 | timeoutTimer, |
michael@0 | 7911 | // Cross-domain detection vars |
michael@0 | 7912 | parts, |
michael@0 | 7913 | // To know if global events are to be dispatched |
michael@0 | 7914 | fireGlobals, |
michael@0 | 7915 | // Loop variable |
michael@0 | 7916 | i, |
michael@0 | 7917 | // Create the final options object |
michael@0 | 7918 | s = jQuery.ajaxSetup( {}, options ), |
michael@0 | 7919 | // Callbacks context |
michael@0 | 7920 | callbackContext = s.context || s, |
michael@0 | 7921 | // Context for global events is callbackContext if it is a DOM node or jQuery collection |
michael@0 | 7922 | globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? |
michael@0 | 7923 | jQuery( callbackContext ) : |
michael@0 | 7924 | jQuery.event, |
michael@0 | 7925 | // Deferreds |
michael@0 | 7926 | deferred = jQuery.Deferred(), |
michael@0 | 7927 | completeDeferred = jQuery.Callbacks("once memory"), |
michael@0 | 7928 | // Status-dependent callbacks |
michael@0 | 7929 | statusCode = s.statusCode || {}, |
michael@0 | 7930 | // Headers (they are sent all at once) |
michael@0 | 7931 | requestHeaders = {}, |
michael@0 | 7932 | requestHeadersNames = {}, |
michael@0 | 7933 | // The jqXHR state |
michael@0 | 7934 | state = 0, |
michael@0 | 7935 | // Default abort message |
michael@0 | 7936 | strAbort = "canceled", |
michael@0 | 7937 | // Fake xhr |
michael@0 | 7938 | jqXHR = { |
michael@0 | 7939 | readyState: 0, |
michael@0 | 7940 | |
michael@0 | 7941 | // Builds headers hashtable if needed |
michael@0 | 7942 | getResponseHeader: function( key ) { |
michael@0 | 7943 | var match; |
michael@0 | 7944 | if ( state === 2 ) { |
michael@0 | 7945 | if ( !responseHeaders ) { |
michael@0 | 7946 | responseHeaders = {}; |
michael@0 | 7947 | while ( (match = rheaders.exec( responseHeadersString )) ) { |
michael@0 | 7948 | responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; |
michael@0 | 7949 | } |
michael@0 | 7950 | } |
michael@0 | 7951 | match = responseHeaders[ key.toLowerCase() ]; |
michael@0 | 7952 | } |
michael@0 | 7953 | return match == null ? null : match; |
michael@0 | 7954 | }, |
michael@0 | 7955 | |
michael@0 | 7956 | // Raw string |
michael@0 | 7957 | getAllResponseHeaders: function() { |
michael@0 | 7958 | return state === 2 ? responseHeadersString : null; |
michael@0 | 7959 | }, |
michael@0 | 7960 | |
michael@0 | 7961 | // Caches the header |
michael@0 | 7962 | setRequestHeader: function( name, value ) { |
michael@0 | 7963 | var lname = name.toLowerCase(); |
michael@0 | 7964 | if ( !state ) { |
michael@0 | 7965 | name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; |
michael@0 | 7966 | requestHeaders[ name ] = value; |
michael@0 | 7967 | } |
michael@0 | 7968 | return this; |
michael@0 | 7969 | }, |
michael@0 | 7970 | |
michael@0 | 7971 | // Overrides response content-type header |
michael@0 | 7972 | overrideMimeType: function( type ) { |
michael@0 | 7973 | if ( !state ) { |
michael@0 | 7974 | s.mimeType = type; |
michael@0 | 7975 | } |
michael@0 | 7976 | return this; |
michael@0 | 7977 | }, |
michael@0 | 7978 | |
michael@0 | 7979 | // Status-dependent callbacks |
michael@0 | 7980 | statusCode: function( map ) { |
michael@0 | 7981 | var code; |
michael@0 | 7982 | if ( map ) { |
michael@0 | 7983 | if ( state < 2 ) { |
michael@0 | 7984 | for ( code in map ) { |
michael@0 | 7985 | // Lazy-add the new callback in a way that preserves old ones |
michael@0 | 7986 | statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; |
michael@0 | 7987 | } |
michael@0 | 7988 | } else { |
michael@0 | 7989 | // Execute the appropriate callbacks |
michael@0 | 7990 | jqXHR.always( map[ jqXHR.status ] ); |
michael@0 | 7991 | } |
michael@0 | 7992 | } |
michael@0 | 7993 | return this; |
michael@0 | 7994 | }, |
michael@0 | 7995 | |
michael@0 | 7996 | // Cancel the request |
michael@0 | 7997 | abort: function( statusText ) { |
michael@0 | 7998 | var finalText = statusText || strAbort; |
michael@0 | 7999 | if ( transport ) { |
michael@0 | 8000 | transport.abort( finalText ); |
michael@0 | 8001 | } |
michael@0 | 8002 | done( 0, finalText ); |
michael@0 | 8003 | return this; |
michael@0 | 8004 | } |
michael@0 | 8005 | }; |
michael@0 | 8006 | |
michael@0 | 8007 | // Attach deferreds |
michael@0 | 8008 | deferred.promise( jqXHR ).complete = completeDeferred.add; |
michael@0 | 8009 | jqXHR.success = jqXHR.done; |
michael@0 | 8010 | jqXHR.error = jqXHR.fail; |
michael@0 | 8011 | |
michael@0 | 8012 | // Remove hash character (#7531: and string promotion) |
michael@0 | 8013 | // Add protocol if not provided (prefilters might expect it) |
michael@0 | 8014 | // Handle falsy url in the settings object (#10093: consistency with old signature) |
michael@0 | 8015 | // We also use the url parameter if available |
michael@0 | 8016 | s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) |
michael@0 | 8017 | .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); |
michael@0 | 8018 | |
michael@0 | 8019 | // Alias method option to type as per ticket #12004 |
michael@0 | 8020 | s.type = options.method || options.type || s.method || s.type; |
michael@0 | 8021 | |
michael@0 | 8022 | // Extract dataTypes list |
michael@0 | 8023 | s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; |
michael@0 | 8024 | |
michael@0 | 8025 | // A cross-domain request is in order when we have a protocol:host:port mismatch |
michael@0 | 8026 | if ( s.crossDomain == null ) { |
michael@0 | 8027 | parts = rurl.exec( s.url.toLowerCase() ); |
michael@0 | 8028 | s.crossDomain = !!( parts && |
michael@0 | 8029 | ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || |
michael@0 | 8030 | ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== |
michael@0 | 8031 | ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) |
michael@0 | 8032 | ); |
michael@0 | 8033 | } |
michael@0 | 8034 | |
michael@0 | 8035 | // Convert data if not already a string |
michael@0 | 8036 | if ( s.data && s.processData && typeof s.data !== "string" ) { |
michael@0 | 8037 | s.data = jQuery.param( s.data, s.traditional ); |
michael@0 | 8038 | } |
michael@0 | 8039 | |
michael@0 | 8040 | // Apply prefilters |
michael@0 | 8041 | inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
michael@0 | 8042 | |
michael@0 | 8043 | // If request was aborted inside a prefilter, stop there |
michael@0 | 8044 | if ( state === 2 ) { |
michael@0 | 8045 | return jqXHR; |
michael@0 | 8046 | } |
michael@0 | 8047 | |
michael@0 | 8048 | // We can fire global events as of now if asked to |
michael@0 | 8049 | fireGlobals = s.global; |
michael@0 | 8050 | |
michael@0 | 8051 | // Watch for a new set of requests |
michael@0 | 8052 | if ( fireGlobals && jQuery.active++ === 0 ) { |
michael@0 | 8053 | jQuery.event.trigger("ajaxStart"); |
michael@0 | 8054 | } |
michael@0 | 8055 | |
michael@0 | 8056 | // Uppercase the type |
michael@0 | 8057 | s.type = s.type.toUpperCase(); |
michael@0 | 8058 | |
michael@0 | 8059 | // Determine if request has content |
michael@0 | 8060 | s.hasContent = !rnoContent.test( s.type ); |
michael@0 | 8061 | |
michael@0 | 8062 | // Save the URL in case we're toying with the If-Modified-Since |
michael@0 | 8063 | // and/or If-None-Match header later on |
michael@0 | 8064 | cacheURL = s.url; |
michael@0 | 8065 | |
michael@0 | 8066 | // More options handling for requests with no content |
michael@0 | 8067 | if ( !s.hasContent ) { |
michael@0 | 8068 | |
michael@0 | 8069 | // If data is available, append data to url |
michael@0 | 8070 | if ( s.data ) { |
michael@0 | 8071 | cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); |
michael@0 | 8072 | // #9682: remove data so that it's not used in an eventual retry |
michael@0 | 8073 | delete s.data; |
michael@0 | 8074 | } |
michael@0 | 8075 | |
michael@0 | 8076 | // Add anti-cache in url if needed |
michael@0 | 8077 | if ( s.cache === false ) { |
michael@0 | 8078 | s.url = rts.test( cacheURL ) ? |
michael@0 | 8079 | |
michael@0 | 8080 | // If there is already a '_' parameter, set its value |
michael@0 | 8081 | cacheURL.replace( rts, "$1_=" + nonce++ ) : |
michael@0 | 8082 | |
michael@0 | 8083 | // Otherwise add one to the end |
michael@0 | 8084 | cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; |
michael@0 | 8085 | } |
michael@0 | 8086 | } |
michael@0 | 8087 | |
michael@0 | 8088 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
michael@0 | 8089 | if ( s.ifModified ) { |
michael@0 | 8090 | if ( jQuery.lastModified[ cacheURL ] ) { |
michael@0 | 8091 | jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); |
michael@0 | 8092 | } |
michael@0 | 8093 | if ( jQuery.etag[ cacheURL ] ) { |
michael@0 | 8094 | jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); |
michael@0 | 8095 | } |
michael@0 | 8096 | } |
michael@0 | 8097 | |
michael@0 | 8098 | // Set the correct header, if data is being sent |
michael@0 | 8099 | if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { |
michael@0 | 8100 | jqXHR.setRequestHeader( "Content-Type", s.contentType ); |
michael@0 | 8101 | } |
michael@0 | 8102 | |
michael@0 | 8103 | // Set the Accepts header for the server, depending on the dataType |
michael@0 | 8104 | jqXHR.setRequestHeader( |
michael@0 | 8105 | "Accept", |
michael@0 | 8106 | s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? |
michael@0 | 8107 | s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : |
michael@0 | 8108 | s.accepts[ "*" ] |
michael@0 | 8109 | ); |
michael@0 | 8110 | |
michael@0 | 8111 | // Check for headers option |
michael@0 | 8112 | for ( i in s.headers ) { |
michael@0 | 8113 | jqXHR.setRequestHeader( i, s.headers[ i ] ); |
michael@0 | 8114 | } |
michael@0 | 8115 | |
michael@0 | 8116 | // Allow custom headers/mimetypes and early abort |
michael@0 | 8117 | if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { |
michael@0 | 8118 | // Abort if not done already and return |
michael@0 | 8119 | return jqXHR.abort(); |
michael@0 | 8120 | } |
michael@0 | 8121 | |
michael@0 | 8122 | // aborting is no longer a cancellation |
michael@0 | 8123 | strAbort = "abort"; |
michael@0 | 8124 | |
michael@0 | 8125 | // Install callbacks on deferreds |
michael@0 | 8126 | for ( i in { success: 1, error: 1, complete: 1 } ) { |
michael@0 | 8127 | jqXHR[ i ]( s[ i ] ); |
michael@0 | 8128 | } |
michael@0 | 8129 | |
michael@0 | 8130 | // Get transport |
michael@0 | 8131 | transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
michael@0 | 8132 | |
michael@0 | 8133 | // If no transport, we auto-abort |
michael@0 | 8134 | if ( !transport ) { |
michael@0 | 8135 | done( -1, "No Transport" ); |
michael@0 | 8136 | } else { |
michael@0 | 8137 | jqXHR.readyState = 1; |
michael@0 | 8138 | |
michael@0 | 8139 | // Send global event |
michael@0 | 8140 | if ( fireGlobals ) { |
michael@0 | 8141 | globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
michael@0 | 8142 | } |
michael@0 | 8143 | // Timeout |
michael@0 | 8144 | if ( s.async && s.timeout > 0 ) { |
michael@0 | 8145 | timeoutTimer = setTimeout(function() { |
michael@0 | 8146 | jqXHR.abort("timeout"); |
michael@0 | 8147 | }, s.timeout ); |
michael@0 | 8148 | } |
michael@0 | 8149 | |
michael@0 | 8150 | try { |
michael@0 | 8151 | state = 1; |
michael@0 | 8152 | transport.send( requestHeaders, done ); |
michael@0 | 8153 | } catch ( e ) { |
michael@0 | 8154 | // Propagate exception as error if not done |
michael@0 | 8155 | if ( state < 2 ) { |
michael@0 | 8156 | done( -1, e ); |
michael@0 | 8157 | // Simply rethrow otherwise |
michael@0 | 8158 | } else { |
michael@0 | 8159 | throw e; |
michael@0 | 8160 | } |
michael@0 | 8161 | } |
michael@0 | 8162 | } |
michael@0 | 8163 | |
michael@0 | 8164 | // Callback for when everything is done |
michael@0 | 8165 | function done( status, nativeStatusText, responses, headers ) { |
michael@0 | 8166 | var isSuccess, success, error, response, modified, |
michael@0 | 8167 | statusText = nativeStatusText; |
michael@0 | 8168 | |
michael@0 | 8169 | // Called once |
michael@0 | 8170 | if ( state === 2 ) { |
michael@0 | 8171 | return; |
michael@0 | 8172 | } |
michael@0 | 8173 | |
michael@0 | 8174 | // State is "done" now |
michael@0 | 8175 | state = 2; |
michael@0 | 8176 | |
michael@0 | 8177 | // Clear timeout if it exists |
michael@0 | 8178 | if ( timeoutTimer ) { |
michael@0 | 8179 | clearTimeout( timeoutTimer ); |
michael@0 | 8180 | } |
michael@0 | 8181 | |
michael@0 | 8182 | // Dereference transport for early garbage collection |
michael@0 | 8183 | // (no matter how long the jqXHR object will be used) |
michael@0 | 8184 | transport = undefined; |
michael@0 | 8185 | |
michael@0 | 8186 | // Cache response headers |
michael@0 | 8187 | responseHeadersString = headers || ""; |
michael@0 | 8188 | |
michael@0 | 8189 | // Set readyState |
michael@0 | 8190 | jqXHR.readyState = status > 0 ? 4 : 0; |
michael@0 | 8191 | |
michael@0 | 8192 | // Determine if successful |
michael@0 | 8193 | isSuccess = status >= 200 && status < 300 || status === 304; |
michael@0 | 8194 | |
michael@0 | 8195 | // Get response data |
michael@0 | 8196 | if ( responses ) { |
michael@0 | 8197 | response = ajaxHandleResponses( s, jqXHR, responses ); |
michael@0 | 8198 | } |
michael@0 | 8199 | |
michael@0 | 8200 | // Convert no matter what (that way responseXXX fields are always set) |
michael@0 | 8201 | response = ajaxConvert( s, response, jqXHR, isSuccess ); |
michael@0 | 8202 | |
michael@0 | 8203 | // If successful, handle type chaining |
michael@0 | 8204 | if ( isSuccess ) { |
michael@0 | 8205 | |
michael@0 | 8206 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
michael@0 | 8207 | if ( s.ifModified ) { |
michael@0 | 8208 | modified = jqXHR.getResponseHeader("Last-Modified"); |
michael@0 | 8209 | if ( modified ) { |
michael@0 | 8210 | jQuery.lastModified[ cacheURL ] = modified; |
michael@0 | 8211 | } |
michael@0 | 8212 | modified = jqXHR.getResponseHeader("etag"); |
michael@0 | 8213 | if ( modified ) { |
michael@0 | 8214 | jQuery.etag[ cacheURL ] = modified; |
michael@0 | 8215 | } |
michael@0 | 8216 | } |
michael@0 | 8217 | |
michael@0 | 8218 | // if no content |
michael@0 | 8219 | if ( status === 204 || s.type === "HEAD" ) { |
michael@0 | 8220 | statusText = "nocontent"; |
michael@0 | 8221 | |
michael@0 | 8222 | // if not modified |
michael@0 | 8223 | } else if ( status === 304 ) { |
michael@0 | 8224 | statusText = "notmodified"; |
michael@0 | 8225 | |
michael@0 | 8226 | // If we have data, let's convert it |
michael@0 | 8227 | } else { |
michael@0 | 8228 | statusText = response.state; |
michael@0 | 8229 | success = response.data; |
michael@0 | 8230 | error = response.error; |
michael@0 | 8231 | isSuccess = !error; |
michael@0 | 8232 | } |
michael@0 | 8233 | } else { |
michael@0 | 8234 | // We extract error from statusText |
michael@0 | 8235 | // then normalize statusText and status for non-aborts |
michael@0 | 8236 | error = statusText; |
michael@0 | 8237 | if ( status || !statusText ) { |
michael@0 | 8238 | statusText = "error"; |
michael@0 | 8239 | if ( status < 0 ) { |
michael@0 | 8240 | status = 0; |
michael@0 | 8241 | } |
michael@0 | 8242 | } |
michael@0 | 8243 | } |
michael@0 | 8244 | |
michael@0 | 8245 | // Set data for the fake xhr object |
michael@0 | 8246 | jqXHR.status = status; |
michael@0 | 8247 | jqXHR.statusText = ( nativeStatusText || statusText ) + ""; |
michael@0 | 8248 | |
michael@0 | 8249 | // Success/Error |
michael@0 | 8250 | if ( isSuccess ) { |
michael@0 | 8251 | deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
michael@0 | 8252 | } else { |
michael@0 | 8253 | deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
michael@0 | 8254 | } |
michael@0 | 8255 | |
michael@0 | 8256 | // Status-dependent callbacks |
michael@0 | 8257 | jqXHR.statusCode( statusCode ); |
michael@0 | 8258 | statusCode = undefined; |
michael@0 | 8259 | |
michael@0 | 8260 | if ( fireGlobals ) { |
michael@0 | 8261 | globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", |
michael@0 | 8262 | [ jqXHR, s, isSuccess ? success : error ] ); |
michael@0 | 8263 | } |
michael@0 | 8264 | |
michael@0 | 8265 | // Complete |
michael@0 | 8266 | completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); |
michael@0 | 8267 | |
michael@0 | 8268 | if ( fireGlobals ) { |
michael@0 | 8269 | globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); |
michael@0 | 8270 | // Handle the global AJAX counter |
michael@0 | 8271 | if ( !( --jQuery.active ) ) { |
michael@0 | 8272 | jQuery.event.trigger("ajaxStop"); |
michael@0 | 8273 | } |
michael@0 | 8274 | } |
michael@0 | 8275 | } |
michael@0 | 8276 | |
michael@0 | 8277 | return jqXHR; |
michael@0 | 8278 | }, |
michael@0 | 8279 | |
michael@0 | 8280 | getJSON: function( url, data, callback ) { |
michael@0 | 8281 | return jQuery.get( url, data, callback, "json" ); |
michael@0 | 8282 | }, |
michael@0 | 8283 | |
michael@0 | 8284 | getScript: function( url, callback ) { |
michael@0 | 8285 | return jQuery.get( url, undefined, callback, "script" ); |
michael@0 | 8286 | } |
michael@0 | 8287 | }); |
michael@0 | 8288 | |
michael@0 | 8289 | jQuery.each( [ "get", "post" ], function( i, method ) { |
michael@0 | 8290 | jQuery[ method ] = function( url, data, callback, type ) { |
michael@0 | 8291 | // shift arguments if data argument was omitted |
michael@0 | 8292 | if ( jQuery.isFunction( data ) ) { |
michael@0 | 8293 | type = type || callback; |
michael@0 | 8294 | callback = data; |
michael@0 | 8295 | data = undefined; |
michael@0 | 8296 | } |
michael@0 | 8297 | |
michael@0 | 8298 | return jQuery.ajax({ |
michael@0 | 8299 | url: url, |
michael@0 | 8300 | type: method, |
michael@0 | 8301 | dataType: type, |
michael@0 | 8302 | data: data, |
michael@0 | 8303 | success: callback |
michael@0 | 8304 | }); |
michael@0 | 8305 | }; |
michael@0 | 8306 | }); |
michael@0 | 8307 | |
michael@0 | 8308 | // Attach a bunch of functions for handling common AJAX events |
michael@0 | 8309 | jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { |
michael@0 | 8310 | jQuery.fn[ type ] = function( fn ) { |
michael@0 | 8311 | return this.on( type, fn ); |
michael@0 | 8312 | }; |
michael@0 | 8313 | }); |
michael@0 | 8314 | |
michael@0 | 8315 | |
michael@0 | 8316 | jQuery._evalUrl = function( url ) { |
michael@0 | 8317 | return jQuery.ajax({ |
michael@0 | 8318 | url: url, |
michael@0 | 8319 | type: "GET", |
michael@0 | 8320 | dataType: "script", |
michael@0 | 8321 | async: false, |
michael@0 | 8322 | global: false, |
michael@0 | 8323 | "throws": true |
michael@0 | 8324 | }); |
michael@0 | 8325 | }; |
michael@0 | 8326 | |
michael@0 | 8327 | |
michael@0 | 8328 | jQuery.fn.extend({ |
michael@0 | 8329 | wrapAll: function( html ) { |
michael@0 | 8330 | var wrap; |
michael@0 | 8331 | |
michael@0 | 8332 | if ( jQuery.isFunction( html ) ) { |
michael@0 | 8333 | return this.each(function( i ) { |
michael@0 | 8334 | jQuery( this ).wrapAll( html.call(this, i) ); |
michael@0 | 8335 | }); |
michael@0 | 8336 | } |
michael@0 | 8337 | |
michael@0 | 8338 | if ( this[ 0 ] ) { |
michael@0 | 8339 | |
michael@0 | 8340 | // The elements to wrap the target around |
michael@0 | 8341 | wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); |
michael@0 | 8342 | |
michael@0 | 8343 | if ( this[ 0 ].parentNode ) { |
michael@0 | 8344 | wrap.insertBefore( this[ 0 ] ); |
michael@0 | 8345 | } |
michael@0 | 8346 | |
michael@0 | 8347 | wrap.map(function() { |
michael@0 | 8348 | var elem = this; |
michael@0 | 8349 | |
michael@0 | 8350 | while ( elem.firstElementChild ) { |
michael@0 | 8351 | elem = elem.firstElementChild; |
michael@0 | 8352 | } |
michael@0 | 8353 | |
michael@0 | 8354 | return elem; |
michael@0 | 8355 | }).append( this ); |
michael@0 | 8356 | } |
michael@0 | 8357 | |
michael@0 | 8358 | return this; |
michael@0 | 8359 | }, |
michael@0 | 8360 | |
michael@0 | 8361 | wrapInner: function( html ) { |
michael@0 | 8362 | if ( jQuery.isFunction( html ) ) { |
michael@0 | 8363 | return this.each(function( i ) { |
michael@0 | 8364 | jQuery( this ).wrapInner( html.call(this, i) ); |
michael@0 | 8365 | }); |
michael@0 | 8366 | } |
michael@0 | 8367 | |
michael@0 | 8368 | return this.each(function() { |
michael@0 | 8369 | var self = jQuery( this ), |
michael@0 | 8370 | contents = self.contents(); |
michael@0 | 8371 | |
michael@0 | 8372 | if ( contents.length ) { |
michael@0 | 8373 | contents.wrapAll( html ); |
michael@0 | 8374 | |
michael@0 | 8375 | } else { |
michael@0 | 8376 | self.append( html ); |
michael@0 | 8377 | } |
michael@0 | 8378 | }); |
michael@0 | 8379 | }, |
michael@0 | 8380 | |
michael@0 | 8381 | wrap: function( html ) { |
michael@0 | 8382 | var isFunction = jQuery.isFunction( html ); |
michael@0 | 8383 | |
michael@0 | 8384 | return this.each(function( i ) { |
michael@0 | 8385 | jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); |
michael@0 | 8386 | }); |
michael@0 | 8387 | }, |
michael@0 | 8388 | |
michael@0 | 8389 | unwrap: function() { |
michael@0 | 8390 | return this.parent().each(function() { |
michael@0 | 8391 | if ( !jQuery.nodeName( this, "body" ) ) { |
michael@0 | 8392 | jQuery( this ).replaceWith( this.childNodes ); |
michael@0 | 8393 | } |
michael@0 | 8394 | }).end(); |
michael@0 | 8395 | } |
michael@0 | 8396 | }); |
michael@0 | 8397 | |
michael@0 | 8398 | |
michael@0 | 8399 | jQuery.expr.filters.hidden = function( elem ) { |
michael@0 | 8400 | // Support: Opera <= 12.12 |
michael@0 | 8401 | // Opera reports offsetWidths and offsetHeights less than zero on some elements |
michael@0 | 8402 | return elem.offsetWidth <= 0 && elem.offsetHeight <= 0; |
michael@0 | 8403 | }; |
michael@0 | 8404 | jQuery.expr.filters.visible = function( elem ) { |
michael@0 | 8405 | return !jQuery.expr.filters.hidden( elem ); |
michael@0 | 8406 | }; |
michael@0 | 8407 | |
michael@0 | 8408 | |
michael@0 | 8409 | |
michael@0 | 8410 | |
michael@0 | 8411 | var r20 = /%20/g, |
michael@0 | 8412 | rbracket = /\[\]$/, |
michael@0 | 8413 | rCRLF = /\r?\n/g, |
michael@0 | 8414 | rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, |
michael@0 | 8415 | rsubmittable = /^(?:input|select|textarea|keygen)/i; |
michael@0 | 8416 | |
michael@0 | 8417 | function buildParams( prefix, obj, traditional, add ) { |
michael@0 | 8418 | var name; |
michael@0 | 8419 | |
michael@0 | 8420 | if ( jQuery.isArray( obj ) ) { |
michael@0 | 8421 | // Serialize array item. |
michael@0 | 8422 | jQuery.each( obj, function( i, v ) { |
michael@0 | 8423 | if ( traditional || rbracket.test( prefix ) ) { |
michael@0 | 8424 | // Treat each array item as a scalar. |
michael@0 | 8425 | add( prefix, v ); |
michael@0 | 8426 | |
michael@0 | 8427 | } else { |
michael@0 | 8428 | // Item is non-scalar (array or object), encode its numeric index. |
michael@0 | 8429 | buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); |
michael@0 | 8430 | } |
michael@0 | 8431 | }); |
michael@0 | 8432 | |
michael@0 | 8433 | } else if ( !traditional && jQuery.type( obj ) === "object" ) { |
michael@0 | 8434 | // Serialize object item. |
michael@0 | 8435 | for ( name in obj ) { |
michael@0 | 8436 | buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); |
michael@0 | 8437 | } |
michael@0 | 8438 | |
michael@0 | 8439 | } else { |
michael@0 | 8440 | // Serialize scalar item. |
michael@0 | 8441 | add( prefix, obj ); |
michael@0 | 8442 | } |
michael@0 | 8443 | } |
michael@0 | 8444 | |
michael@0 | 8445 | // Serialize an array of form elements or a set of |
michael@0 | 8446 | // key/values into a query string |
michael@0 | 8447 | jQuery.param = function( a, traditional ) { |
michael@0 | 8448 | var prefix, |
michael@0 | 8449 | s = [], |
michael@0 | 8450 | add = function( key, value ) { |
michael@0 | 8451 | // If value is a function, invoke it and return its value |
michael@0 | 8452 | value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); |
michael@0 | 8453 | s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); |
michael@0 | 8454 | }; |
michael@0 | 8455 | |
michael@0 | 8456 | // Set traditional to true for jQuery <= 1.3.2 behavior. |
michael@0 | 8457 | if ( traditional === undefined ) { |
michael@0 | 8458 | traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; |
michael@0 | 8459 | } |
michael@0 | 8460 | |
michael@0 | 8461 | // If an array was passed in, assume that it is an array of form elements. |
michael@0 | 8462 | if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { |
michael@0 | 8463 | // Serialize the form elements |
michael@0 | 8464 | jQuery.each( a, function() { |
michael@0 | 8465 | add( this.name, this.value ); |
michael@0 | 8466 | }); |
michael@0 | 8467 | |
michael@0 | 8468 | } else { |
michael@0 | 8469 | // If traditional, encode the "old" way (the way 1.3.2 or older |
michael@0 | 8470 | // did it), otherwise encode params recursively. |
michael@0 | 8471 | for ( prefix in a ) { |
michael@0 | 8472 | buildParams( prefix, a[ prefix ], traditional, add ); |
michael@0 | 8473 | } |
michael@0 | 8474 | } |
michael@0 | 8475 | |
michael@0 | 8476 | // Return the resulting serialization |
michael@0 | 8477 | return s.join( "&" ).replace( r20, "+" ); |
michael@0 | 8478 | }; |
michael@0 | 8479 | |
michael@0 | 8480 | jQuery.fn.extend({ |
michael@0 | 8481 | serialize: function() { |
michael@0 | 8482 | return jQuery.param( this.serializeArray() ); |
michael@0 | 8483 | }, |
michael@0 | 8484 | serializeArray: function() { |
michael@0 | 8485 | return this.map(function() { |
michael@0 | 8486 | // Can add propHook for "elements" to filter or add form elements |
michael@0 | 8487 | var elements = jQuery.prop( this, "elements" ); |
michael@0 | 8488 | return elements ? jQuery.makeArray( elements ) : this; |
michael@0 | 8489 | }) |
michael@0 | 8490 | .filter(function() { |
michael@0 | 8491 | var type = this.type; |
michael@0 | 8492 | |
michael@0 | 8493 | // Use .is( ":disabled" ) so that fieldset[disabled] works |
michael@0 | 8494 | return this.name && !jQuery( this ).is( ":disabled" ) && |
michael@0 | 8495 | rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && |
michael@0 | 8496 | ( this.checked || !rcheckableType.test( type ) ); |
michael@0 | 8497 | }) |
michael@0 | 8498 | .map(function( i, elem ) { |
michael@0 | 8499 | var val = jQuery( this ).val(); |
michael@0 | 8500 | |
michael@0 | 8501 | return val == null ? |
michael@0 | 8502 | null : |
michael@0 | 8503 | jQuery.isArray( val ) ? |
michael@0 | 8504 | jQuery.map( val, function( val ) { |
michael@0 | 8505 | return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
michael@0 | 8506 | }) : |
michael@0 | 8507 | { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
michael@0 | 8508 | }).get(); |
michael@0 | 8509 | } |
michael@0 | 8510 | }); |
michael@0 | 8511 | |
michael@0 | 8512 | |
michael@0 | 8513 | jQuery.ajaxSettings.xhr = function() { |
michael@0 | 8514 | try { |
michael@0 | 8515 | return new XMLHttpRequest(); |
michael@0 | 8516 | } catch( e ) {} |
michael@0 | 8517 | }; |
michael@0 | 8518 | |
michael@0 | 8519 | var xhrId = 0, |
michael@0 | 8520 | xhrCallbacks = {}, |
michael@0 | 8521 | xhrSuccessStatus = { |
michael@0 | 8522 | // file protocol always yields status code 0, assume 200 |
michael@0 | 8523 | 0: 200, |
michael@0 | 8524 | // Support: IE9 |
michael@0 | 8525 | // #1450: sometimes IE returns 1223 when it should be 204 |
michael@0 | 8526 | 1223: 204 |
michael@0 | 8527 | }, |
michael@0 | 8528 | xhrSupported = jQuery.ajaxSettings.xhr(); |
michael@0 | 8529 | |
michael@0 | 8530 | // Support: IE9 |
michael@0 | 8531 | // Open requests must be manually aborted on unload (#5280) |
michael@0 | 8532 | if ( window.ActiveXObject ) { |
michael@0 | 8533 | jQuery( window ).on( "unload", function() { |
michael@0 | 8534 | for ( var key in xhrCallbacks ) { |
michael@0 | 8535 | xhrCallbacks[ key ](); |
michael@0 | 8536 | } |
michael@0 | 8537 | }); |
michael@0 | 8538 | } |
michael@0 | 8539 | |
michael@0 | 8540 | support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); |
michael@0 | 8541 | support.ajax = xhrSupported = !!xhrSupported; |
michael@0 | 8542 | |
michael@0 | 8543 | jQuery.ajaxTransport(function( options ) { |
michael@0 | 8544 | var callback; |
michael@0 | 8545 | |
michael@0 | 8546 | // Cross domain only allowed if supported through XMLHttpRequest |
michael@0 | 8547 | if ( support.cors || xhrSupported && !options.crossDomain ) { |
michael@0 | 8548 | return { |
michael@0 | 8549 | send: function( headers, complete ) { |
michael@0 | 8550 | var i, |
michael@0 | 8551 | xhr = options.xhr(), |
michael@0 | 8552 | id = ++xhrId; |
michael@0 | 8553 | |
michael@0 | 8554 | xhr.open( options.type, options.url, options.async, options.username, options.password ); |
michael@0 | 8555 | |
michael@0 | 8556 | // Apply custom fields if provided |
michael@0 | 8557 | if ( options.xhrFields ) { |
michael@0 | 8558 | for ( i in options.xhrFields ) { |
michael@0 | 8559 | xhr[ i ] = options.xhrFields[ i ]; |
michael@0 | 8560 | } |
michael@0 | 8561 | } |
michael@0 | 8562 | |
michael@0 | 8563 | // Override mime type if needed |
michael@0 | 8564 | if ( options.mimeType && xhr.overrideMimeType ) { |
michael@0 | 8565 | xhr.overrideMimeType( options.mimeType ); |
michael@0 | 8566 | } |
michael@0 | 8567 | |
michael@0 | 8568 | // X-Requested-With header |
michael@0 | 8569 | // For cross-domain requests, seeing as conditions for a preflight are |
michael@0 | 8570 | // akin to a jigsaw puzzle, we simply never set it to be sure. |
michael@0 | 8571 | // (it can always be set on a per-request basis or even using ajaxSetup) |
michael@0 | 8572 | // For same-domain requests, won't change header if already provided. |
michael@0 | 8573 | if ( !options.crossDomain && !headers["X-Requested-With"] ) { |
michael@0 | 8574 | headers["X-Requested-With"] = "XMLHttpRequest"; |
michael@0 | 8575 | } |
michael@0 | 8576 | |
michael@0 | 8577 | // Set headers |
michael@0 | 8578 | for ( i in headers ) { |
michael@0 | 8579 | xhr.setRequestHeader( i, headers[ i ] ); |
michael@0 | 8580 | } |
michael@0 | 8581 | |
michael@0 | 8582 | // Callback |
michael@0 | 8583 | callback = function( type ) { |
michael@0 | 8584 | return function() { |
michael@0 | 8585 | if ( callback ) { |
michael@0 | 8586 | delete xhrCallbacks[ id ]; |
michael@0 | 8587 | callback = xhr.onload = xhr.onerror = null; |
michael@0 | 8588 | |
michael@0 | 8589 | if ( type === "abort" ) { |
michael@0 | 8590 | xhr.abort(); |
michael@0 | 8591 | } else if ( type === "error" ) { |
michael@0 | 8592 | complete( |
michael@0 | 8593 | // file: protocol always yields status 0; see #8605, #14207 |
michael@0 | 8594 | xhr.status, |
michael@0 | 8595 | xhr.statusText |
michael@0 | 8596 | ); |
michael@0 | 8597 | } else { |
michael@0 | 8598 | complete( |
michael@0 | 8599 | xhrSuccessStatus[ xhr.status ] || xhr.status, |
michael@0 | 8600 | xhr.statusText, |
michael@0 | 8601 | // Support: IE9 |
michael@0 | 8602 | // Accessing binary-data responseText throws an exception |
michael@0 | 8603 | // (#11426) |
michael@0 | 8604 | typeof xhr.responseText === "string" ? { |
michael@0 | 8605 | text: xhr.responseText |
michael@0 | 8606 | } : undefined, |
michael@0 | 8607 | xhr.getAllResponseHeaders() |
michael@0 | 8608 | ); |
michael@0 | 8609 | } |
michael@0 | 8610 | } |
michael@0 | 8611 | }; |
michael@0 | 8612 | }; |
michael@0 | 8613 | |
michael@0 | 8614 | // Listen to events |
michael@0 | 8615 | xhr.onload = callback(); |
michael@0 | 8616 | xhr.onerror = callback("error"); |
michael@0 | 8617 | |
michael@0 | 8618 | // Create the abort callback |
michael@0 | 8619 | callback = xhrCallbacks[ id ] = callback("abort"); |
michael@0 | 8620 | |
michael@0 | 8621 | try { |
michael@0 | 8622 | // Do send the request (this may raise an exception) |
michael@0 | 8623 | xhr.send( options.hasContent && options.data || null ); |
michael@0 | 8624 | } catch ( e ) { |
michael@0 | 8625 | // #14683: Only rethrow if this hasn't been notified as an error yet |
michael@0 | 8626 | if ( callback ) { |
michael@0 | 8627 | throw e; |
michael@0 | 8628 | } |
michael@0 | 8629 | } |
michael@0 | 8630 | }, |
michael@0 | 8631 | |
michael@0 | 8632 | abort: function() { |
michael@0 | 8633 | if ( callback ) { |
michael@0 | 8634 | callback(); |
michael@0 | 8635 | } |
michael@0 | 8636 | } |
michael@0 | 8637 | }; |
michael@0 | 8638 | } |
michael@0 | 8639 | }); |
michael@0 | 8640 | |
michael@0 | 8641 | |
michael@0 | 8642 | |
michael@0 | 8643 | |
michael@0 | 8644 | // Install script dataType |
michael@0 | 8645 | jQuery.ajaxSetup({ |
michael@0 | 8646 | accepts: { |
michael@0 | 8647 | script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" |
michael@0 | 8648 | }, |
michael@0 | 8649 | contents: { |
michael@0 | 8650 | script: /(?:java|ecma)script/ |
michael@0 | 8651 | }, |
michael@0 | 8652 | converters: { |
michael@0 | 8653 | "text script": function( text ) { |
michael@0 | 8654 | jQuery.globalEval( text ); |
michael@0 | 8655 | return text; |
michael@0 | 8656 | } |
michael@0 | 8657 | } |
michael@0 | 8658 | }); |
michael@0 | 8659 | |
michael@0 | 8660 | // Handle cache's special case and crossDomain |
michael@0 | 8661 | jQuery.ajaxPrefilter( "script", function( s ) { |
michael@0 | 8662 | if ( s.cache === undefined ) { |
michael@0 | 8663 | s.cache = false; |
michael@0 | 8664 | } |
michael@0 | 8665 | if ( s.crossDomain ) { |
michael@0 | 8666 | s.type = "GET"; |
michael@0 | 8667 | } |
michael@0 | 8668 | }); |
michael@0 | 8669 | |
michael@0 | 8670 | // Bind script tag hack transport |
michael@0 | 8671 | jQuery.ajaxTransport( "script", function( s ) { |
michael@0 | 8672 | // This transport only deals with cross domain requests |
michael@0 | 8673 | if ( s.crossDomain ) { |
michael@0 | 8674 | var script, callback; |
michael@0 | 8675 | return { |
michael@0 | 8676 | send: function( _, complete ) { |
michael@0 | 8677 | script = jQuery("<script>").prop({ |
michael@0 | 8678 | async: true, |
michael@0 | 8679 | charset: s.scriptCharset, |
michael@0 | 8680 | src: s.url |
michael@0 | 8681 | }).on( |
michael@0 | 8682 | "load error", |
michael@0 | 8683 | callback = function( evt ) { |
michael@0 | 8684 | script.remove(); |
michael@0 | 8685 | callback = null; |
michael@0 | 8686 | if ( evt ) { |
michael@0 | 8687 | complete( evt.type === "error" ? 404 : 200, evt.type ); |
michael@0 | 8688 | } |
michael@0 | 8689 | } |
michael@0 | 8690 | ); |
michael@0 | 8691 | document.head.appendChild( script[ 0 ] ); |
michael@0 | 8692 | }, |
michael@0 | 8693 | abort: function() { |
michael@0 | 8694 | if ( callback ) { |
michael@0 | 8695 | callback(); |
michael@0 | 8696 | } |
michael@0 | 8697 | } |
michael@0 | 8698 | }; |
michael@0 | 8699 | } |
michael@0 | 8700 | }); |
michael@0 | 8701 | |
michael@0 | 8702 | |
michael@0 | 8703 | |
michael@0 | 8704 | |
michael@0 | 8705 | var oldCallbacks = [], |
michael@0 | 8706 | rjsonp = /(=)\?(?=&|$)|\?\?/; |
michael@0 | 8707 | |
michael@0 | 8708 | // Default jsonp settings |
michael@0 | 8709 | jQuery.ajaxSetup({ |
michael@0 | 8710 | jsonp: "callback", |
michael@0 | 8711 | jsonpCallback: function() { |
michael@0 | 8712 | var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); |
michael@0 | 8713 | this[ callback ] = true; |
michael@0 | 8714 | return callback; |
michael@0 | 8715 | } |
michael@0 | 8716 | }); |
michael@0 | 8717 | |
michael@0 | 8718 | // Detect, normalize options and install callbacks for jsonp requests |
michael@0 | 8719 | jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { |
michael@0 | 8720 | |
michael@0 | 8721 | var callbackName, overwritten, responseContainer, |
michael@0 | 8722 | jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? |
michael@0 | 8723 | "url" : |
michael@0 | 8724 | typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" |
michael@0 | 8725 | ); |
michael@0 | 8726 | |
michael@0 | 8727 | // Handle iff the expected data type is "jsonp" or we have a parameter to set |
michael@0 | 8728 | if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { |
michael@0 | 8729 | |
michael@0 | 8730 | // Get callback name, remembering preexisting value associated with it |
michael@0 | 8731 | callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? |
michael@0 | 8732 | s.jsonpCallback() : |
michael@0 | 8733 | s.jsonpCallback; |
michael@0 | 8734 | |
michael@0 | 8735 | // Insert callback into url or form data |
michael@0 | 8736 | if ( jsonProp ) { |
michael@0 | 8737 | s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); |
michael@0 | 8738 | } else if ( s.jsonp !== false ) { |
michael@0 | 8739 | s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; |
michael@0 | 8740 | } |
michael@0 | 8741 | |
michael@0 | 8742 | // Use data converter to retrieve json after script execution |
michael@0 | 8743 | s.converters["script json"] = function() { |
michael@0 | 8744 | if ( !responseContainer ) { |
michael@0 | 8745 | jQuery.error( callbackName + " was not called" ); |
michael@0 | 8746 | } |
michael@0 | 8747 | return responseContainer[ 0 ]; |
michael@0 | 8748 | }; |
michael@0 | 8749 | |
michael@0 | 8750 | // force json dataType |
michael@0 | 8751 | s.dataTypes[ 0 ] = "json"; |
michael@0 | 8752 | |
michael@0 | 8753 | // Install callback |
michael@0 | 8754 | overwritten = window[ callbackName ]; |
michael@0 | 8755 | window[ callbackName ] = function() { |
michael@0 | 8756 | responseContainer = arguments; |
michael@0 | 8757 | }; |
michael@0 | 8758 | |
michael@0 | 8759 | // Clean-up function (fires after converters) |
michael@0 | 8760 | jqXHR.always(function() { |
michael@0 | 8761 | // Restore preexisting value |
michael@0 | 8762 | window[ callbackName ] = overwritten; |
michael@0 | 8763 | |
michael@0 | 8764 | // Save back as free |
michael@0 | 8765 | if ( s[ callbackName ] ) { |
michael@0 | 8766 | // make sure that re-using the options doesn't screw things around |
michael@0 | 8767 | s.jsonpCallback = originalSettings.jsonpCallback; |
michael@0 | 8768 | |
michael@0 | 8769 | // save the callback name for future use |
michael@0 | 8770 | oldCallbacks.push( callbackName ); |
michael@0 | 8771 | } |
michael@0 | 8772 | |
michael@0 | 8773 | // Call if it was a function and we have a response |
michael@0 | 8774 | if ( responseContainer && jQuery.isFunction( overwritten ) ) { |
michael@0 | 8775 | overwritten( responseContainer[ 0 ] ); |
michael@0 | 8776 | } |
michael@0 | 8777 | |
michael@0 | 8778 | responseContainer = overwritten = undefined; |
michael@0 | 8779 | }); |
michael@0 | 8780 | |
michael@0 | 8781 | // Delegate to script |
michael@0 | 8782 | return "script"; |
michael@0 | 8783 | } |
michael@0 | 8784 | }); |
michael@0 | 8785 | |
michael@0 | 8786 | |
michael@0 | 8787 | |
michael@0 | 8788 | |
michael@0 | 8789 | // data: string of html |
michael@0 | 8790 | // context (optional): If specified, the fragment will be created in this context, defaults to document |
michael@0 | 8791 | // keepScripts (optional): If true, will include scripts passed in the html string |
michael@0 | 8792 | jQuery.parseHTML = function( data, context, keepScripts ) { |
michael@0 | 8793 | if ( !data || typeof data !== "string" ) { |
michael@0 | 8794 | return null; |
michael@0 | 8795 | } |
michael@0 | 8796 | if ( typeof context === "boolean" ) { |
michael@0 | 8797 | keepScripts = context; |
michael@0 | 8798 | context = false; |
michael@0 | 8799 | } |
michael@0 | 8800 | context = context || document; |
michael@0 | 8801 | |
michael@0 | 8802 | var parsed = rsingleTag.exec( data ), |
michael@0 | 8803 | scripts = !keepScripts && []; |
michael@0 | 8804 | |
michael@0 | 8805 | // Single tag |
michael@0 | 8806 | if ( parsed ) { |
michael@0 | 8807 | return [ context.createElement( parsed[1] ) ]; |
michael@0 | 8808 | } |
michael@0 | 8809 | |
michael@0 | 8810 | parsed = jQuery.buildFragment( [ data ], context, scripts ); |
michael@0 | 8811 | |
michael@0 | 8812 | if ( scripts && scripts.length ) { |
michael@0 | 8813 | jQuery( scripts ).remove(); |
michael@0 | 8814 | } |
michael@0 | 8815 | |
michael@0 | 8816 | return jQuery.merge( [], parsed.childNodes ); |
michael@0 | 8817 | }; |
michael@0 | 8818 | |
michael@0 | 8819 | |
michael@0 | 8820 | // Keep a copy of the old load method |
michael@0 | 8821 | var _load = jQuery.fn.load; |
michael@0 | 8822 | |
michael@0 | 8823 | /** |
michael@0 | 8824 | * Load a url into a page |
michael@0 | 8825 | */ |
michael@0 | 8826 | jQuery.fn.load = function( url, params, callback ) { |
michael@0 | 8827 | if ( typeof url !== "string" && _load ) { |
michael@0 | 8828 | return _load.apply( this, arguments ); |
michael@0 | 8829 | } |
michael@0 | 8830 | |
michael@0 | 8831 | var selector, type, response, |
michael@0 | 8832 | self = this, |
michael@0 | 8833 | off = url.indexOf(" "); |
michael@0 | 8834 | |
michael@0 | 8835 | if ( off >= 0 ) { |
michael@0 | 8836 | selector = jQuery.trim( url.slice( off ) ); |
michael@0 | 8837 | url = url.slice( 0, off ); |
michael@0 | 8838 | } |
michael@0 | 8839 | |
michael@0 | 8840 | // If it's a function |
michael@0 | 8841 | if ( jQuery.isFunction( params ) ) { |
michael@0 | 8842 | |
michael@0 | 8843 | // We assume that it's the callback |
michael@0 | 8844 | callback = params; |
michael@0 | 8845 | params = undefined; |
michael@0 | 8846 | |
michael@0 | 8847 | // Otherwise, build a param string |
michael@0 | 8848 | } else if ( params && typeof params === "object" ) { |
michael@0 | 8849 | type = "POST"; |
michael@0 | 8850 | } |
michael@0 | 8851 | |
michael@0 | 8852 | // If we have elements to modify, make the request |
michael@0 | 8853 | if ( self.length > 0 ) { |
michael@0 | 8854 | jQuery.ajax({ |
michael@0 | 8855 | url: url, |
michael@0 | 8856 | |
michael@0 | 8857 | // if "type" variable is undefined, then "GET" method will be used |
michael@0 | 8858 | type: type, |
michael@0 | 8859 | dataType: "html", |
michael@0 | 8860 | data: params |
michael@0 | 8861 | }).done(function( responseText ) { |
michael@0 | 8862 | |
michael@0 | 8863 | // Save response for use in complete callback |
michael@0 | 8864 | response = arguments; |
michael@0 | 8865 | |
michael@0 | 8866 | self.html( selector ? |
michael@0 | 8867 | |
michael@0 | 8868 | // If a selector was specified, locate the right elements in a dummy div |
michael@0 | 8869 | // Exclude scripts to avoid IE 'Permission Denied' errors |
michael@0 | 8870 | jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : |
michael@0 | 8871 | |
michael@0 | 8872 | // Otherwise use the full result |
michael@0 | 8873 | responseText ); |
michael@0 | 8874 | |
michael@0 | 8875 | }).complete( callback && function( jqXHR, status ) { |
michael@0 | 8876 | self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); |
michael@0 | 8877 | }); |
michael@0 | 8878 | } |
michael@0 | 8879 | |
michael@0 | 8880 | return this; |
michael@0 | 8881 | }; |
michael@0 | 8882 | |
michael@0 | 8883 | |
michael@0 | 8884 | |
michael@0 | 8885 | |
michael@0 | 8886 | jQuery.expr.filters.animated = function( elem ) { |
michael@0 | 8887 | return jQuery.grep(jQuery.timers, function( fn ) { |
michael@0 | 8888 | return elem === fn.elem; |
michael@0 | 8889 | }).length; |
michael@0 | 8890 | }; |
michael@0 | 8891 | |
michael@0 | 8892 | |
michael@0 | 8893 | |
michael@0 | 8894 | |
michael@0 | 8895 | var docElem = window.document.documentElement; |
michael@0 | 8896 | |
michael@0 | 8897 | /** |
michael@0 | 8898 | * Gets a window from an element |
michael@0 | 8899 | */ |
michael@0 | 8900 | function getWindow( elem ) { |
michael@0 | 8901 | return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; |
michael@0 | 8902 | } |
michael@0 | 8903 | |
michael@0 | 8904 | jQuery.offset = { |
michael@0 | 8905 | setOffset: function( elem, options, i ) { |
michael@0 | 8906 | var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, |
michael@0 | 8907 | position = jQuery.css( elem, "position" ), |
michael@0 | 8908 | curElem = jQuery( elem ), |
michael@0 | 8909 | props = {}; |
michael@0 | 8910 | |
michael@0 | 8911 | // Set position first, in-case top/left are set even on static elem |
michael@0 | 8912 | if ( position === "static" ) { |
michael@0 | 8913 | elem.style.position = "relative"; |
michael@0 | 8914 | } |
michael@0 | 8915 | |
michael@0 | 8916 | curOffset = curElem.offset(); |
michael@0 | 8917 | curCSSTop = jQuery.css( elem, "top" ); |
michael@0 | 8918 | curCSSLeft = jQuery.css( elem, "left" ); |
michael@0 | 8919 | calculatePosition = ( position === "absolute" || position === "fixed" ) && |
michael@0 | 8920 | ( curCSSTop + curCSSLeft ).indexOf("auto") > -1; |
michael@0 | 8921 | |
michael@0 | 8922 | // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed |
michael@0 | 8923 | if ( calculatePosition ) { |
michael@0 | 8924 | curPosition = curElem.position(); |
michael@0 | 8925 | curTop = curPosition.top; |
michael@0 | 8926 | curLeft = curPosition.left; |
michael@0 | 8927 | |
michael@0 | 8928 | } else { |
michael@0 | 8929 | curTop = parseFloat( curCSSTop ) || 0; |
michael@0 | 8930 | curLeft = parseFloat( curCSSLeft ) || 0; |
michael@0 | 8931 | } |
michael@0 | 8932 | |
michael@0 | 8933 | if ( jQuery.isFunction( options ) ) { |
michael@0 | 8934 | options = options.call( elem, i, curOffset ); |
michael@0 | 8935 | } |
michael@0 | 8936 | |
michael@0 | 8937 | if ( options.top != null ) { |
michael@0 | 8938 | props.top = ( options.top - curOffset.top ) + curTop; |
michael@0 | 8939 | } |
michael@0 | 8940 | if ( options.left != null ) { |
michael@0 | 8941 | props.left = ( options.left - curOffset.left ) + curLeft; |
michael@0 | 8942 | } |
michael@0 | 8943 | |
michael@0 | 8944 | if ( "using" in options ) { |
michael@0 | 8945 | options.using.call( elem, props ); |
michael@0 | 8946 | |
michael@0 | 8947 | } else { |
michael@0 | 8948 | curElem.css( props ); |
michael@0 | 8949 | } |
michael@0 | 8950 | } |
michael@0 | 8951 | }; |
michael@0 | 8952 | |
michael@0 | 8953 | jQuery.fn.extend({ |
michael@0 | 8954 | offset: function( options ) { |
michael@0 | 8955 | if ( arguments.length ) { |
michael@0 | 8956 | return options === undefined ? |
michael@0 | 8957 | this : |
michael@0 | 8958 | this.each(function( i ) { |
michael@0 | 8959 | jQuery.offset.setOffset( this, options, i ); |
michael@0 | 8960 | }); |
michael@0 | 8961 | } |
michael@0 | 8962 | |
michael@0 | 8963 | var docElem, win, |
michael@0 | 8964 | elem = this[ 0 ], |
michael@0 | 8965 | box = { top: 0, left: 0 }, |
michael@0 | 8966 | doc = elem && elem.ownerDocument; |
michael@0 | 8967 | |
michael@0 | 8968 | if ( !doc ) { |
michael@0 | 8969 | return; |
michael@0 | 8970 | } |
michael@0 | 8971 | |
michael@0 | 8972 | docElem = doc.documentElement; |
michael@0 | 8973 | |
michael@0 | 8974 | // Make sure it's not a disconnected DOM node |
michael@0 | 8975 | if ( !jQuery.contains( docElem, elem ) ) { |
michael@0 | 8976 | return box; |
michael@0 | 8977 | } |
michael@0 | 8978 | |
michael@0 | 8979 | // If we don't have gBCR, just use 0,0 rather than error |
michael@0 | 8980 | // BlackBerry 5, iOS 3 (original iPhone) |
michael@0 | 8981 | if ( typeof elem.getBoundingClientRect !== strundefined ) { |
michael@0 | 8982 | box = elem.getBoundingClientRect(); |
michael@0 | 8983 | } |
michael@0 | 8984 | win = getWindow( doc ); |
michael@0 | 8985 | return { |
michael@0 | 8986 | top: box.top + win.pageYOffset - docElem.clientTop, |
michael@0 | 8987 | left: box.left + win.pageXOffset - docElem.clientLeft |
michael@0 | 8988 | }; |
michael@0 | 8989 | }, |
michael@0 | 8990 | |
michael@0 | 8991 | position: function() { |
michael@0 | 8992 | if ( !this[ 0 ] ) { |
michael@0 | 8993 | return; |
michael@0 | 8994 | } |
michael@0 | 8995 | |
michael@0 | 8996 | var offsetParent, offset, |
michael@0 | 8997 | elem = this[ 0 ], |
michael@0 | 8998 | parentOffset = { top: 0, left: 0 }; |
michael@0 | 8999 | |
michael@0 | 9000 | // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent |
michael@0 | 9001 | if ( jQuery.css( elem, "position" ) === "fixed" ) { |
michael@0 | 9002 | // We assume that getBoundingClientRect is available when computed position is fixed |
michael@0 | 9003 | offset = elem.getBoundingClientRect(); |
michael@0 | 9004 | |
michael@0 | 9005 | } else { |
michael@0 | 9006 | // Get *real* offsetParent |
michael@0 | 9007 | offsetParent = this.offsetParent(); |
michael@0 | 9008 | |
michael@0 | 9009 | // Get correct offsets |
michael@0 | 9010 | offset = this.offset(); |
michael@0 | 9011 | if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { |
michael@0 | 9012 | parentOffset = offsetParent.offset(); |
michael@0 | 9013 | } |
michael@0 | 9014 | |
michael@0 | 9015 | // Add offsetParent borders |
michael@0 | 9016 | parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); |
michael@0 | 9017 | parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); |
michael@0 | 9018 | } |
michael@0 | 9019 | |
michael@0 | 9020 | // Subtract parent offsets and element margins |
michael@0 | 9021 | return { |
michael@0 | 9022 | top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), |
michael@0 | 9023 | left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) |
michael@0 | 9024 | }; |
michael@0 | 9025 | }, |
michael@0 | 9026 | |
michael@0 | 9027 | offsetParent: function() { |
michael@0 | 9028 | return this.map(function() { |
michael@0 | 9029 | var offsetParent = this.offsetParent || docElem; |
michael@0 | 9030 | |
michael@0 | 9031 | while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { |
michael@0 | 9032 | offsetParent = offsetParent.offsetParent; |
michael@0 | 9033 | } |
michael@0 | 9034 | |
michael@0 | 9035 | return offsetParent || docElem; |
michael@0 | 9036 | }); |
michael@0 | 9037 | } |
michael@0 | 9038 | }); |
michael@0 | 9039 | |
michael@0 | 9040 | // Create scrollLeft and scrollTop methods |
michael@0 | 9041 | jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { |
michael@0 | 9042 | var top = "pageYOffset" === prop; |
michael@0 | 9043 | |
michael@0 | 9044 | jQuery.fn[ method ] = function( val ) { |
michael@0 | 9045 | return access( this, function( elem, method, val ) { |
michael@0 | 9046 | var win = getWindow( elem ); |
michael@0 | 9047 | |
michael@0 | 9048 | if ( val === undefined ) { |
michael@0 | 9049 | return win ? win[ prop ] : elem[ method ]; |
michael@0 | 9050 | } |
michael@0 | 9051 | |
michael@0 | 9052 | if ( win ) { |
michael@0 | 9053 | win.scrollTo( |
michael@0 | 9054 | !top ? val : window.pageXOffset, |
michael@0 | 9055 | top ? val : window.pageYOffset |
michael@0 | 9056 | ); |
michael@0 | 9057 | |
michael@0 | 9058 | } else { |
michael@0 | 9059 | elem[ method ] = val; |
michael@0 | 9060 | } |
michael@0 | 9061 | }, method, val, arguments.length, null ); |
michael@0 | 9062 | }; |
michael@0 | 9063 | }); |
michael@0 | 9064 | |
michael@0 | 9065 | // Add the top/left cssHooks using jQuery.fn.position |
michael@0 | 9066 | // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 |
michael@0 | 9067 | // getComputedStyle returns percent when specified for top/left/bottom/right |
michael@0 | 9068 | // rather than make the css module depend on the offset module, we just check for it here |
michael@0 | 9069 | jQuery.each( [ "top", "left" ], function( i, prop ) { |
michael@0 | 9070 | jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, |
michael@0 | 9071 | function( elem, computed ) { |
michael@0 | 9072 | if ( computed ) { |
michael@0 | 9073 | computed = curCSS( elem, prop ); |
michael@0 | 9074 | // if curCSS returns percentage, fallback to offset |
michael@0 | 9075 | return rnumnonpx.test( computed ) ? |
michael@0 | 9076 | jQuery( elem ).position()[ prop ] + "px" : |
michael@0 | 9077 | computed; |
michael@0 | 9078 | } |
michael@0 | 9079 | } |
michael@0 | 9080 | ); |
michael@0 | 9081 | }); |
michael@0 | 9082 | |
michael@0 | 9083 | |
michael@0 | 9084 | // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods |
michael@0 | 9085 | jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { |
michael@0 | 9086 | jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { |
michael@0 | 9087 | // margin is only for outerHeight, outerWidth |
michael@0 | 9088 | jQuery.fn[ funcName ] = function( margin, value ) { |
michael@0 | 9089 | var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), |
michael@0 | 9090 | extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); |
michael@0 | 9091 | |
michael@0 | 9092 | return access( this, function( elem, type, value ) { |
michael@0 | 9093 | var doc; |
michael@0 | 9094 | |
michael@0 | 9095 | if ( jQuery.isWindow( elem ) ) { |
michael@0 | 9096 | // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there |
michael@0 | 9097 | // isn't a whole lot we can do. See pull request at this URL for discussion: |
michael@0 | 9098 | // https://github.com/jquery/jquery/pull/764 |
michael@0 | 9099 | return elem.document.documentElement[ "client" + name ]; |
michael@0 | 9100 | } |
michael@0 | 9101 | |
michael@0 | 9102 | // Get document width or height |
michael@0 | 9103 | if ( elem.nodeType === 9 ) { |
michael@0 | 9104 | doc = elem.documentElement; |
michael@0 | 9105 | |
michael@0 | 9106 | // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], |
michael@0 | 9107 | // whichever is greatest |
michael@0 | 9108 | return Math.max( |
michael@0 | 9109 | elem.body[ "scroll" + name ], doc[ "scroll" + name ], |
michael@0 | 9110 | elem.body[ "offset" + name ], doc[ "offset" + name ], |
michael@0 | 9111 | doc[ "client" + name ] |
michael@0 | 9112 | ); |
michael@0 | 9113 | } |
michael@0 | 9114 | |
michael@0 | 9115 | return value === undefined ? |
michael@0 | 9116 | // Get width or height on the element, requesting but not forcing parseFloat |
michael@0 | 9117 | jQuery.css( elem, type, extra ) : |
michael@0 | 9118 | |
michael@0 | 9119 | // Set width or height on the element |
michael@0 | 9120 | jQuery.style( elem, type, value, extra ); |
michael@0 | 9121 | }, type, chainable ? margin : undefined, chainable, null ); |
michael@0 | 9122 | }; |
michael@0 | 9123 | }); |
michael@0 | 9124 | }); |
michael@0 | 9125 | |
michael@0 | 9126 | |
michael@0 | 9127 | // The number of elements contained in the matched element set |
michael@0 | 9128 | jQuery.fn.size = function() { |
michael@0 | 9129 | return this.length; |
michael@0 | 9130 | }; |
michael@0 | 9131 | |
michael@0 | 9132 | jQuery.fn.andSelf = jQuery.fn.addBack; |
michael@0 | 9133 | |
michael@0 | 9134 | |
michael@0 | 9135 | |
michael@0 | 9136 | |
michael@0 | 9137 | // Register as a named AMD module, since jQuery can be concatenated with other |
michael@0 | 9138 | // files that may use define, but not via a proper concatenation script that |
michael@0 | 9139 | // understands anonymous AMD modules. A named AMD is safest and most robust |
michael@0 | 9140 | // way to register. Lowercase jquery is used because AMD module names are |
michael@0 | 9141 | // derived from file names, and jQuery is normally delivered in a lowercase |
michael@0 | 9142 | // file name. Do this after creating the global so that if an AMD module wants |
michael@0 | 9143 | // to call noConflict to hide this version of jQuery, it will work. |
michael@0 | 9144 | |
michael@0 | 9145 | // Note that for maximum portability, libraries that are not jQuery should |
michael@0 | 9146 | // declare themselves as anonymous modules, and avoid setting a global if an |
michael@0 | 9147 | // AMD loader is present. jQuery is a special case. For more information, see |
michael@0 | 9148 | // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon |
michael@0 | 9149 | |
michael@0 | 9150 | if ( typeof define === "function" && define.amd ) { |
michael@0 | 9151 | define( "jquery", [], function() { |
michael@0 | 9152 | return jQuery; |
michael@0 | 9153 | }); |
michael@0 | 9154 | } |
michael@0 | 9155 | |
michael@0 | 9156 | |
michael@0 | 9157 | |
michael@0 | 9158 | |
michael@0 | 9159 | var |
michael@0 | 9160 | // Map over jQuery in case of overwrite |
michael@0 | 9161 | _jQuery = window.jQuery, |
michael@0 | 9162 | |
michael@0 | 9163 | // Map over the $ in case of overwrite |
michael@0 | 9164 | _$ = window.$; |
michael@0 | 9165 | |
michael@0 | 9166 | jQuery.noConflict = function( deep ) { |
michael@0 | 9167 | if ( window.$ === jQuery ) { |
michael@0 | 9168 | window.$ = _$; |
michael@0 | 9169 | } |
michael@0 | 9170 | |
michael@0 | 9171 | if ( deep && window.jQuery === jQuery ) { |
michael@0 | 9172 | window.jQuery = _jQuery; |
michael@0 | 9173 | } |
michael@0 | 9174 | |
michael@0 | 9175 | return jQuery; |
michael@0 | 9176 | }; |
michael@0 | 9177 | |
michael@0 | 9178 | // Expose jQuery and $ identifiers, even in |
michael@0 | 9179 | // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) |
michael@0 | 9180 | // and CommonJS for browser emulators (#13566) |
michael@0 | 9181 | if ( typeof noGlobal === strundefined ) { |
michael@0 | 9182 | window.jQuery = window.$ = jQuery; |
michael@0 | 9183 | } |
michael@0 | 9184 | |
michael@0 | 9185 | |
michael@0 | 9186 | |
michael@0 | 9187 | |
michael@0 | 9188 | return jQuery; |
michael@0 | 9189 | |
michael@0 | 9190 | })); |