jquery-source 1.4.4 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module Jquery
2
2
  module Source
3
- VERSION = "1.4.4"
3
+ VERSION = "1.5.0"
4
4
  end
5
5
  end
@@ -1,17 +1,17 @@
1
1
  /*!
2
- * jQuery JavaScript Library v1.4.4
2
+ * jQuery JavaScript Library v1.5
3
3
  * http://jquery.com/
4
4
  *
5
- * Copyright 2010, John Resig
5
+ * Copyright 2011, John Resig
6
6
  * Dual licensed under the MIT or GPL Version 2 licenses.
7
7
  * http://jquery.org/license
8
8
  *
9
9
  * Includes Sizzle.js
10
10
  * http://sizzlejs.com/
11
- * Copyright 2010, The Dojo Foundation
11
+ * Copyright 2011, The Dojo Foundation
12
12
  * Released under the MIT, BSD, and GPL Licenses.
13
13
  *
14
- * Date: Thu Nov 11 19:04:53 2010 -0500
14
+ * Date: Mon Jan 31 08:31:29 2011 -0500
15
15
  */
16
16
  (function( window, undefined ) {
17
17
 
@@ -22,7 +22,7 @@ var jQuery = (function() {
22
22
  // Define a local copy of jQuery
23
23
  var jQuery = function( selector, context ) {
24
24
  // The jQuery object is actually just the init constructor 'enhanced'
25
- return new jQuery.fn.init( selector, context );
25
+ return new jQuery.fn.init( selector, context, rootjQuery );
26
26
  },
27
27
 
28
28
  // Map over jQuery in case of overwrite
@@ -38,20 +38,13 @@ var jQuery = function( selector, context ) {
38
38
  // (both of which we optimize for)
39
39
  quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
40
40
 
41
- // Is it a simple selector
42
- isSimple = /^.[^:#\[\.,]*$/,
43
-
44
41
  // Check if a string has a non-whitespace character in it
45
42
  rnotwhite = /\S/,
46
- rwhite = /\s/,
47
43
 
48
44
  // Used for trimming whitespace
49
45
  trimLeft = /^\s+/,
50
46
  trimRight = /\s+$/,
51
47
 
52
- // Check for non-word characters
53
- rnonword = /\W/,
54
-
55
48
  // Check for digits
56
49
  rdigit = /\d/,
57
50
 
@@ -75,12 +68,15 @@ var jQuery = function( selector, context ) {
75
68
 
76
69
  // For matching the engine and version of the browser
77
70
  browserMatch,
78
-
71
+
79
72
  // Has the ready events already been bound?
80
73
  readyBound = false,
81
-
82
- // The functions to execute on DOM ready
83
- readyList = [],
74
+
75
+ // The deferred used on DOM ready
76
+ readyList,
77
+
78
+ // Promise methods
79
+ promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
84
80
 
85
81
  // The ready event handler
86
82
  DOMContentLoaded,
@@ -92,12 +88,13 @@ var jQuery = function( selector, context ) {
92
88
  slice = Array.prototype.slice,
93
89
  trim = String.prototype.trim,
94
90
  indexOf = Array.prototype.indexOf,
95
-
91
+
96
92
  // [[Class]] -> type pairs
97
93
  class2type = {};
98
94
 
99
95
  jQuery.fn = jQuery.prototype = {
100
- init: function( selector, context ) {
96
+ constructor: jQuery,
97
+ init: function( selector, context, rootjQuery ) {
101
98
  var match, elem, ret, doc;
102
99
 
103
100
  // Handle $(""), $(null), or $(undefined)
@@ -111,7 +108,7 @@ jQuery.fn = jQuery.prototype = {
111
108
  this.length = 1;
112
109
  return this;
113
110
  }
114
-
111
+
115
112
  // The body element only exists once, optimize finding it
116
113
  if ( selector === "body" && !context && document.body ) {
117
114
  this.context = document;
@@ -131,6 +128,7 @@ jQuery.fn = jQuery.prototype = {
131
128
 
132
129
  // HANDLE: $(html) -> $(array)
133
130
  if ( match[1] ) {
131
+ context = context instanceof jQuery ? context[0] : context;
134
132
  doc = (context ? context.ownerDocument || context : document);
135
133
 
136
134
  // If a single string is passed in and it's a single tag
@@ -148,11 +146,11 @@ jQuery.fn = jQuery.prototype = {
148
146
 
149
147
  } else {
150
148
  ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151
- selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
149
+ selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
152
150
  }
153
-
151
+
154
152
  return jQuery.merge( this, selector );
155
-
153
+
156
154
  // HANDLE: $("#id")
157
155
  } else {
158
156
  elem = document.getElementById( match[2] );
@@ -176,13 +174,6 @@ jQuery.fn = jQuery.prototype = {
176
174
  return this;
177
175
  }
178
176
 
179
- // HANDLE: $("TAG")
180
- } else if ( !context && !rnonword.test( selector ) ) {
181
- this.selector = selector;
182
- this.context = document;
183
- selector = document.getElementsByTagName( selector );
184
- return jQuery.merge( this, selector );
185
-
186
177
  // HANDLE: $(expr, $(...))
187
178
  } else if ( !context || context.jquery ) {
188
179
  return (context || rootjQuery).find( selector );
@@ -190,7 +181,7 @@ jQuery.fn = jQuery.prototype = {
190
181
  // HANDLE: $(expr, context)
191
182
  // (which is just equivalent to: $(context).find(expr)
192
183
  } else {
193
- return jQuery( context ).find( selector );
184
+ return this.constructor( context ).find( selector );
194
185
  }
195
186
 
196
187
  // HANDLE: $(function)
@@ -211,7 +202,7 @@ jQuery.fn = jQuery.prototype = {
211
202
  selector: "",
212
203
 
213
204
  // The current version of jQuery being used
214
- jquery: "1.4.4",
205
+ jquery: "1.5",
215
206
 
216
207
  // The default length of a jQuery object is 0
217
208
  length: 0,
@@ -234,18 +225,18 @@ jQuery.fn = jQuery.prototype = {
234
225
  this.toArray() :
235
226
 
236
227
  // Return just the object
237
- ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
228
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
238
229
  },
239
230
 
240
231
  // Take an array of elements and push it onto the stack
241
232
  // (returning the new matched element set)
242
233
  pushStack: function( elems, name, selector ) {
243
234
  // Build a new jQuery matched element set
244
- var ret = jQuery();
235
+ var ret = this.constructor();
245
236
 
246
237
  if ( jQuery.isArray( elems ) ) {
247
238
  push.apply( ret, elems );
248
-
239
+
249
240
  } else {
250
241
  jQuery.merge( ret, elems );
251
242
  }
@@ -271,25 +262,17 @@ jQuery.fn = jQuery.prototype = {
271
262
  each: function( callback, args ) {
272
263
  return jQuery.each( this, callback, args );
273
264
  },
274
-
265
+
275
266
  ready: function( fn ) {
276
267
  // Attach the listeners
277
268
  jQuery.bindReady();
278
269
 
279
- // If the DOM is already ready
280
- if ( jQuery.isReady ) {
281
- // Execute the function immediately
282
- fn.call( document, jQuery );
283
-
284
- // Otherwise, remember the function for later
285
- } else if ( readyList ) {
286
- // Add the function to the wait list
287
- readyList.push( fn );
288
- }
270
+ // Add the callback
271
+ readyList.done( fn );
289
272
 
290
273
  return this;
291
274
  },
292
-
275
+
293
276
  eq: function( i ) {
294
277
  return i === -1 ?
295
278
  this.slice( i ) :
@@ -314,9 +297,9 @@ jQuery.fn = jQuery.prototype = {
314
297
  return callback.call( elem, i, elem );
315
298
  }));
316
299
  },
317
-
300
+
318
301
  end: function() {
319
- return this.prevObject || jQuery(null);
302
+ return this.prevObject || this.constructor(null);
320
303
  },
321
304
 
322
305
  // For internal use only.
@@ -403,14 +386,14 @@ jQuery.extend({
403
386
 
404
387
  return jQuery;
405
388
  },
406
-
389
+
407
390
  // Is the DOM ready to be used? Set to true once it occurs.
408
391
  isReady: false,
409
392
 
410
393
  // A counter to track how many items to wait for before
411
394
  // the ready event fires. See #6781
412
395
  readyWait: 1,
413
-
396
+
414
397
  // Handle when the DOM is ready
415
398
  ready: function( wait ) {
416
399
  // A third-party is pushing the ready event forwards
@@ -434,27 +417,15 @@ jQuery.extend({
434
417
  }
435
418
 
436
419
  // If there are functions bound, to execute
437
- if ( readyList ) {
438
- // Execute all of them
439
- var fn,
440
- i = 0,
441
- ready = readyList;
420
+ readyList.resolveWith( document, [ jQuery ] );
442
421
 
443
- // Reset the list of functions
444
- readyList = null;
445
-
446
- while ( (fn = ready[ i++ ]) ) {
447
- fn.call( document, jQuery );
448
- }
449
-
450
- // Trigger any bound ready events
451
- if ( jQuery.fn.trigger ) {
452
- jQuery( document ).trigger( "ready" ).unbind( "ready" );
453
- }
422
+ // Trigger any bound ready events
423
+ if ( jQuery.fn.trigger ) {
424
+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
454
425
  }
455
426
  }
456
427
  },
457
-
428
+
458
429
  bindReady: function() {
459
430
  if ( readyBound ) {
460
431
  return;
@@ -473,7 +444,7 @@ jQuery.extend({
473
444
  if ( document.addEventListener ) {
474
445
  // Use the handy event callback
475
446
  document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
476
-
447
+
477
448
  // A fallback to window.onload, that will always work
478
449
  window.addEventListener( "load", jQuery.ready, false );
479
450
 
@@ -482,7 +453,7 @@ jQuery.extend({
482
453
  // ensure firing before onload,
483
454
  // maybe late but safe also for iframes
484
455
  document.attachEvent("onreadystatechange", DOMContentLoaded);
485
-
456
+
486
457
  // A fallback to window.onload, that will always work
487
458
  window.attachEvent( "onload", jQuery.ready );
488
459
 
@@ -533,20 +504,20 @@ jQuery.extend({
533
504
  if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
534
505
  return false;
535
506
  }
536
-
507
+
537
508
  // Not own constructor property must be Object
538
509
  if ( obj.constructor &&
539
510
  !hasOwn.call(obj, "constructor") &&
540
511
  !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
541
512
  return false;
542
513
  }
543
-
514
+
544
515
  // Own properties are enumerated firstly, so to speed up,
545
516
  // if last one is own, then all properties are own.
546
-
517
+
547
518
  var key;
548
519
  for ( key in obj ) {}
549
-
520
+
550
521
  return key === undefined || hasOwn.call( obj, key );
551
522
  },
552
523
 
@@ -556,11 +527,11 @@ jQuery.extend({
556
527
  }
557
528
  return true;
558
529
  },
559
-
530
+
560
531
  error: function( msg ) {
561
532
  throw msg;
562
533
  },
563
-
534
+
564
535
  parseJSON: function( data ) {
565
536
  if ( typeof data !== "string" || !data ) {
566
537
  return null;
@@ -568,7 +539,7 @@ jQuery.extend({
568
539
 
569
540
  // Make sure leading/trailing whitespace is removed (IE can't handle it)
570
541
  data = jQuery.trim( data );
571
-
542
+
572
543
  // Make sure the incoming data is actual JSON
573
544
  // Logic borrowed from http://json.org/json2.js
574
545
  if ( rvalidchars.test(data.replace(rvalidescape, "@")
@@ -585,6 +556,28 @@ jQuery.extend({
585
556
  }
586
557
  },
587
558
 
559
+ // Cross-browser xml parsing
560
+ // (xml & tmp used internally)
561
+ parseXML: function( data , xml , tmp ) {
562
+
563
+ if ( window.DOMParser ) { // Standard
564
+ tmp = new DOMParser();
565
+ xml = tmp.parseFromString( data , "text/xml" );
566
+ } else { // IE
567
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
568
+ xml.async = "false";
569
+ xml.loadXML( data );
570
+ }
571
+
572
+ tmp = xml.documentElement;
573
+
574
+ if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
575
+ jQuery.error( "Invalid XML: " + data );
576
+ }
577
+
578
+ return xml;
579
+ },
580
+
588
581
  noop: function() {},
589
582
 
590
583
  // Evalulates a script in a global context
@@ -597,7 +590,7 @@ jQuery.extend({
597
590
 
598
591
  script.type = "text/javascript";
599
592
 
600
- if ( jQuery.support.scriptEval ) {
593
+ if ( jQuery.support.scriptEval() ) {
601
594
  script.appendChild( document.createTextNode( data ) );
602
595
  } else {
603
596
  script.text = data;
@@ -710,7 +703,7 @@ jQuery.extend({
710
703
  for ( var l = second.length; j < l; j++ ) {
711
704
  first[ i++ ] = second[ j ];
712
705
  }
713
-
706
+
714
707
  } else {
715
708
  while ( second[j] !== undefined ) {
716
709
  first[ i++ ] = second[ j++ ];
@@ -752,6 +745,7 @@ jQuery.extend({
752
745
  }
753
746
  }
754
747
 
748
+ // Flatten any nested arrays
755
749
  return ret.concat.apply( [], ret );
756
750
  },
757
751
 
@@ -790,7 +784,7 @@ jQuery.extend({
790
784
  // The value/s can be optionally by executed if its a function
791
785
  access: function( elems, key, value, exec, fn, pass ) {
792
786
  var length = elems.length;
793
-
787
+
794
788
  // Setting many attributes
795
789
  if ( typeof key === "object" ) {
796
790
  for ( var k in key ) {
@@ -798,19 +792,19 @@ jQuery.extend({
798
792
  }
799
793
  return elems;
800
794
  }
801
-
795
+
802
796
  // Setting one attribute
803
797
  if ( value !== undefined ) {
804
798
  // Optionally, function values get executed if exec is true
805
799
  exec = !pass && exec && jQuery.isFunction(value);
806
-
800
+
807
801
  for ( var i = 0; i < length; i++ ) {
808
802
  fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
809
803
  }
810
-
804
+
811
805
  return elems;
812
806
  }
813
-
807
+
814
808
  // Getting an attribute
815
809
  return length ? fn( elems[0], key ) : undefined;
816
810
  },
@@ -819,6 +813,155 @@ jQuery.extend({
819
813
  return (new Date()).getTime();
820
814
  },
821
815
 
816
+ // Create a simple deferred (one callbacks list)
817
+ _Deferred: function() {
818
+ var // callbacks list
819
+ callbacks = [],
820
+ // stored [ context , args ]
821
+ fired,
822
+ // to avoid firing when already doing so
823
+ firing,
824
+ // flag to know if the deferred has been cancelled
825
+ cancelled,
826
+ // the deferred itself
827
+ deferred = {
828
+
829
+ // done( f1, f2, ...)
830
+ done: function() {
831
+ if ( !cancelled ) {
832
+ var args = arguments,
833
+ i,
834
+ length,
835
+ elem,
836
+ type,
837
+ _fired;
838
+ if ( fired ) {
839
+ _fired = fired;
840
+ fired = 0;
841
+ }
842
+ for ( i = 0, length = args.length; i < length; i++ ) {
843
+ elem = args[ i ];
844
+ type = jQuery.type( elem );
845
+ if ( type === "array" ) {
846
+ deferred.done.apply( deferred, elem );
847
+ } else if ( type === "function" ) {
848
+ callbacks.push( elem );
849
+ }
850
+ }
851
+ if ( _fired ) {
852
+ deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
853
+ }
854
+ }
855
+ return this;
856
+ },
857
+
858
+ // resolve with given context and args
859
+ resolveWith: function( context, args ) {
860
+ if ( !cancelled && !fired && !firing ) {
861
+ firing = 1;
862
+ try {
863
+ while( callbacks[ 0 ] ) {
864
+ callbacks.shift().apply( context, args );
865
+ }
866
+ }
867
+ finally {
868
+ fired = [ context, args ];
869
+ firing = 0;
870
+ }
871
+ }
872
+ return this;
873
+ },
874
+
875
+ // resolve with this as context and given arguments
876
+ resolve: function() {
877
+ deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments );
878
+ return this;
879
+ },
880
+
881
+ // Has this deferred been resolved?
882
+ isResolved: function() {
883
+ return !!( firing || fired );
884
+ },
885
+
886
+ // Cancel
887
+ cancel: function() {
888
+ cancelled = 1;
889
+ callbacks = [];
890
+ return this;
891
+ }
892
+ };
893
+
894
+ return deferred;
895
+ },
896
+
897
+ // Full fledged deferred (two callbacks list)
898
+ Deferred: function( func ) {
899
+ var deferred = jQuery._Deferred(),
900
+ failDeferred = jQuery._Deferred(),
901
+ promise;
902
+ // Add errorDeferred methods, then and promise
903
+ jQuery.extend( deferred, {
904
+ then: function( doneCallbacks, failCallbacks ) {
905
+ deferred.done( doneCallbacks ).fail( failCallbacks );
906
+ return this;
907
+ },
908
+ fail: failDeferred.done,
909
+ rejectWith: failDeferred.resolveWith,
910
+ reject: failDeferred.resolve,
911
+ isRejected: failDeferred.isResolved,
912
+ // Get a promise for this deferred
913
+ // If obj is provided, the promise aspect is added to the object
914
+ promise: function( obj , i /* internal */ ) {
915
+ if ( obj == null ) {
916
+ if ( promise ) {
917
+ return promise;
918
+ }
919
+ promise = obj = {};
920
+ }
921
+ i = promiseMethods.length;
922
+ while( i-- ) {
923
+ obj[ promiseMethods[ i ] ] = deferred[ promiseMethods[ i ] ];
924
+ }
925
+ return obj;
926
+ }
927
+ } );
928
+ // Make sure only one callback list will be used
929
+ deferred.then( failDeferred.cancel, deferred.cancel );
930
+ // Unexpose cancel
931
+ delete deferred.cancel;
932
+ // Call given func if any
933
+ if ( func ) {
934
+ func.call( deferred, deferred );
935
+ }
936
+ return deferred;
937
+ },
938
+
939
+ // Deferred helper
940
+ when: function( object ) {
941
+ var args = arguments,
942
+ length = args.length,
943
+ deferred = length <= 1 && object && jQuery.isFunction( object.promise ) ?
944
+ object :
945
+ jQuery.Deferred(),
946
+ promise = deferred.promise(),
947
+ resolveArray;
948
+
949
+ if ( length > 1 ) {
950
+ resolveArray = new Array( length );
951
+ jQuery.each( args, function( index, element ) {
952
+ jQuery.when( element ).then( function( value ) {
953
+ resolveArray[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value;
954
+ if( ! --length ) {
955
+ deferred.resolveWith( promise, resolveArray );
956
+ }
957
+ }, deferred.reject );
958
+ } );
959
+ } else if ( deferred !== object ) {
960
+ deferred.resolve( object );
961
+ }
962
+ return promise;
963
+ },
964
+
822
965
  // Use of jQuery.browser is frowned upon.
823
966
  // More details: http://docs.jquery.com/Utilities/jQuery.browser
824
967
  uaMatch: function( ua ) {
@@ -833,9 +976,33 @@ jQuery.extend({
833
976
  return { browser: match[1] || "", version: match[2] || "0" };
834
977
  },
835
978
 
979
+ sub: function() {
980
+ function jQuerySubclass( selector, context ) {
981
+ return new jQuerySubclass.fn.init( selector, context );
982
+ }
983
+ jQuery.extend( true, jQuerySubclass, this );
984
+ jQuerySubclass.superclass = this;
985
+ jQuerySubclass.fn = jQuerySubclass.prototype = this();
986
+ jQuerySubclass.fn.constructor = jQuerySubclass;
987
+ jQuerySubclass.subclass = this.subclass;
988
+ jQuerySubclass.fn.init = function init( selector, context ) {
989
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) {
990
+ context = jQuerySubclass(context);
991
+ }
992
+
993
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
994
+ };
995
+ jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
996
+ var rootjQuerySubclass = jQuerySubclass(document);
997
+ return jQuerySubclass;
998
+ },
999
+
836
1000
  browser: {}
837
1001
  });
838
1002
 
1003
+ // Create readyList deferred
1004
+ readyList = jQuery._Deferred();
1005
+
839
1006
  // Populate the class2type map
840
1007
  jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
841
1008
  class2type[ "[object " + name + "]" ] = name.toLowerCase();
@@ -858,9 +1025,8 @@ if ( indexOf ) {
858
1025
  };
859
1026
  }
860
1027
 
861
- // Verify that \s matches non-breaking spaces
862
- // (IE fails on this test)
863
- if ( !rwhite.test( "\xA0" ) ) {
1028
+ // IE doesn't match non-breaking spaces with \s
1029
+ if ( rnotwhite.test( "\xA0" ) ) {
864
1030
  trimLeft = /^[\s\xA0]+/;
865
1031
  trimRight = /[\s\xA0]+$/;
866
1032
  }
@@ -914,10 +1080,7 @@ return (window.jQuery = window.$ = jQuery);
914
1080
 
915
1081
  jQuery.support = {};
916
1082
 
917
- var root = document.documentElement,
918
- script = document.createElement("script"),
919
- div = document.createElement("div"),
920
- id = "script" + jQuery.now();
1083
+ var div = document.createElement("div");
921
1084
 
922
1085
  div.style.display = "none";
923
1086
  div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
@@ -974,7 +1137,7 @@ return (window.jQuery = window.$ = jQuery);
974
1137
  deleteExpando: true,
975
1138
  optDisabled: false,
976
1139
  checkClone: false,
977
- scriptEval: false,
1140
+ _scriptEval: null,
978
1141
  noCloneEvent: true,
979
1142
  boxModel: null,
980
1143
  inlineBlockNeedsLayout: false,
@@ -987,32 +1150,46 @@ return (window.jQuery = window.$ = jQuery);
987
1150
  select.disabled = true;
988
1151
  jQuery.support.optDisabled = !opt.disabled;
989
1152
 
990
- script.type = "text/javascript";
991
- try {
992
- script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
993
- } catch(e) {}
1153
+ jQuery.support.scriptEval = function() {
1154
+ if ( jQuery.support._scriptEval === null ) {
1155
+ var root = document.documentElement,
1156
+ script = document.createElement("script"),
1157
+ id = "script" + jQuery.now();
1158
+
1159
+ script.type = "text/javascript";
1160
+ try {
1161
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
1162
+ } catch(e) {}
994
1163
 
995
- root.insertBefore( script, root.firstChild );
1164
+ root.insertBefore( script, root.firstChild );
996
1165
 
997
- // Make sure that the execution of code works by injecting a script
998
- // tag with appendChild/createTextNode
999
- // (IE doesn't support this, fails, and uses .text instead)
1000
- if ( window[ id ] ) {
1001
- jQuery.support.scriptEval = true;
1002
- delete window[ id ];
1003
- }
1166
+ // Make sure that the execution of code works by injecting a script
1167
+ // tag with appendChild/createTextNode
1168
+ // (IE doesn't support this, fails, and uses .text instead)
1169
+ if ( window[ id ] ) {
1170
+ jQuery.support._scriptEval = true;
1171
+ delete window[ id ];
1172
+ } else {
1173
+ jQuery.support._scriptEval = false;
1174
+ }
1175
+
1176
+ root.removeChild( script );
1177
+ // release memory in IE
1178
+ root = script = id = null;
1179
+ }
1180
+
1181
+ return jQuery.support._scriptEval;
1182
+ };
1004
1183
 
1005
1184
  // Test to see if it's possible to delete an expando from an element
1006
1185
  // Fails in Internet Explorer
1007
1186
  try {
1008
- delete script.test;
1187
+ delete div.test;
1009
1188
 
1010
1189
  } catch(e) {
1011
1190
  jQuery.support.deleteExpando = false;
1012
1191
  }
1013
1192
 
1014
- root.removeChild( script );
1015
-
1016
1193
  if ( div.attachEvent && div.fireEvent ) {
1017
1194
  div.attachEvent("onclick", function click() {
1018
1195
  // Cloning a node shouldn't copy over any
@@ -1035,10 +1212,16 @@ return (window.jQuery = window.$ = jQuery);
1035
1212
  // Figure out if the W3C box model works as expected
1036
1213
  // document.body must exist before we can do this
1037
1214
  jQuery(function() {
1038
- var div = document.createElement("div");
1039
- div.style.width = div.style.paddingLeft = "1px";
1215
+ var div = document.createElement("div"),
1216
+ body = document.getElementsByTagName("body")[0];
1040
1217
 
1041
- document.body.appendChild( div );
1218
+ // Frameset documents with no body should not run this code
1219
+ if ( !body ) {
1220
+ return;
1221
+ }
1222
+
1223
+ div.style.width = div.style.paddingLeft = "1px";
1224
+ body.appendChild( div );
1042
1225
  jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1043
1226
 
1044
1227
  if ( "zoom" in div.style ) {
@@ -1057,7 +1240,7 @@ return (window.jQuery = window.$ = jQuery);
1057
1240
  jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1058
1241
  }
1059
1242
 
1060
- div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
1243
+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1061
1244
  var tds = div.getElementsByTagName("td");
1062
1245
 
1063
1246
  // Check if table cells still have offsetWidth/Height when they are set
@@ -1077,7 +1260,7 @@ return (window.jQuery = window.$ = jQuery);
1077
1260
  jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1078
1261
  div.innerHTML = "";
1079
1262
 
1080
- document.body.removeChild( div ).style.display = "none";
1263
+ body.removeChild( div ).style.display = "none";
1081
1264
  div = tds = null;
1082
1265
  });
1083
1266
 
@@ -1087,6 +1270,14 @@ return (window.jQuery = window.$ = jQuery);
1087
1270
  var el = document.createElement("div");
1088
1271
  eventName = "on" + eventName;
1089
1272
 
1273
+ // We only care about the case where non-standard event systems
1274
+ // are used, namely in IE. Short-circuiting here helps us to
1275
+ // avoid an eval call (in setAttribute) which can cause CSP
1276
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1277
+ if ( !el.attachEvent ) {
1278
+ return true;
1279
+ }
1280
+
1090
1281
  var isSupported = (eventName in el);
1091
1282
  if ( !isSupported ) {
1092
1283
  el.setAttribute(eventName, "return;");
@@ -1101,13 +1292,12 @@ return (window.jQuery = window.$ = jQuery);
1101
1292
  jQuery.support.changeBubbles = eventSupported("change");
1102
1293
 
1103
1294
  // release memory in IE
1104
- root = script = div = all = a = null;
1295
+ div = all = a = null;
1105
1296
  })();
1106
1297
 
1107
1298
 
1108
1299
 
1109
- var windowData = {},
1110
- rbrace = /^(?:\{.*\}|\[.*\])$/;
1300
+ var rbrace = /^(?:\{.*\}|\[.*\])$/;
1111
1301
 
1112
1302
  jQuery.extend({
1113
1303
  cache: {},
@@ -1115,8 +1305,9 @@ jQuery.extend({
1115
1305
  // Please use with caution
1116
1306
  uuid: 0,
1117
1307
 
1118
- // Unique for each copy of jQuery on the page
1119
- expando: "jQuery" + jQuery.now(),
1308
+ // Unique for each copy of jQuery on the page
1309
+ // Non-digits removed to match rinlinejQuery
1310
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1120
1311
 
1121
1312
  // The following elements throw uncatchable exceptions if you
1122
1313
  // attempt to add expando properties to them.
@@ -1127,103 +1318,171 @@ jQuery.extend({
1127
1318
  "applet": true
1128
1319
  },
1129
1320
 
1130
- data: function( elem, name, data ) {
1321
+ hasData: function( elem ) {
1322
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1323
+
1324
+ return !!elem && !jQuery.isEmptyObject(elem);
1325
+ },
1326
+
1327
+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1131
1328
  if ( !jQuery.acceptData( elem ) ) {
1132
1329
  return;
1133
1330
  }
1134
1331
 
1135
- elem = elem == window ?
1136
- windowData :
1137
- elem;
1332
+ var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1333
+
1334
+ // We have to handle DOM nodes and JS objects differently because IE6-7
1335
+ // can't GC object references properly across the DOM-JS boundary
1336
+ isNode = elem.nodeType,
1337
+
1338
+ // Only DOM nodes need the global jQuery cache; JS object data is
1339
+ // attached directly to the object so GC can occur automatically
1340
+ cache = isNode ? jQuery.cache : elem,
1138
1341
 
1139
- var isNode = elem.nodeType,
1140
- id = isNode ? elem[ jQuery.expando ] : null,
1141
- cache = jQuery.cache, thisCache;
1342
+ // Only defining an ID for JS objects if its cache already exists allows
1343
+ // the code to shortcut on the same path as a DOM node with no cache
1344
+ id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1142
1345
 
1143
- if ( isNode && !id && typeof name === "string" && data === undefined ) {
1346
+ // Avoid doing any more work than we need to when trying to get data on an
1347
+ // object that has no data at all
1348
+ if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1144
1349
  return;
1145
1350
  }
1146
1351
 
1147
- // Get the data from the object directly
1148
- if ( !isNode ) {
1149
- cache = elem;
1352
+ if ( !id ) {
1353
+ // Only DOM nodes need a new unique ID for each element since their data
1354
+ // ends up in the global cache
1355
+ if ( isNode ) {
1356
+ elem[ jQuery.expando ] = id = ++jQuery.uuid;
1357
+ } else {
1358
+ id = jQuery.expando;
1359
+ }
1360
+ }
1150
1361
 
1151
- // Compute a unique ID for the element
1152
- } else if ( !id ) {
1153
- elem[ jQuery.expando ] = id = ++jQuery.uuid;
1362
+ if ( !cache[ id ] ) {
1363
+ cache[ id ] = {};
1154
1364
  }
1155
1365
 
1156
- // Avoid generating a new cache unless none exists and we
1157
- // want to manipulate it.
1366
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
1367
+ // shallow copied over onto the existing cache
1158
1368
  if ( typeof name === "object" ) {
1159
- if ( isNode ) {
1369
+ if ( pvt ) {
1370
+ cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1371
+ } else {
1160
1372
  cache[ id ] = jQuery.extend(cache[ id ], name);
1373
+ }
1374
+ }
1161
1375
 
1162
- } else {
1163
- jQuery.extend( cache, name );
1376
+ thisCache = cache[ id ];
1377
+
1378
+ // Internal jQuery data is stored in a separate object inside the object's data
1379
+ // cache in order to avoid key collisions between internal data and user-defined
1380
+ // data
1381
+ if ( pvt ) {
1382
+ if ( !thisCache[ internalKey ] ) {
1383
+ thisCache[ internalKey ] = {};
1164
1384
  }
1165
1385
 
1166
- } else if ( isNode && !cache[ id ] ) {
1167
- cache[ id ] = {};
1386
+ thisCache = thisCache[ internalKey ];
1168
1387
  }
1169
1388
 
1170
- thisCache = isNode ? cache[ id ] : cache;
1171
-
1172
- // Prevent overriding the named cache with undefined values
1173
1389
  if ( data !== undefined ) {
1174
1390
  thisCache[ name ] = data;
1175
1391
  }
1176
1392
 
1177
- return typeof name === "string" ? thisCache[ name ] : thisCache;
1393
+ // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1394
+ // not attempt to inspect the internal events object using jQuery.data, as this
1395
+ // internal data object is undocumented and subject to change.
1396
+ if ( name === "events" && !thisCache[name] ) {
1397
+ return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1398
+ }
1399
+
1400
+ return getByName ? thisCache[ name ] : thisCache;
1178
1401
  },
1179
1402
 
1180
- removeData: function( elem, name ) {
1403
+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1181
1404
  if ( !jQuery.acceptData( elem ) ) {
1182
1405
  return;
1183
1406
  }
1184
1407
 
1185
- elem = elem == window ?
1186
- windowData :
1187
- elem;
1408
+ var internalKey = jQuery.expando, isNode = elem.nodeType,
1409
+
1410
+ // See jQuery.data for more information
1411
+ cache = isNode ? jQuery.cache : elem,
1188
1412
 
1189
- var isNode = elem.nodeType,
1190
- id = isNode ? elem[ jQuery.expando ] : elem,
1191
- cache = jQuery.cache,
1192
- thisCache = isNode ? cache[ id ] : id;
1413
+ // See jQuery.data for more information
1414
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1415
+
1416
+ // If there is already no cache entry for this object, there is no
1417
+ // purpose in continuing
1418
+ if ( !cache[ id ] ) {
1419
+ return;
1420
+ }
1193
1421
 
1194
- // If we want to remove a specific section of the element's data
1195
1422
  if ( name ) {
1423
+ var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1424
+
1196
1425
  if ( thisCache ) {
1197
- // Remove the section of cache data
1198
1426
  delete thisCache[ name ];
1199
1427
 
1200
- // If we've removed all the data, remove the element's cache
1201
- if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1202
- jQuery.removeData( elem );
1428
+ // If there is no data left in the cache, we want to continue
1429
+ // and let the cache object itself get destroyed
1430
+ if ( !jQuery.isEmptyObject(thisCache) ) {
1431
+ return;
1203
1432
  }
1204
1433
  }
1434
+ }
1435
+
1436
+ // See jQuery.data for more information
1437
+ if ( pvt ) {
1438
+ delete cache[ id ][ internalKey ];
1439
+
1440
+ // Don't destroy the parent cache unless the internal data object
1441
+ // had been the only thing left in it
1442
+ if ( !jQuery.isEmptyObject(cache[ id ]) ) {
1443
+ return;
1444
+ }
1445
+ }
1205
1446
 
1206
- // Otherwise, we want to remove all of the element's data
1447
+ var internalCache = cache[ id ][ internalKey ];
1448
+
1449
+ // Browsers that fail expando deletion also refuse to delete expandos on
1450
+ // the window, but it will allow it on all other JS objects; other browsers
1451
+ // don't care
1452
+ if ( jQuery.support.deleteExpando || cache != window ) {
1453
+ delete cache[ id ];
1207
1454
  } else {
1208
- if ( isNode && jQuery.support.deleteExpando ) {
1209
- delete elem[ jQuery.expando ];
1455
+ cache[ id ] = null;
1456
+ }
1210
1457
 
1458
+ // We destroyed the entire user cache at once because it's faster than
1459
+ // iterating through each key, but we need to continue to persist internal
1460
+ // data if it existed
1461
+ if ( internalCache ) {
1462
+ cache[ id ] = {};
1463
+ cache[ id ][ internalKey ] = internalCache;
1464
+
1465
+ // Otherwise, we need to eliminate the expando on the node to avoid
1466
+ // false lookups in the cache for entries that no longer exist
1467
+ } else if ( isNode ) {
1468
+ // IE does not allow us to delete expando properties from nodes,
1469
+ // nor does it have a removeAttribute function on Document nodes;
1470
+ // we must handle all of these cases
1471
+ if ( jQuery.support.deleteExpando ) {
1472
+ delete elem[ jQuery.expando ];
1211
1473
  } else if ( elem.removeAttribute ) {
1212
1474
  elem.removeAttribute( jQuery.expando );
1213
-
1214
- // Completely remove the data cache
1215
- } else if ( isNode ) {
1216
- delete cache[ id ];
1217
-
1218
- // Remove all fields from the object
1219
1475
  } else {
1220
- for ( var n in elem ) {
1221
- delete elem[ n ];
1222
- }
1476
+ elem[ jQuery.expando ] = null;
1223
1477
  }
1224
1478
  }
1225
1479
  },
1226
1480
 
1481
+ // For internal use only.
1482
+ _data: function( elem, name, data ) {
1483
+ return jQuery.data( elem, name, data, true );
1484
+ },
1485
+
1227
1486
  // A method for determining if a DOM node can handle the data expando
1228
1487
  acceptData: function( elem ) {
1229
1488
  if ( elem.nodeName ) {
@@ -1244,15 +1503,17 @@ jQuery.fn.extend({
1244
1503
 
1245
1504
  if ( typeof key === "undefined" ) {
1246
1505
  if ( this.length ) {
1247
- var attr = this[0].attributes, name;
1248
1506
  data = jQuery.data( this[0] );
1249
1507
 
1250
- for ( var i = 0, l = attr.length; i < l; i++ ) {
1251
- name = attr[i].name;
1508
+ if ( this[0].nodeType === 1 ) {
1509
+ var attr = this[0].attributes, name;
1510
+ for ( var i = 0, l = attr.length; i < l; i++ ) {
1511
+ name = attr[i].name;
1252
1512
 
1253
- if ( name.indexOf( "data-" ) === 0 ) {
1254
- name = name.substr( 5 );
1255
- dataAttr( this[0], name, data[ name ] );
1513
+ if ( name.indexOf( "data-" ) === 0 ) {
1514
+ name = name.substr( 5 );
1515
+ dataAttr( this[0], name, data[ name ] );
1516
+ }
1256
1517
  }
1257
1518
  }
1258
1519
  }
@@ -1337,7 +1598,7 @@ jQuery.extend({
1337
1598
  }
1338
1599
 
1339
1600
  type = (type || "fx") + "queue";
1340
- var q = jQuery.data( elem, type );
1601
+ var q = jQuery._data( elem, type );
1341
1602
 
1342
1603
  // Speed up dequeue by getting out quickly if this is just a lookup
1343
1604
  if ( !data ) {
@@ -1345,7 +1606,7 @@ jQuery.extend({
1345
1606
  }
1346
1607
 
1347
1608
  if ( !q || jQuery.isArray(data) ) {
1348
- q = jQuery.data( elem, type, jQuery.makeArray(data) );
1609
+ q = jQuery._data( elem, type, jQuery.makeArray(data) );
1349
1610
 
1350
1611
  } else {
1351
1612
  q.push( data );
@@ -1376,6 +1637,10 @@ jQuery.extend({
1376
1637
  jQuery.dequeue(elem, type);
1377
1638
  });
1378
1639
  }
1640
+
1641
+ if ( !queue.length ) {
1642
+ jQuery.removeData( elem, type + "queue", true );
1643
+ }
1379
1644
  }
1380
1645
  });
1381
1646
 
@@ -1425,7 +1690,7 @@ jQuery.fn.extend({
1425
1690
 
1426
1691
 
1427
1692
 
1428
- var rclass = /[\n\t]/g,
1693
+ var rclass = /[\n\t\r]/g,
1429
1694
  rspaces = /\s+/,
1430
1695
  rreturn = /\r/g,
1431
1696
  rspecialurl = /^(?:href|src|style)$/,
@@ -1558,11 +1823,11 @@ jQuery.fn.extend({
1558
1823
  } else if ( type === "undefined" || type === "boolean" ) {
1559
1824
  if ( this.className ) {
1560
1825
  // store className if set
1561
- jQuery.data( this, "__className__", this.className );
1826
+ jQuery._data( this, "__className__", this.className );
1562
1827
  }
1563
1828
 
1564
1829
  // toggle whole className
1565
- this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1830
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
1566
1831
  }
1567
1832
  });
1568
1833
  },
@@ -1607,7 +1872,7 @@ jQuery.fn.extend({
1607
1872
  var option = options[ i ];
1608
1873
 
1609
1874
  // Don't return options that are disabled or in a disabled optgroup
1610
- if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
1875
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
1611
1876
  (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1612
1877
 
1613
1878
  // Get the specific value for the option
@@ -1630,7 +1895,6 @@ jQuery.fn.extend({
1630
1895
  if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1631
1896
  return elem.getAttribute("value") === null ? "on" : elem.value;
1632
1897
  }
1633
-
1634
1898
 
1635
1899
  // Everything else, we just grab the value
1636
1900
  return (elem.value || "").replace(rreturn, "");
@@ -1696,10 +1960,10 @@ jQuery.extend({
1696
1960
  height: true,
1697
1961
  offset: true
1698
1962
  },
1699
-
1963
+
1700
1964
  attr: function( elem, name, value, pass ) {
1701
- // don't set attributes on text and comment nodes
1702
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1965
+ // don't get/set attributes on text, comment and attribute nodes
1966
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
1703
1967
  return undefined;
1704
1968
  }
1705
1969
 
@@ -1714,88 +1978,96 @@ jQuery.extend({
1714
1978
  // Try to normalize/fix the name
1715
1979
  name = notxml && jQuery.props[ name ] || name;
1716
1980
 
1717
- // These attributes require special treatment
1718
- var special = rspecialurl.test( name );
1981
+ // Only do all the following if this is a node (faster for style)
1982
+ if ( elem.nodeType === 1 ) {
1983
+ // These attributes require special treatment
1984
+ var special = rspecialurl.test( name );
1985
+
1986
+ // Safari mis-reports the default selected property of an option
1987
+ // Accessing the parent's selectedIndex property fixes it
1988
+ if ( name === "selected" && !jQuery.support.optSelected ) {
1989
+ var parent = elem.parentNode;
1990
+ if ( parent ) {
1991
+ parent.selectedIndex;
1992
+
1993
+ // Make sure that it also works with optgroups, see #5701
1994
+ if ( parent.parentNode ) {
1995
+ parent.parentNode.selectedIndex;
1996
+ }
1997
+ }
1998
+ }
1999
+
2000
+ // If applicable, access the attribute via the DOM 0 way
2001
+ // 'in' checks fail in Blackberry 4.7 #6931
2002
+ if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
2003
+ if ( set ) {
2004
+ // We can't allow the type property to be changed (since it causes problems in IE)
2005
+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
2006
+ jQuery.error( "type property can't be changed" );
2007
+ }
1719
2008
 
1720
- // Safari mis-reports the default selected property of an option
1721
- // Accessing the parent's selectedIndex property fixes it
1722
- if ( name === "selected" && !jQuery.support.optSelected ) {
1723
- var parent = elem.parentNode;
1724
- if ( parent ) {
1725
- parent.selectedIndex;
2009
+ if ( value === null ) {
2010
+ if ( elem.nodeType === 1 ) {
2011
+ elem.removeAttribute( name );
2012
+ }
1726
2013
 
1727
- // Make sure that it also works with optgroups, see #5701
1728
- if ( parent.parentNode ) {
1729
- parent.parentNode.selectedIndex;
2014
+ } else {
2015
+ elem[ name ] = value;
2016
+ }
1730
2017
  }
1731
- }
1732
- }
1733
2018
 
1734
- // If applicable, access the attribute via the DOM 0 way
1735
- // 'in' checks fail in Blackberry 4.7 #6931
1736
- if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1737
- if ( set ) {
1738
- // We can't allow the type property to be changed (since it causes problems in IE)
1739
- if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1740
- jQuery.error( "type property can't be changed" );
2019
+ // browsers index elements by id/name on forms, give priority to attributes.
2020
+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
2021
+ return elem.getAttributeNode( name ).nodeValue;
1741
2022
  }
1742
2023
 
1743
- if ( value === null ) {
1744
- if ( elem.nodeType === 1 ) {
1745
- elem.removeAttribute( name );
1746
- }
2024
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2025
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2026
+ if ( name === "tabIndex" ) {
2027
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
1747
2028
 
1748
- } else {
1749
- elem[ name ] = value;
2029
+ return attributeNode && attributeNode.specified ?
2030
+ attributeNode.value :
2031
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2032
+ 0 :
2033
+ undefined;
1750
2034
  }
1751
- }
1752
2035
 
1753
- // browsers index elements by id/name on forms, give priority to attributes.
1754
- if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1755
- return elem.getAttributeNode( name ).nodeValue;
2036
+ return elem[ name ];
1756
2037
  }
1757
2038
 
1758
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1759
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1760
- if ( name === "tabIndex" ) {
1761
- var attributeNode = elem.getAttributeNode( "tabIndex" );
2039
+ if ( !jQuery.support.style && notxml && name === "style" ) {
2040
+ if ( set ) {
2041
+ elem.style.cssText = "" + value;
2042
+ }
1762
2043
 
1763
- return attributeNode && attributeNode.specified ?
1764
- attributeNode.value :
1765
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1766
- 0 :
1767
- undefined;
2044
+ return elem.style.cssText;
1768
2045
  }
1769
2046
 
1770
- return elem[ name ];
1771
- }
1772
-
1773
- if ( !jQuery.support.style && notxml && name === "style" ) {
1774
2047
  if ( set ) {
1775
- elem.style.cssText = "" + value;
2048
+ // convert the value to a string (all browsers do this but IE) see #1070
2049
+ elem.setAttribute( name, "" + value );
1776
2050
  }
1777
2051
 
1778
- return elem.style.cssText;
1779
- }
2052
+ // Ensure that missing attributes return undefined
2053
+ // Blackberry 4.7 returns "" from getAttribute #6938
2054
+ if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
2055
+ return undefined;
2056
+ }
1780
2057
 
1781
- if ( set ) {
1782
- // convert the value to a string (all browsers do this but IE) see #1070
1783
- elem.setAttribute( name, "" + value );
1784
- }
2058
+ var attr = !jQuery.support.hrefNormalized && notxml && special ?
2059
+ // Some attributes require a special call on IE
2060
+ elem.getAttribute( name, 2 ) :
2061
+ elem.getAttribute( name );
1785
2062
 
1786
- // Ensure that missing attributes return undefined
1787
- // Blackberry 4.7 returns "" from getAttribute #6938
1788
- if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1789
- return undefined;
2063
+ // Non-existent attributes return null, we normalize to undefined
2064
+ return attr === null ? undefined : attr;
1790
2065
  }
1791
-
1792
- var attr = !jQuery.support.hrefNormalized && notxml && special ?
1793
- // Some attributes require a special call on IE
1794
- elem.getAttribute( name, 2 ) :
1795
- elem.getAttribute( name );
1796
-
1797
- // Non-existent attributes return null, we normalize to undefined
1798
- return attr === null ? undefined : attr;
2066
+ // Handle everything which isn't a DOM element node
2067
+ if ( set ) {
2068
+ elem[ name ] = value;
2069
+ }
2070
+ return elem[ name ];
1799
2071
  }
1800
2072
  });
1801
2073
 
@@ -1810,7 +2082,7 @@ var rnamespaces = /\.(.*)$/,
1810
2082
  fcleanup = function( nm ) {
1811
2083
  return nm.replace(rescape, "\\$&");
1812
2084
  },
1813
- focusCounts = { focusin: 0, focusout: 0 };
2085
+ eventKey = "events";
1814
2086
 
1815
2087
  /*
1816
2088
  * A number of helper functions used for managing events.
@@ -1852,7 +2124,7 @@ jQuery.event = {
1852
2124
  }
1853
2125
 
1854
2126
  // Init the element's event structure
1855
- var elemData = jQuery.data( elem );
2127
+ var elemData = jQuery._data( elem );
1856
2128
 
1857
2129
  // If no elemData is found then we must be trying to bind to one of the
1858
2130
  // banned noData elements
@@ -1860,12 +2132,9 @@ jQuery.event = {
1860
2132
  return;
1861
2133
  }
1862
2134
 
1863
- // Use a key less likely to result in collisions for plain JS objects.
1864
- // Fixes bug #7150.
1865
- var eventKey = elem.nodeType ? "events" : "__events__",
1866
- events = elemData[ eventKey ],
2135
+ var events = elemData[ eventKey ],
1867
2136
  eventHandle = elemData.handle;
1868
-
2137
+
1869
2138
  if ( typeof events === "function" ) {
1870
2139
  // On plain objects events is a fn that holds the the data
1871
2140
  // which prevents this data from being JSON serialized
@@ -1945,9 +2214,9 @@ jQuery.event = {
1945
2214
  }
1946
2215
  }
1947
2216
  }
1948
-
1949
- if ( special.add ) {
1950
- special.add.call( elem, handleObj );
2217
+
2218
+ if ( special.add ) {
2219
+ special.add.call( elem, handleObj );
1951
2220
 
1952
2221
  if ( !handleObj.handler.guid ) {
1953
2222
  handleObj.handler.guid = handler.guid;
@@ -1979,14 +2248,13 @@ jQuery.event = {
1979
2248
  }
1980
2249
 
1981
2250
  var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1982
- eventKey = elem.nodeType ? "events" : "__events__",
1983
- elemData = jQuery.data( elem ),
2251
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
1984
2252
  events = elemData && elemData[ eventKey ];
1985
2253
 
1986
2254
  if ( !elemData || !events ) {
1987
2255
  return;
1988
2256
  }
1989
-
2257
+
1990
2258
  if ( typeof events === "function" ) {
1991
2259
  elemData = events;
1992
2260
  events = events.events;
@@ -2024,7 +2292,7 @@ jQuery.event = {
2024
2292
  namespaces = type.split(".");
2025
2293
  type = namespaces.shift();
2026
2294
 
2027
- namespace = new RegExp("(^|\\.)" +
2295
+ namespace = new RegExp("(^|\\.)" +
2028
2296
  jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2029
2297
  }
2030
2298
 
@@ -2092,10 +2360,10 @@ jQuery.event = {
2092
2360
  delete elemData.handle;
2093
2361
 
2094
2362
  if ( typeof elemData === "function" ) {
2095
- jQuery.removeData( elem, eventKey );
2363
+ jQuery.removeData( elem, eventKey, true );
2096
2364
 
2097
2365
  } else if ( jQuery.isEmptyObject( elemData ) ) {
2098
- jQuery.removeData( elem );
2366
+ jQuery.removeData( elem, undefined, true );
2099
2367
  }
2100
2368
  }
2101
2369
  },
@@ -2127,9 +2395,16 @@ jQuery.event = {
2127
2395
 
2128
2396
  // Only trigger if we've ever bound an event for it
2129
2397
  if ( jQuery.event.global[ type ] ) {
2398
+ // XXX This code smells terrible. event.js should not be directly
2399
+ // inspecting the data cache
2130
2400
  jQuery.each( jQuery.cache, function() {
2131
- if ( this.events && this.events[type] ) {
2132
- jQuery.event.trigger( event, data, this.handle.elem );
2401
+ // internalKey variable is just used to make it easier to find
2402
+ // and potentially change this stuff later; currently it just
2403
+ // points to jQuery.expando
2404
+ var internalKey = jQuery.expando,
2405
+ internalCache = this[ internalKey ];
2406
+ if ( internalCache && internalCache.events && internalCache.events[type] ) {
2407
+ jQuery.event.trigger( event, data, internalCache.handle.elem );
2133
2408
  }
2134
2409
  });
2135
2410
  }
@@ -2155,8 +2430,8 @@ jQuery.event = {
2155
2430
 
2156
2431
  // Trigger the event, it is assumed that "handle" is a function
2157
2432
  var handle = elem.nodeType ?
2158
- jQuery.data( elem, "handle" ) :
2159
- (jQuery.data( elem, "__events__" ) || {}).handle;
2433
+ jQuery._data( elem, "handle" ) :
2434
+ (jQuery._data( elem, eventKey ) || {}).handle;
2160
2435
 
2161
2436
  if ( handle ) {
2162
2437
  handle.apply( elem, data );
@@ -2186,7 +2461,7 @@ jQuery.event = {
2186
2461
  isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
2187
2462
  special = jQuery.event.special[ targetType ] || {};
2188
2463
 
2189
- if ( (!special._default || special._default.call( elem, event ) === false) &&
2464
+ if ( (!special._default || special._default.call( elem, event ) === false) &&
2190
2465
  !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2191
2466
 
2192
2467
  try {
@@ -2234,7 +2509,7 @@ jQuery.event = {
2234
2509
 
2235
2510
  event.namespace = event.namespace || namespace_sort.join(".");
2236
2511
 
2237
- events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2512
+ events = jQuery._data(this, eventKey);
2238
2513
 
2239
2514
  if ( typeof events === "function" ) {
2240
2515
  events = events.events;
@@ -2256,7 +2531,7 @@ jQuery.event = {
2256
2531
  event.handler = handleObj.handler;
2257
2532
  event.data = handleObj.data;
2258
2533
  event.handleObj = handleObj;
2259
-
2534
+
2260
2535
  var ret = handleObj.handler.apply( this, args );
2261
2536
 
2262
2537
  if ( ret !== undefined ) {
@@ -2355,7 +2630,7 @@ jQuery.event = {
2355
2630
  add: function( handleObj ) {
2356
2631
  jQuery.event.add( this,
2357
2632
  liveConvert( handleObj.origType, handleObj.selector ),
2358
- jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2633
+ jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2359
2634
  },
2360
2635
 
2361
2636
  remove: function( handleObj ) {
@@ -2385,7 +2660,7 @@ jQuery.removeEvent = document.removeEventListener ?
2385
2660
  if ( elem.removeEventListener ) {
2386
2661
  elem.removeEventListener( type, handle, false );
2387
2662
  }
2388
- } :
2663
+ } :
2389
2664
  function( elem, type, handle ) {
2390
2665
  if ( elem.detachEvent ) {
2391
2666
  elem.detachEvent( "on" + type, handle );
@@ -2402,6 +2677,12 @@ jQuery.Event = function( src ) {
2402
2677
  if ( src && src.type ) {
2403
2678
  this.originalEvent = src;
2404
2679
  this.type = src.type;
2680
+
2681
+ // Events bubbling up the document may have been marked as prevented
2682
+ // by a handler lower down the tree; reflect the correct value.
2683
+ this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
2684
+ src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
2685
+
2405
2686
  // Event type
2406
2687
  } else {
2407
2688
  this.type = src;
@@ -2432,7 +2713,7 @@ jQuery.Event.prototype = {
2432
2713
  if ( !e ) {
2433
2714
  return;
2434
2715
  }
2435
-
2716
+
2436
2717
  // if preventDefault exists run it on the original event
2437
2718
  if ( e.preventDefault ) {
2438
2719
  e.preventDefault();
@@ -2518,7 +2799,7 @@ if ( !jQuery.support.submitBubbles ) {
2518
2799
 
2519
2800
  jQuery.event.special.submit = {
2520
2801
  setup: function( data, namespaces ) {
2521
- if ( this.nodeName.toLowerCase() !== "form" ) {
2802
+ if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) {
2522
2803
  jQuery.event.add(this, "click.specialSubmit", function( e ) {
2523
2804
  var elem = e.target,
2524
2805
  type = elem.type;
@@ -2528,7 +2809,7 @@ if ( !jQuery.support.submitBubbles ) {
2528
2809
  return trigger( "submit", this, arguments );
2529
2810
  }
2530
2811
  });
2531
-
2812
+
2532
2813
  jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2533
2814
  var elem = e.target,
2534
2815
  type = elem.type;
@@ -2583,14 +2864,14 @@ if ( !jQuery.support.changeBubbles ) {
2583
2864
  return;
2584
2865
  }
2585
2866
 
2586
- data = jQuery.data( elem, "_change_data" );
2867
+ data = jQuery._data( elem, "_change_data" );
2587
2868
  val = getVal(elem);
2588
2869
 
2589
2870
  // the current data will be also retrieved by beforeactivate
2590
2871
  if ( e.type !== "focusout" || elem.type !== "radio" ) {
2591
- jQuery.data( elem, "_change_data", val );
2872
+ jQuery._data( elem, "_change_data", val );
2592
2873
  }
2593
-
2874
+
2594
2875
  if ( data === undefined || val === data ) {
2595
2876
  return;
2596
2877
  }
@@ -2604,7 +2885,7 @@ if ( !jQuery.support.changeBubbles ) {
2604
2885
 
2605
2886
  jQuery.event.special.change = {
2606
2887
  filters: {
2607
- focusout: testChange,
2888
+ focusout: testChange,
2608
2889
 
2609
2890
  beforedeactivate: testChange,
2610
2891
 
@@ -2633,7 +2914,7 @@ if ( !jQuery.support.changeBubbles ) {
2633
2914
  // information
2634
2915
  beforeactivate: function( e ) {
2635
2916
  var elem = e.target;
2636
- jQuery.data( elem, "_change_data", getVal(elem) );
2917
+ jQuery._data( elem, "_change_data", getVal(elem) );
2637
2918
  }
2638
2919
  },
2639
2920
 
@@ -2672,21 +2953,17 @@ if ( document.addEventListener ) {
2672
2953
  jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2673
2954
  jQuery.event.special[ fix ] = {
2674
2955
  setup: function() {
2675
- if ( focusCounts[fix]++ === 0 ) {
2676
- document.addEventListener( orig, handler, true );
2677
- }
2956
+ this.addEventListener( orig, handler, true );
2678
2957
  },
2679
2958
  teardown: function() {
2680
- if ( --focusCounts[fix] === 0 ) {
2681
- document.removeEventListener( orig, handler, true );
2682
- }
2959
+ this.removeEventListener( orig, handler, true );
2683
2960
  }
2684
2961
  };
2685
2962
 
2686
- function handler( e ) {
2963
+ function handler( e ) {
2687
2964
  e = jQuery.event.fix( e );
2688
2965
  e.type = fix;
2689
- return jQuery.event.trigger( e, null, e.target );
2966
+ return jQuery.event.handle.call( this, e );
2690
2967
  }
2691
2968
  });
2692
2969
  }
@@ -2700,7 +2977,7 @@ jQuery.each(["bind", "one"], function( i, name ) {
2700
2977
  }
2701
2978
  return this;
2702
2979
  }
2703
-
2980
+
2704
2981
  if ( jQuery.isFunction( data ) || data === false ) {
2705
2982
  fn = data;
2706
2983
  data = undefined;
@@ -2740,20 +3017,20 @@ jQuery.fn.extend({
2740
3017
 
2741
3018
  return this;
2742
3019
  },
2743
-
3020
+
2744
3021
  delegate: function( selector, types, data, fn ) {
2745
3022
  return this.live( types, data, fn, selector );
2746
3023
  },
2747
-
3024
+
2748
3025
  undelegate: function( selector, types, fn ) {
2749
3026
  if ( arguments.length === 0 ) {
2750
3027
  return this.unbind( "live" );
2751
-
3028
+
2752
3029
  } else {
2753
3030
  return this.die( types, null, fn, selector );
2754
3031
  }
2755
3032
  },
2756
-
3033
+
2757
3034
  trigger: function( type, data ) {
2758
3035
  return this.each(function() {
2759
3036
  jQuery.event.trigger( type, data, this );
@@ -2782,8 +3059,8 @@ jQuery.fn.extend({
2782
3059
 
2783
3060
  return this.click( jQuery.proxy( fn, function( event ) {
2784
3061
  // Figure out which function to execute
2785
- var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2786
- jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3062
+ var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3063
+ jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2787
3064
 
2788
3065
  // Make sure that clicks stop
2789
3066
  event.preventDefault();
@@ -2810,12 +3087,12 @@ jQuery.each(["live", "die"], function( i, name ) {
2810
3087
  var type, i = 0, match, namespaces, preType,
2811
3088
  selector = origSelector || this.selector,
2812
3089
  context = origSelector ? this : jQuery( this.context );
2813
-
3090
+
2814
3091
  if ( typeof types === "object" && !types.preventDefault ) {
2815
3092
  for ( var key in types ) {
2816
3093
  context[ name ]( key, data, types[key], selector );
2817
3094
  }
2818
-
3095
+
2819
3096
  return this;
2820
3097
  }
2821
3098
 
@@ -2862,7 +3139,7 @@ jQuery.each(["live", "die"], function( i, name ) {
2862
3139
  context.unbind( "live." + liveConvert( type, selector ), fn );
2863
3140
  }
2864
3141
  }
2865
-
3142
+
2866
3143
  return this;
2867
3144
  };
2868
3145
  });
@@ -2871,17 +3148,17 @@ function liveHandler( event ) {
2871
3148
  var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
2872
3149
  elems = [],
2873
3150
  selectors = [],
2874
- events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
3151
+ events = jQuery._data( this, eventKey );
2875
3152
 
2876
3153
  if ( typeof events === "function" ) {
2877
3154
  events = events.events;
2878
3155
  }
2879
3156
 
2880
- // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2881
- if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
3157
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3158
+ if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
2882
3159
  return;
2883
3160
  }
2884
-
3161
+
2885
3162
  if ( event.namespace ) {
2886
3163
  namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
2887
3164
  }
@@ -2979,27 +3256,10 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
2979
3256
  }
2980
3257
  });
2981
3258
 
2982
- // Prevent memory leaks in IE
2983
- // Window isn't included so as not to unbind existing unload events
2984
- // More info:
2985
- // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2986
- if ( window.attachEvent && !window.addEventListener ) {
2987
- jQuery(window).bind("unload", function() {
2988
- for ( var id in jQuery.cache ) {
2989
- if ( jQuery.cache[ id ].handle ) {
2990
- // Try/Catch is to handle iframes being unloaded, see #4280
2991
- try {
2992
- jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2993
- } catch(e) {}
2994
- }
2995
- }
2996
- });
2997
- }
2998
-
2999
3259
 
3000
3260
  /*!
3001
- * Sizzle CSS Selector Engine - v1.0
3002
- * Copyright 2009, The Dojo Foundation
3261
+ * Sizzle CSS Selector Engine
3262
+ * Copyright 2011, The Dojo Foundation
3003
3263
  * Released under the MIT, BSD, and GPL Licenses.
3004
3264
  * More information: http://sizzlejs.com/
3005
3265
  */
@@ -3220,7 +3480,9 @@ Sizzle.find = function( expr, context, isXML ) {
3220
3480
  }
3221
3481
 
3222
3482
  if ( !set ) {
3223
- set = context.getElementsByTagName( "*" );
3483
+ set = typeof context.getElementsByTagName !== "undefined" ?
3484
+ context.getElementsByTagName( "*" ) :
3485
+ [];
3224
3486
  }
3225
3487
 
3226
3488
  return { set: set, expr: expr };
@@ -3328,9 +3590,9 @@ var Expr = Sizzle.selectors = {
3328
3590
  ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3329
3591
  CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3330
3592
  NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3331
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3593
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
3332
3594
  TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3333
- CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
3595
+ CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
3334
3596
  POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3335
3597
  PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3336
3598
  },
@@ -3463,7 +3725,9 @@ var Expr = Sizzle.selectors = {
3463
3725
  },
3464
3726
 
3465
3727
  TAG: function( match, context ) {
3466
- return context.getElementsByTagName( match[1] );
3728
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
3729
+ return context.getElementsByTagName( match[1] );
3730
+ }
3467
3731
  }
3468
3732
  },
3469
3733
  preFilter: {
@@ -3476,7 +3740,7 @@ var Expr = Sizzle.selectors = {
3476
3740
 
3477
3741
  for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3478
3742
  if ( elem ) {
3479
- if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3743
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
3480
3744
  if ( !inplace ) {
3481
3745
  result.push( elem );
3482
3746
  }
@@ -3500,8 +3764,14 @@ var Expr = Sizzle.selectors = {
3500
3764
 
3501
3765
  CHILD: function( match ) {
3502
3766
  if ( match[1] === "nth" ) {
3767
+ if ( !match[2] ) {
3768
+ Sizzle.error( match[0] );
3769
+ }
3770
+
3771
+ match[2] = match[2].replace(/^\+|\s*/g, '');
3772
+
3503
3773
  // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3504
- var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3774
+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
3505
3775
  match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3506
3776
  !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3507
3777
 
@@ -3509,6 +3779,9 @@ var Expr = Sizzle.selectors = {
3509
3779
  match[2] = (test[1] + (test[2] || 1)) - 0;
3510
3780
  match[3] = test[3] - 0;
3511
3781
  }
3782
+ else if ( match[2] ) {
3783
+ Sizzle.error( match[0] );
3784
+ }
3512
3785
 
3513
3786
  // TODO: Move to normal caching system
3514
3787
  match[0] = done++;
@@ -3517,12 +3790,15 @@ var Expr = Sizzle.selectors = {
3517
3790
  },
3518
3791
 
3519
3792
  ATTR: function( match, curLoop, inplace, result, not, isXML ) {
3520
- var name = match[1].replace(/\\/g, "");
3793
+ var name = match[1] = match[1].replace(/\\/g, "");
3521
3794
 
3522
3795
  if ( !isXML && Expr.attrMap[name] ) {
3523
3796
  match[1] = Expr.attrMap[name];
3524
3797
  }
3525
3798
 
3799
+ // Handle if an un-quoted value was used
3800
+ match[4] = ( match[4] || match[5] || "" ).replace(/\\/g, "");
3801
+
3526
3802
  if ( match[2] === "~=" ) {
3527
3803
  match[4] = " " + match[4] + " ";
3528
3804
  }
@@ -3691,7 +3967,7 @@ var Expr = Sizzle.selectors = {
3691
3967
  return true;
3692
3968
 
3693
3969
  } else {
3694
- Sizzle.error( "Syntax error, unrecognized expression: " + name );
3970
+ Sizzle.error( name );
3695
3971
  }
3696
3972
  },
3697
3973
 
@@ -4081,13 +4357,47 @@ if ( document.querySelectorAll ) {
4081
4357
  Sizzle = function( query, context, extra, seed ) {
4082
4358
  context = context || document;
4083
4359
 
4084
- // Make sure that attribute selectors are quoted
4085
- query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4086
-
4087
4360
  // Only use querySelectorAll on non-XML documents
4088
4361
  // (ID selectors don't work in non-HTML documents)
4089
4362
  if ( !seed && !Sizzle.isXML(context) ) {
4363
+ // See if we find a selector to speed up
4364
+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4365
+
4366
+ if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4367
+ // Speed-up: Sizzle("TAG")
4368
+ if ( match[1] ) {
4369
+ return makeArray( context.getElementsByTagName( query ), extra );
4370
+
4371
+ // Speed-up: Sizzle(".CLASS")
4372
+ } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4373
+ return makeArray( context.getElementsByClassName( match[2] ), extra );
4374
+ }
4375
+ }
4376
+
4090
4377
  if ( context.nodeType === 9 ) {
4378
+ // Speed-up: Sizzle("body")
4379
+ // The body element only exists once, optimize finding it
4380
+ if ( query === "body" && context.body ) {
4381
+ return makeArray( [ context.body ], extra );
4382
+
4383
+ // Speed-up: Sizzle("#ID")
4384
+ } else if ( match && match[3] ) {
4385
+ var elem = context.getElementById( match[3] );
4386
+
4387
+ // Check parentNode to catch when Blackberry 4.6 returns
4388
+ // nodes that are no longer in the document #6963
4389
+ if ( elem && elem.parentNode ) {
4390
+ // Handle the case where IE and Opera return items
4391
+ // by name instead of ID
4392
+ if ( elem.id === match[3] ) {
4393
+ return makeArray( [ elem ], extra );
4394
+ }
4395
+
4396
+ } else {
4397
+ return makeArray( [], extra );
4398
+ }
4399
+ }
4400
+
4091
4401
  try {
4092
4402
  return makeArray( context.querySelectorAll(query), extra );
4093
4403
  } catch(qsaError) {}
@@ -4098,14 +4408,23 @@ if ( document.querySelectorAll ) {
4098
4408
  // IE 8 doesn't work on object elements
4099
4409
  } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4100
4410
  var old = context.getAttribute( "id" ),
4101
- nid = old || id;
4411
+ nid = old || id,
4412
+ hasParent = context.parentNode,
4413
+ relativeHierarchySelector = /^\s*[+~]/.test( query );
4102
4414
 
4103
4415
  if ( !old ) {
4104
4416
  context.setAttribute( "id", nid );
4417
+ } else {
4418
+ nid = nid.replace( /'/g, "\\$&" );
4419
+ }
4420
+ if ( relativeHierarchySelector && hasParent ) {
4421
+ context = context.parentNode;
4105
4422
  }
4106
4423
 
4107
4424
  try {
4108
- return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
4425
+ if ( !relativeHierarchySelector || hasParent ) {
4426
+ return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4427
+ }
4109
4428
 
4110
4429
  } catch(pseudoError) {
4111
4430
  } finally {
@@ -4328,7 +4647,14 @@ var runtil = /Until$/,
4328
4647
  rmultiselector = /,/,
4329
4648
  isSimple = /^.[^:#\[\.,]*$/,
4330
4649
  slice = Array.prototype.slice,
4331
- POS = jQuery.expr.match.POS;
4650
+ POS = jQuery.expr.match.POS,
4651
+ // methods guaranteed to produce a unique set when starting from a unique set
4652
+ guaranteedUnique = {
4653
+ children: true,
4654
+ contents: true,
4655
+ next: true,
4656
+ prev: true
4657
+ };
4332
4658
 
4333
4659
  jQuery.fn.extend({
4334
4660
  find: function( selector ) {
@@ -4373,7 +4699,7 @@ jQuery.fn.extend({
4373
4699
  filter: function( selector ) {
4374
4700
  return this.pushStack( winnow(this, selector, true), "filter", selector );
4375
4701
  },
4376
-
4702
+
4377
4703
  is: function( selector ) {
4378
4704
  return !!selector && jQuery.filter( selector, this ).length > 0;
4379
4705
  },
@@ -4391,7 +4717,7 @@ jQuery.fn.extend({
4391
4717
  selector = selectors[i];
4392
4718
 
4393
4719
  if ( !matches[selector] ) {
4394
- matches[selector] = jQuery.expr.match.POS.test( selector ) ?
4720
+ matches[selector] = jQuery.expr.match.POS.test( selector ) ?
4395
4721
  jQuery( selector, context || this.context ) :
4396
4722
  selector;
4397
4723
  }
@@ -4414,7 +4740,7 @@ jQuery.fn.extend({
4414
4740
  return ret;
4415
4741
  }
4416
4742
 
4417
- var pos = POS.test( selectors ) ?
4743
+ var pos = POS.test( selectors ) ?
4418
4744
  jQuery( selectors, context || this.context ) : null;
4419
4745
 
4420
4746
  for ( i = 0, l = this.length; i < l; i++ ) {
@@ -4435,10 +4761,10 @@ jQuery.fn.extend({
4435
4761
  }
4436
4762
 
4437
4763
  ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4438
-
4764
+
4439
4765
  return this.pushStack( ret, "closest", selectors );
4440
4766
  },
4441
-
4767
+
4442
4768
  // Determine the position of an element within
4443
4769
  // the matched set of elements
4444
4770
  index: function( elem ) {
@@ -4456,7 +4782,7 @@ jQuery.fn.extend({
4456
4782
 
4457
4783
  add: function( selector, context ) {
4458
4784
  var set = typeof selector === "string" ?
4459
- jQuery( selector, context || this.context ) :
4785
+ jQuery( selector, context ) :
4460
4786
  jQuery.makeArray( selector ),
4461
4787
  all = jQuery.merge( this.get(), set );
4462
4788
 
@@ -4518,8 +4844,13 @@ jQuery.each({
4518
4844
  }
4519
4845
  }, function( name, fn ) {
4520
4846
  jQuery.fn[ name ] = function( until, selector ) {
4521
- var ret = jQuery.map( this, fn, until );
4522
-
4847
+ var ret = jQuery.map( this, fn, until ),
4848
+ // The variable 'args' was introduced in
4849
+ // https://github.com/jquery/jquery/commit/52a0238
4850
+ // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
4851
+ // http://code.google.com/p/v8/issues/detail?id=1050
4852
+ args = slice.call(arguments);
4853
+
4523
4854
  if ( !runtil.test( name ) ) {
4524
4855
  selector = until;
4525
4856
  }
@@ -4528,13 +4859,13 @@ jQuery.each({
4528
4859
  ret = jQuery.filter( selector, ret );
4529
4860
  }
4530
4861
 
4531
- ret = this.length > 1 ? jQuery.unique( ret ) : ret;
4862
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
4532
4863
 
4533
4864
  if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4534
4865
  ret = ret.reverse();
4535
4866
  }
4536
4867
 
4537
- return this.pushStack( ret, name, slice.call(arguments).join(",") );
4868
+ return this.pushStack( ret, name, args.join(",") );
4538
4869
  };
4539
4870
  });
4540
4871
 
@@ -4548,7 +4879,7 @@ jQuery.extend({
4548
4879
  jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4549
4880
  jQuery.find.matches(expr, elems);
4550
4881
  },
4551
-
4882
+
4552
4883
  dir: function( elem, dir, until ) {
4553
4884
  var matched = [],
4554
4885
  cur = elem[ dir ];
@@ -4630,7 +4961,6 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4630
4961
  rnocache = /<(?:script|object|embed|option|style)/i,
4631
4962
  // checked="checked" or checked (html5)
4632
4963
  rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4633
- raction = /\=([^="'>\s]+\/)>/g,
4634
4964
  wrapMap = {
4635
4965
  option: [ 1, "<select multiple='multiple'>", "</select>" ],
4636
4966
  legend: [ 1, "<fieldset>", "</fieldset>" ],
@@ -4770,7 +5100,7 @@ jQuery.fn.extend({
4770
5100
  return set;
4771
5101
  }
4772
5102
  },
4773
-
5103
+
4774
5104
  // keepData is for internal use only--do not document
4775
5105
  remove: function( selector, keepData ) {
4776
5106
  for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
@@ -4785,7 +5115,7 @@ jQuery.fn.extend({
4785
5115
  }
4786
5116
  }
4787
5117
  }
4788
-
5118
+
4789
5119
  return this;
4790
5120
  },
4791
5121
 
@@ -4801,48 +5131,17 @@ jQuery.fn.extend({
4801
5131
  elem.removeChild( elem.firstChild );
4802
5132
  }
4803
5133
  }
4804
-
5134
+
4805
5135
  return this;
4806
5136
  },
4807
5137
 
4808
- clone: function( events ) {
4809
- // Do the clone
4810
- var ret = this.map(function() {
4811
- if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4812
- // IE copies events bound via attachEvent when
4813
- // using cloneNode. Calling detachEvent on the
4814
- // clone will also remove the events from the orignal
4815
- // In order to get around this, we use innerHTML.
4816
- // Unfortunately, this means some modifications to
4817
- // attributes in IE that are actually only stored
4818
- // as properties will not be copied (such as the
4819
- // the name attribute on an input).
4820
- var html = this.outerHTML,
4821
- ownerDocument = this.ownerDocument;
4822
-
4823
- if ( !html ) {
4824
- var div = ownerDocument.createElement("div");
4825
- div.appendChild( this.cloneNode(true) );
4826
- html = div.innerHTML;
4827
- }
4828
-
4829
- return jQuery.clean([html.replace(rinlinejQuery, "")
4830
- // Handle the case in IE 8 where action=/test/> self-closes a tag
4831
- .replace(raction, '="$1">')
4832
- .replace(rleadingWhitespace, "")], ownerDocument)[0];
4833
- } else {
4834
- return this.cloneNode(true);
4835
- }
4836
- });
5138
+ clone: function( dataAndEvents, deepDataAndEvents ) {
5139
+ dataAndEvents = dataAndEvents == null ? true : dataAndEvents;
5140
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
4837
5141
 
4838
- // Copy the events from the original to the clone
4839
- if ( events === true ) {
4840
- cloneCopyEvent( this, ret );
4841
- cloneCopyEvent( this.find("*"), ret.find("*") );
4842
- }
4843
-
4844
- // Return the cloned set
4845
- return ret;
5142
+ return this.map( function () {
5143
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5144
+ });
4846
5145
  },
4847
5146
 
4848
5147
  html: function( value ) {
@@ -4952,9 +5251,9 @@ jQuery.fn.extend({
4952
5251
  } else {
4953
5252
  results = jQuery.buildFragment( args, this, scripts );
4954
5253
  }
4955
-
5254
+
4956
5255
  fragment = results.fragment;
4957
-
5256
+
4958
5257
  if ( fragment.childNodes.length === 1 ) {
4959
5258
  first = fragment = fragment.firstChild;
4960
5259
  } else {
@@ -4964,13 +5263,20 @@ jQuery.fn.extend({
4964
5263
  if ( first ) {
4965
5264
  table = table && jQuery.nodeName( first, "tr" );
4966
5265
 
4967
- for ( var i = 0, l = this.length; i < l; i++ ) {
5266
+ for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
4968
5267
  callback.call(
4969
5268
  table ?
4970
5269
  root(this[i], first) :
4971
5270
  this[i],
4972
- i > 0 || results.cacheable || this.length > 1 ?
4973
- fragment.cloneNode(true) :
5271
+ // Make sure that we do not leak memory by inadvertently discarding
5272
+ // the original fragment (which might have attached data) instead of
5273
+ // using it; in addition, use the original fragment object for the last
5274
+ // item instead of first because it can end up being emptied incorrectly
5275
+ // in certain situations (Bug #8070).
5276
+ // Fragments from the fragment cache must always be cloned and never used
5277
+ // in place.
5278
+ results.cacheable || (l > 1 && i < lastIndex) ?
5279
+ jQuery.clone( fragment, true, true ) :
4974
5280
  fragment
4975
5281
  );
4976
5282
  }
@@ -4992,41 +5298,97 @@ function root( elem, cur ) {
4992
5298
  elem;
4993
5299
  }
4994
5300
 
4995
- function cloneCopyEvent(orig, ret) {
4996
- var i = 0;
5301
+ function cloneCopyEvent( src, dest ) {
4997
5302
 
4998
- ret.each(function() {
4999
- if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
5000
- return;
5001
- }
5303
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5304
+ return;
5305
+ }
5002
5306
 
5003
- var oldData = jQuery.data( orig[i++] ),
5004
- curData = jQuery.data( this, oldData ),
5005
- events = oldData && oldData.events;
5307
+ var internalKey = jQuery.expando,
5308
+ oldData = jQuery.data( src ),
5309
+ curData = jQuery.data( dest, oldData );
5310
+
5311
+ // Switch to use the internal data object, if it exists, for the next
5312
+ // stage of data copying
5313
+ if ( (oldData = oldData[ internalKey ]) ) {
5314
+ var events = oldData.events;
5315
+ curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5006
5316
 
5007
5317
  if ( events ) {
5008
5318
  delete curData.handle;
5009
5319
  curData.events = {};
5010
5320
 
5011
5321
  for ( var type in events ) {
5012
- for ( var handler in events[ type ] ) {
5013
- jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
5322
+ for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5323
+ jQuery.event.add( dest, type, events[ type ][ i ], events[ type ][ i ].data );
5014
5324
  }
5015
5325
  }
5016
5326
  }
5017
- });
5327
+ }
5328
+ }
5329
+
5330
+ function cloneFixAttributes(src, dest) {
5331
+ // We do not need to do anything for non-Elements
5332
+ if ( dest.nodeType !== 1 ) {
5333
+ return;
5334
+ }
5335
+
5336
+ var nodeName = dest.nodeName.toLowerCase();
5337
+
5338
+ // clearAttributes removes the attributes, which we don't want,
5339
+ // but also removes the attachEvent events, which we *do* want
5340
+ dest.clearAttributes();
5341
+
5342
+ // mergeAttributes, in contrast, only merges back on the
5343
+ // original attributes, not the events
5344
+ dest.mergeAttributes(src);
5345
+
5346
+ // IE6-8 fail to clone children inside object elements that use
5347
+ // the proprietary classid attribute value (rather than the type
5348
+ // attribute) to identify the type of content to display
5349
+ if ( nodeName === "object" ) {
5350
+ dest.outerHTML = src.outerHTML;
5351
+
5352
+ } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5353
+ // IE6-8 fails to persist the checked state of a cloned checkbox
5354
+ // or radio button. Worse, IE6-7 fail to give the cloned element
5355
+ // a checked appearance if the defaultChecked value isn't also set
5356
+ if ( src.checked ) {
5357
+ dest.defaultChecked = dest.checked = src.checked;
5358
+ }
5359
+
5360
+ // IE6-7 get confused and end up setting the value of a cloned
5361
+ // checkbox/radio button to an empty string instead of "on"
5362
+ if ( dest.value !== src.value ) {
5363
+ dest.value = src.value;
5364
+ }
5365
+
5366
+ // IE6-8 fails to return the selected option to the default selected
5367
+ // state when cloning options
5368
+ } else if ( nodeName === "option" ) {
5369
+ dest.selected = src.defaultSelected;
5370
+
5371
+ // IE6-8 fails to set the defaultValue to the correct value when
5372
+ // cloning other types of input fields
5373
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
5374
+ dest.defaultValue = src.defaultValue;
5375
+ }
5376
+
5377
+ // Event data gets referenced instead of copied if the expando
5378
+ // gets copied too
5379
+ dest.removeAttribute( jQuery.expando );
5018
5380
  }
5019
5381
 
5020
5382
  jQuery.buildFragment = function( args, nodes, scripts ) {
5021
5383
  var fragment, cacheable, cacheresults,
5022
5384
  doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5023
5385
 
5024
- // Only cache "small" (1/2 KB) strings that are associated with the main document
5386
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5025
5387
  // Cloning options loses the selected state, so don't cache them
5026
5388
  // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5027
5389
  // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5028
5390
  if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5029
- !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5391
+ args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5030
5392
 
5031
5393
  cacheable = true;
5032
5394
  cacheresults = jQuery.fragments[ args[0] ];
@@ -5062,24 +5424,72 @@ jQuery.each({
5062
5424
  var ret = [],
5063
5425
  insert = jQuery( selector ),
5064
5426
  parent = this.length === 1 && this[0].parentNode;
5065
-
5427
+
5066
5428
  if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5067
5429
  insert[ original ]( this[0] );
5068
5430
  return this;
5069
-
5431
+
5070
5432
  } else {
5071
5433
  for ( var i = 0, l = insert.length; i < l; i++ ) {
5072
5434
  var elems = (i > 0 ? this.clone(true) : this).get();
5073
5435
  jQuery( insert[i] )[ original ]( elems );
5074
5436
  ret = ret.concat( elems );
5075
5437
  }
5076
-
5438
+
5077
5439
  return this.pushStack( ret, name, insert.selector );
5078
5440
  }
5079
5441
  };
5080
5442
  });
5081
5443
 
5082
5444
  jQuery.extend({
5445
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5446
+ var clone = elem.cloneNode(true),
5447
+ srcElements,
5448
+ destElements,
5449
+ i;
5450
+
5451
+ if ( !jQuery.support.noCloneEvent && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5452
+ // IE copies events bound via attachEvent when using cloneNode.
5453
+ // Calling detachEvent on the clone will also remove the events
5454
+ // from the original. In order to get around this, we use some
5455
+ // proprietary methods to clear the events. Thanks to MooTools
5456
+ // guys for this hotness.
5457
+
5458
+ // Using Sizzle here is crazy slow, so we use getElementsByTagName
5459
+ // instead
5460
+ srcElements = elem.getElementsByTagName("*");
5461
+ destElements = clone.getElementsByTagName("*");
5462
+
5463
+ // Weird iteration because IE will replace the length property
5464
+ // with an element if you are cloning the body and one of the
5465
+ // elements on the page has a name or id of "length"
5466
+ for ( i = 0; srcElements[i]; ++i ) {
5467
+ cloneFixAttributes( srcElements[i], destElements[i] );
5468
+ }
5469
+
5470
+ cloneFixAttributes( elem, clone );
5471
+ }
5472
+
5473
+ // Copy the events from the original to the clone
5474
+ if ( dataAndEvents ) {
5475
+
5476
+ cloneCopyEvent( elem, clone );
5477
+
5478
+ if ( deepDataAndEvents && "getElementsByTagName" in elem ) {
5479
+
5480
+ srcElements = elem.getElementsByTagName("*");
5481
+ destElements = clone.getElementsByTagName("*");
5482
+
5483
+ if ( srcElements.length ) {
5484
+ for ( i = 0; srcElements[i]; ++i ) {
5485
+ cloneCopyEvent( srcElements[i], destElements[i] );
5486
+ }
5487
+ }
5488
+ }
5489
+ }
5490
+ // Return the cloned set
5491
+ return clone;
5492
+ },
5083
5493
  clean: function( elems, context, fragment, scripts ) {
5084
5494
  context = context || document;
5085
5495
 
@@ -5161,7 +5571,7 @@ jQuery.extend({
5161
5571
  for ( i = 0; ret[i]; i++ ) {
5162
5572
  if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
5163
5573
  scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
5164
-
5574
+
5165
5575
  } else {
5166
5576
  if ( ret[i].nodeType === 1 ) {
5167
5577
  ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
@@ -5173,40 +5583,45 @@ jQuery.extend({
5173
5583
 
5174
5584
  return ret;
5175
5585
  },
5176
-
5586
+
5177
5587
  cleanData: function( elems ) {
5178
- var data, id, cache = jQuery.cache,
5179
- special = jQuery.event.special,
5588
+ var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
5180
5589
  deleteExpando = jQuery.support.deleteExpando;
5181
-
5590
+
5182
5591
  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5183
5592
  if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
5184
5593
  continue;
5185
5594
  }
5186
5595
 
5187
5596
  id = elem[ jQuery.expando ];
5188
-
5597
+
5189
5598
  if ( id ) {
5190
- data = cache[ id ];
5191
-
5599
+ data = cache[ id ] && cache[ id ][ internalKey ];
5600
+
5192
5601
  if ( data && data.events ) {
5193
5602
  for ( var type in data.events ) {
5194
5603
  if ( special[ type ] ) {
5195
5604
  jQuery.event.remove( elem, type );
5196
5605
 
5606
+ // This is a shortcut to avoid jQuery.event.remove's overhead
5197
5607
  } else {
5198
5608
  jQuery.removeEvent( elem, type, data.handle );
5199
5609
  }
5200
5610
  }
5611
+
5612
+ // Null the DOM reference to avoid IE6/7/8 leak (#7054)
5613
+ if ( data.handle ) {
5614
+ data.handle.elem = null;
5615
+ }
5201
5616
  }
5202
-
5617
+
5203
5618
  if ( deleteExpando ) {
5204
5619
  delete elem[ jQuery.expando ];
5205
5620
 
5206
5621
  } else if ( elem.removeAttribute ) {
5207
5622
  elem.removeAttribute( jQuery.expando );
5208
5623
  }
5209
-
5624
+
5210
5625
  delete cache[ id ];
5211
5626
  }
5212
5627
  }
@@ -5495,8 +5910,9 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) {
5495
5910
 
5496
5911
  if ( document.documentElement.currentStyle ) {
5497
5912
  currentStyle = function( elem, name ) {
5498
- var left, rsLeft,
5913
+ var left,
5499
5914
  ret = elem.currentStyle && elem.currentStyle[ name ],
5915
+ rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
5500
5916
  style = elem.style;
5501
5917
 
5502
5918
  // From the awesome hack by Dean Edwards
@@ -5507,16 +5923,19 @@ if ( document.documentElement.currentStyle ) {
5507
5923
  if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5508
5924
  // Remember the original values
5509
5925
  left = style.left;
5510
- rsLeft = elem.runtimeStyle.left;
5511
5926
 
5512
5927
  // Put in the new values to get a computed value out
5513
- elem.runtimeStyle.left = elem.currentStyle.left;
5928
+ if ( rsLeft ) {
5929
+ elem.runtimeStyle.left = elem.currentStyle.left;
5930
+ }
5514
5931
  style.left = name === "fontSize" ? "1em" : (ret || 0);
5515
5932
  ret = style.pixelLeft + "px";
5516
5933
 
5517
5934
  // Revert the changed values
5518
5935
  style.left = left;
5519
- elem.runtimeStyle.left = rsLeft;
5936
+ if ( rsLeft ) {
5937
+ elem.runtimeStyle.left = rsLeft;
5938
+ }
5520
5939
  }
5521
5940
 
5522
5941
  return ret === "" ? "auto" : ret;
@@ -5565,21 +5984,117 @@ if ( jQuery.expr && jQuery.expr.filters ) {
5565
5984
 
5566
5985
 
5567
5986
 
5568
- var jsc = jQuery.now(),
5569
- rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5570
- rselectTextarea = /^(?:select|textarea)/i,
5987
+ var r20 = /%20/g,
5988
+ rbracket = /\[\]$/,
5989
+ rCRLF = /\r?\n/g,
5990
+ rhash = /#.*$/,
5991
+ rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL
5571
5992
  rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5572
5993
  rnoContent = /^(?:GET|HEAD)$/,
5573
- rbracket = /\[\]$/,
5574
- jsre = /\=\?(&|$)/,
5994
+ rprotocol = /^\/\//,
5575
5995
  rquery = /\?/,
5996
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5997
+ rselectTextarea = /^(?:select|textarea)/i,
5998
+ rspacesAjax = /\s+/,
5576
5999
  rts = /([?&])_=[^&]*/,
5577
- rurl = /^(\w+:)?\/\/([^\/?#]+)/,
5578
- r20 = /%20/g,
5579
- rhash = /#.*$/,
6000
+ rurl = /^(\w+:)\/\/([^\/?#:]+)(?::(\d+))?/,
5580
6001
 
5581
6002
  // Keep a copy of the old load method
5582
- _load = jQuery.fn.load;
6003
+ _load = jQuery.fn.load,
6004
+
6005
+ /* Prefilters
6006
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6007
+ * 2) These are called:
6008
+ * - BEFORE asking for a transport
6009
+ * - AFTER param serialization (s.data is a string if s.processData is true)
6010
+ * 3) key is the dataType
6011
+ * 4) the catchall symbol "*" can be used
6012
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6013
+ */
6014
+ prefilters = {},
6015
+
6016
+ /* Transports bindings
6017
+ * 1) key is the dataType
6018
+ * 2) the catchall symbol "*" can be used
6019
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
6020
+ */
6021
+ transports = {};
6022
+
6023
+ // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6024
+ function addToPrefiltersOrTransports( structure ) {
6025
+
6026
+ // dataTypeExpression is optional and defaults to "*"
6027
+ return function( dataTypeExpression, func ) {
6028
+
6029
+ if ( typeof dataTypeExpression !== "string" ) {
6030
+ func = dataTypeExpression;
6031
+ dataTypeExpression = "*";
6032
+ }
6033
+
6034
+ if ( jQuery.isFunction( func ) ) {
6035
+ var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6036
+ i = 0,
6037
+ length = dataTypes.length,
6038
+ dataType,
6039
+ list,
6040
+ placeBefore;
6041
+
6042
+ // For each dataType in the dataTypeExpression
6043
+ for(; i < length; i++ ) {
6044
+ dataType = dataTypes[ i ];
6045
+ // We control if we're asked to add before
6046
+ // any existing element
6047
+ placeBefore = /^\+/.test( dataType );
6048
+ if ( placeBefore ) {
6049
+ dataType = dataType.substr( 1 ) || "*";
6050
+ }
6051
+ list = structure[ dataType ] = structure[ dataType ] || [];
6052
+ // then we add to the structure accordingly
6053
+ list[ placeBefore ? "unshift" : "push" ]( func );
6054
+ }
6055
+ }
6056
+ };
6057
+ }
6058
+
6059
+ //Base inspection function for prefilters and transports
6060
+ function inspectPrefiltersOrTransports( structure, options, originalOptions, jXHR,
6061
+ dataType /* internal */, inspected /* internal */ ) {
6062
+
6063
+ dataType = dataType || options.dataTypes[ 0 ];
6064
+ inspected = inspected || {};
6065
+
6066
+ inspected[ dataType ] = true;
6067
+
6068
+ var list = structure[ dataType ],
6069
+ i = 0,
6070
+ length = list ? list.length : 0,
6071
+ executeOnly = ( structure === prefilters ),
6072
+ selection;
6073
+
6074
+ for(; i < length && ( executeOnly || !selection ); i++ ) {
6075
+ selection = list[ i ]( options, originalOptions, jXHR );
6076
+ // If we got redirected to another dataType
6077
+ // we try there if not done already
6078
+ if ( typeof selection === "string" ) {
6079
+ if ( inspected[ selection ] ) {
6080
+ selection = undefined;
6081
+ } else {
6082
+ options.dataTypes.unshift( selection );
6083
+ selection = inspectPrefiltersOrTransports(
6084
+ structure, options, originalOptions, jXHR, selection, inspected );
6085
+ }
6086
+ }
6087
+ }
6088
+ // If we're only executing or nothing was selected
6089
+ // we try the catchall dataType if not done already
6090
+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6091
+ selection = inspectPrefiltersOrTransports(
6092
+ structure, options, originalOptions, jXHR, "*", inspected );
6093
+ }
6094
+ // unnecessary when only executing (prefilters)
6095
+ // but it'll be ignored by the caller in that case
6096
+ return selection;
6097
+ }
5583
6098
 
5584
6099
  jQuery.fn.extend({
5585
6100
  load: function( url, params, callback ) {
@@ -5591,10 +6106,10 @@ jQuery.fn.extend({
5591
6106
  return this;
5592
6107
  }
5593
6108
 
5594
- var off = url.indexOf(" ");
6109
+ var off = url.indexOf( " " );
5595
6110
  if ( off >= 0 ) {
5596
- var selector = url.slice(off, url.length);
5597
- url = url.slice(0, off);
6111
+ var selector = url.slice( off, url.length );
6112
+ url = url.slice( 0, off );
5598
6113
  }
5599
6114
 
5600
6115
  // Default to a GET request
@@ -5623,26 +6138,34 @@ jQuery.fn.extend({
5623
6138
  type: type,
5624
6139
  dataType: "html",
5625
6140
  data: params,
5626
- complete: function( res, status ) {
6141
+ // Complete callback (responseText is used internally)
6142
+ complete: function( jXHR, status, responseText ) {
6143
+ // Store the response as specified by the jXHR object
6144
+ responseText = jXHR.responseText;
5627
6145
  // If successful, inject the HTML into all the matched elements
5628
- if ( status === "success" || status === "notmodified" ) {
6146
+ if ( jXHR.isResolved() ) {
6147
+ // #4825: Get the actual response in case
6148
+ // a dataFilter is present in ajaxSettings
6149
+ jXHR.done(function( r ) {
6150
+ responseText = r;
6151
+ });
5629
6152
  // See if a selector was specified
5630
6153
  self.html( selector ?
5631
6154
  // Create a dummy div to hold the results
5632
6155
  jQuery("<div>")
5633
6156
  // inject the contents of the document in, removing the scripts
5634
6157
  // to avoid any 'Permission Denied' errors in IE
5635
- .append(res.responseText.replace(rscript, ""))
6158
+ .append(responseText.replace(rscript, ""))
5636
6159
 
5637
6160
  // Locate the specified elements
5638
6161
  .find(selector) :
5639
6162
 
5640
6163
  // If not, just inject the full result
5641
- res.responseText );
6164
+ responseText );
5642
6165
  }
5643
6166
 
5644
6167
  if ( callback ) {
5645
- self.each( callback, [res.responseText, status, res] );
6168
+ self.each( callback, [ responseText, status, jXHR ] );
5646
6169
  }
5647
6170
  }
5648
6171
  });
@@ -5651,42 +6174,42 @@ jQuery.fn.extend({
5651
6174
  },
5652
6175
 
5653
6176
  serialize: function() {
5654
- return jQuery.param(this.serializeArray());
6177
+ return jQuery.param( this.serializeArray() );
5655
6178
  },
5656
6179
 
5657
6180
  serializeArray: function() {
5658
- return this.map(function() {
5659
- return this.elements ? jQuery.makeArray(this.elements) : this;
6181
+ return this.map(function(){
6182
+ return this.elements ? jQuery.makeArray( this.elements ) : this;
5660
6183
  })
5661
- .filter(function() {
6184
+ .filter(function(){
5662
6185
  return this.name && !this.disabled &&
5663
- (this.checked || rselectTextarea.test(this.nodeName) ||
5664
- rinput.test(this.type));
6186
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
6187
+ rinput.test( this.type ) );
5665
6188
  })
5666
- .map(function( i, elem ) {
5667
- var val = jQuery(this).val();
6189
+ .map(function( i, elem ){
6190
+ var val = jQuery( this ).val();
5668
6191
 
5669
6192
  return val == null ?
5670
6193
  null :
5671
- jQuery.isArray(val) ?
5672
- jQuery.map( val, function( val, i ) {
5673
- return { name: elem.name, value: val };
6194
+ jQuery.isArray( val ) ?
6195
+ jQuery.map( val, function( val, i ){
6196
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
5674
6197
  }) :
5675
- { name: elem.name, value: val };
6198
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
5676
6199
  }).get();
5677
6200
  }
5678
6201
  });
5679
6202
 
5680
6203
  // Attach a bunch of functions for handling common AJAX events
5681
- jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
5682
- jQuery.fn[o] = function( f ) {
5683
- return this.bind(o, f);
6204
+ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6205
+ jQuery.fn[ o ] = function( f ){
6206
+ return this.bind( o, f );
5684
6207
  };
5685
- });
6208
+ } );
5686
6209
 
5687
- jQuery.extend({
5688
- get: function( url, data, callback, type ) {
5689
- // shift arguments if data argument was omited
6210
+ jQuery.each( [ "get", "post" ], function( i, method ) {
6211
+ jQuery[ method ] = function( url, data, callback, type ) {
6212
+ // shift arguments if data argument was omitted
5690
6213
  if ( jQuery.isFunction( data ) ) {
5691
6214
  type = type || callback;
5692
6215
  callback = data;
@@ -5694,41 +6217,30 @@ jQuery.extend({
5694
6217
  }
5695
6218
 
5696
6219
  return jQuery.ajax({
5697
- type: "GET",
6220
+ type: method,
5698
6221
  url: url,
5699
6222
  data: data,
5700
6223
  success: callback,
5701
6224
  dataType: type
5702
6225
  });
5703
- },
6226
+ };
6227
+ } );
6228
+
6229
+ jQuery.extend({
5704
6230
 
5705
6231
  getScript: function( url, callback ) {
5706
- return jQuery.get(url, null, callback, "script");
6232
+ return jQuery.get( url, null, callback, "script" );
5707
6233
  },
5708
6234
 
5709
6235
  getJSON: function( url, data, callback ) {
5710
- return jQuery.get(url, data, callback, "json");
5711
- },
5712
-
5713
- post: function( url, data, callback, type ) {
5714
- // shift arguments if data argument was omited
5715
- if ( jQuery.isFunction( data ) ) {
5716
- type = type || callback;
5717
- callback = data;
5718
- data = {};
5719
- }
5720
-
5721
- return jQuery.ajax({
5722
- type: "POST",
5723
- url: url,
5724
- data: data,
5725
- success: callback,
5726
- dataType: type
5727
- });
6236
+ return jQuery.get( url, data, callback, "json" );
5728
6237
  },
5729
6238
 
5730
6239
  ajaxSetup: function( settings ) {
5731
- jQuery.extend( jQuery.ajaxSettings, settings );
6240
+ jQuery.extend( true, jQuery.ajaxSettings, settings );
6241
+ if ( settings.context ) {
6242
+ jQuery.ajaxSettings.context = settings.context;
6243
+ }
5732
6244
  },
5733
6245
 
5734
6246
  ajaxSettings: {
@@ -5741,332 +6253,408 @@ jQuery.extend({
5741
6253
  /*
5742
6254
  timeout: 0,
5743
6255
  data: null,
6256
+ dataType: null,
5744
6257
  username: null,
5745
6258
  password: null,
6259
+ cache: null,
5746
6260
  traditional: false,
6261
+ headers: {},
6262
+ crossDomain: null,
5747
6263
  */
5748
- // This function can be overriden by calling jQuery.ajaxSetup
5749
- xhr: function() {
5750
- return new window.XMLHttpRequest();
5751
- },
6264
+
5752
6265
  accepts: {
5753
6266
  xml: "application/xml, text/xml",
5754
6267
  html: "text/html",
5755
- script: "text/javascript, application/javascript",
5756
- json: "application/json, text/javascript",
5757
6268
  text: "text/plain",
5758
- _default: "*/*"
5759
- }
5760
- },
6269
+ json: "application/json, text/javascript",
6270
+ "*": "*/*"
6271
+ },
5761
6272
 
5762
- ajax: function( origSettings ) {
5763
- var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
5764
- jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
6273
+ contents: {
6274
+ xml: /xml/,
6275
+ html: /html/,
6276
+ json: /json/
6277
+ },
5765
6278
 
5766
- s.url = s.url.replace( rhash, "" );
6279
+ responseFields: {
6280
+ xml: "responseXML",
6281
+ text: "responseText"
6282
+ },
5767
6283
 
5768
- // Use original (not extended) context object if it was provided
5769
- s.context = origSettings && origSettings.context != null ? origSettings.context : s;
6284
+ // List of data converters
6285
+ // 1) key format is "source_type destination_type" (a single space in-between)
6286
+ // 2) the catchall symbol "*" can be used for source_type
6287
+ converters: {
6288
+
6289
+ // Convert anything to text
6290
+ "* text": window.String,
6291
+
6292
+ // Text to html (true = no transformation)
6293
+ "text html": true,
6294
+
6295
+ // Evaluate text as a json expression
6296
+ "text json": jQuery.parseJSON,
6297
+
6298
+ // Parse text as xml
6299
+ "text xml": jQuery.parseXML
6300
+ }
6301
+ },
6302
+
6303
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6304
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
6305
+
6306
+ // Main method
6307
+ ajax: function( url, options ) {
6308
+
6309
+ // If options is not an object,
6310
+ // we simulate pre-1.5 signature
6311
+ if ( typeof options !== "object" ) {
6312
+ options = url;
6313
+ url = undefined;
6314
+ }
6315
+
6316
+ // Force options to be an object
6317
+ options = options || {};
6318
+
6319
+ var // Create the final options object
6320
+ s = jQuery.extend( true, {}, jQuery.ajaxSettings, options ),
6321
+ // Callbacks contexts
6322
+ // We force the original context if it exists
6323
+ // or take it from jQuery.ajaxSettings otherwise
6324
+ // (plain objects used as context get extended)
6325
+ callbackContext =
6326
+ ( s.context = ( "context" in options ? options : jQuery.ajaxSettings ).context ) || s,
6327
+ globalEventContext = callbackContext === s ? jQuery.event : jQuery( callbackContext ),
6328
+ // Deferreds
6329
+ deferred = jQuery.Deferred(),
6330
+ completeDeferred = jQuery._Deferred(),
6331
+ // Status-dependent callbacks
6332
+ statusCode = s.statusCode || {},
6333
+ // Headers (they are sent all at once)
6334
+ requestHeaders = {},
6335
+ // Response headers
6336
+ responseHeadersString,
6337
+ responseHeaders,
6338
+ // transport
6339
+ transport,
6340
+ // timeout handle
6341
+ timeoutTimer,
6342
+ // Cross-domain detection vars
6343
+ loc = document.location,
6344
+ protocol = loc.protocol || "http:",
6345
+ parts,
6346
+ // The jXHR state
6347
+ state = 0,
6348
+ // Loop variable
6349
+ i,
6350
+ // Fake xhr
6351
+ jXHR = {
6352
+
6353
+ readyState: 0,
6354
+
6355
+ // Caches the header
6356
+ setRequestHeader: function( name, value ) {
6357
+ if ( state === 0 ) {
6358
+ requestHeaders[ name.toLowerCase() ] = value;
6359
+ }
6360
+ return this;
6361
+ },
6362
+
6363
+ // Raw string
6364
+ getAllResponseHeaders: function() {
6365
+ return state === 2 ? responseHeadersString : null;
6366
+ },
6367
+
6368
+ // Builds headers hashtable if needed
6369
+ getResponseHeader: function( key ) {
6370
+ var match;
6371
+ if ( state === 2 ) {
6372
+ if ( !responseHeaders ) {
6373
+ responseHeaders = {};
6374
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
6375
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
6376
+ }
6377
+ }
6378
+ match = responseHeaders[ key.toLowerCase() ];
6379
+ }
6380
+ return match || null;
6381
+ },
6382
+
6383
+ // Cancel the request
6384
+ abort: function( statusText ) {
6385
+ statusText = statusText || "abort";
6386
+ if ( transport ) {
6387
+ transport.abort( statusText );
6388
+ }
6389
+ done( 0, statusText );
6390
+ return this;
6391
+ }
6392
+ };
5770
6393
 
5771
- // convert data if not already a string
5772
- if ( s.data && s.processData && typeof s.data !== "string" ) {
5773
- s.data = jQuery.param( s.data, s.traditional );
5774
- }
6394
+ // Callback for when everything is done
6395
+ // It is defined here because jslint complains if it is declared
6396
+ // at the end of the function (which would be more logical and readable)
6397
+ function done( status, statusText, responses, headers) {
5775
6398
 
5776
- // Handle JSONP Parameter Callbacks
5777
- if ( s.dataType === "jsonp" ) {
5778
- if ( type === "GET" ) {
5779
- if ( !jsre.test( s.url ) ) {
5780
- s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
5781
- }
5782
- } else if ( !s.data || !jsre.test(s.data) ) {
5783
- s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
6399
+ // Called once
6400
+ if ( state === 2 ) {
6401
+ return;
5784
6402
  }
5785
- s.dataType = "json";
5786
- }
5787
6403
 
5788
- // Build temporary JSONP function
5789
- if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
5790
- jsonp = s.jsonpCallback || ("jsonp" + jsc++);
6404
+ // State is "done" now
6405
+ state = 2;
5791
6406
 
5792
- // Replace the =? sequence both in the query string and the data
5793
- if ( s.data ) {
5794
- s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
6407
+ // Clear timeout if it exists
6408
+ if ( timeoutTimer ) {
6409
+ clearTimeout( timeoutTimer );
5795
6410
  }
5796
6411
 
5797
- s.url = s.url.replace(jsre, "=" + jsonp + "$1");
6412
+ // Dereference transport for early garbage collection
6413
+ // (no matter how long the jXHR object will be used)
6414
+ transport = undefined;
5798
6415
 
5799
- // We need to make sure
5800
- // that a JSONP style response is executed properly
5801
- s.dataType = "script";
6416
+ // Cache response headers
6417
+ responseHeadersString = headers || "";
5802
6418
 
5803
- // Handle JSONP-style loading
5804
- var customJsonp = window[ jsonp ];
6419
+ // Set readyState
6420
+ jXHR.readyState = status ? 4 : 0;
5805
6421
 
5806
- window[ jsonp ] = function( tmp ) {
5807
- if ( jQuery.isFunction( customJsonp ) ) {
5808
- customJsonp( tmp );
6422
+ var isSuccess,
6423
+ success,
6424
+ error,
6425
+ response = responses ? ajaxHandleResponses( s, jXHR, responses ) : undefined,
6426
+ lastModified,
6427
+ etag;
5809
6428
 
5810
- } else {
5811
- // Garbage collect
5812
- window[ jsonp ] = undefined;
6429
+ // If successful, handle type chaining
6430
+ if ( status >= 200 && status < 300 || status === 304 ) {
5813
6431
 
5814
- try {
5815
- delete window[ jsonp ];
5816
- } catch( jsonpError ) {}
5817
- }
6432
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
6433
+ if ( s.ifModified ) {
5818
6434
 
5819
- data = tmp;
5820
- jQuery.handleSuccess( s, xhr, status, data );
5821
- jQuery.handleComplete( s, xhr, status, data );
5822
-
5823
- if ( head ) {
5824
- head.removeChild( script );
6435
+ if ( ( lastModified = jXHR.getResponseHeader( "Last-Modified" ) ) ) {
6436
+ jQuery.lastModified[ s.url ] = lastModified;
6437
+ }
6438
+ if ( ( etag = jXHR.getResponseHeader( "Etag" ) ) ) {
6439
+ jQuery.etag[ s.url ] = etag;
6440
+ }
5825
6441
  }
5826
- };
5827
- }
5828
6442
 
5829
- if ( s.dataType === "script" && s.cache === null ) {
5830
- s.cache = false;
5831
- }
6443
+ // If not modified
6444
+ if ( status === 304 ) {
5832
6445
 
5833
- if ( s.cache === false && noContent ) {
5834
- var ts = jQuery.now();
6446
+ statusText = "notmodified";
6447
+ isSuccess = true;
5835
6448
 
5836
- // try replacing _= if it is there
5837
- var ret = s.url.replace(rts, "$1_=" + ts);
6449
+ // If we have data
6450
+ } else {
5838
6451
 
5839
- // if nothing was replaced, add timestamp to the end
5840
- s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
5841
- }
6452
+ try {
6453
+ success = ajaxConvert( s, response );
6454
+ statusText = "success";
6455
+ isSuccess = true;
6456
+ } catch(e) {
6457
+ // We have a parsererror
6458
+ statusText = "parsererror";
6459
+ error = e;
6460
+ }
6461
+ }
6462
+ } else {
6463
+ // We extract error from statusText
6464
+ // then normalize statusText and status for non-aborts
6465
+ error = statusText;
6466
+ if( status ) {
6467
+ statusText = "error";
6468
+ if ( status < 0 ) {
6469
+ status = 0;
6470
+ }
6471
+ }
6472
+ }
5842
6473
 
5843
- // If data is available, append data to url for GET/HEAD requests
5844
- if ( s.data && noContent ) {
5845
- s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
5846
- }
6474
+ // Set data for the fake xhr object
6475
+ jXHR.status = status;
6476
+ jXHR.statusText = statusText;
5847
6477
 
5848
- // Watch for a new set of requests
5849
- if ( s.global && jQuery.active++ === 0 ) {
5850
- jQuery.event.trigger( "ajaxStart" );
5851
- }
6478
+ // Success/Error
6479
+ if ( isSuccess ) {
6480
+ deferred.resolveWith( callbackContext, [ success, statusText, jXHR ] );
6481
+ } else {
6482
+ deferred.rejectWith( callbackContext, [ jXHR, statusText, error ] );
6483
+ }
5852
6484
 
5853
- // Matches an absolute URL, and saves the domain
5854
- var parts = rurl.exec( s.url ),
5855
- remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
6485
+ // Status-dependent callbacks
6486
+ jXHR.statusCode( statusCode );
6487
+ statusCode = undefined;
5856
6488
 
5857
- // If we're requesting a remote document
5858
- // and trying to load JSON or Script with a GET
5859
- if ( s.dataType === "script" && type === "GET" && remote ) {
5860
- var head = document.getElementsByTagName("head")[0] || document.documentElement;
5861
- var script = document.createElement("script");
5862
- if ( s.scriptCharset ) {
5863
- script.charset = s.scriptCharset;
6489
+ if ( s.global ) {
6490
+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
6491
+ [ jXHR, s, isSuccess ? success : error ] );
5864
6492
  }
5865
- script.src = s.url;
5866
6493
 
5867
- // Handle Script loading
5868
- if ( !jsonp ) {
5869
- var done = false;
6494
+ // Complete
6495
+ completeDeferred.resolveWith( callbackContext, [ jXHR, statusText ] );
5870
6496
 
5871
- // Attach handlers for all browsers
5872
- script.onload = script.onreadystatechange = function() {
5873
- if ( !done && (!this.readyState ||
5874
- this.readyState === "loaded" || this.readyState === "complete") ) {
5875
- done = true;
5876
- jQuery.handleSuccess( s, xhr, status, data );
5877
- jQuery.handleComplete( s, xhr, status, data );
6497
+ if ( s.global ) {
6498
+ globalEventContext.trigger( "ajaxComplete", [ jXHR, s] );
6499
+ // Handle the global AJAX counter
6500
+ if ( !( --jQuery.active ) ) {
6501
+ jQuery.event.trigger( "ajaxStop" );
6502
+ }
6503
+ }
6504
+ }
5878
6505
 
5879
- // Handle memory leak in IE
5880
- script.onload = script.onreadystatechange = null;
5881
- if ( head && script.parentNode ) {
5882
- head.removeChild( script );
5883
- }
6506
+ // Attach deferreds
6507
+ deferred.promise( jXHR );
6508
+ jXHR.success = jXHR.done;
6509
+ jXHR.error = jXHR.fail;
6510
+ jXHR.complete = completeDeferred.done;
6511
+
6512
+ // Status-dependent callbacks
6513
+ jXHR.statusCode = function( map ) {
6514
+ if ( map ) {
6515
+ var tmp;
6516
+ if ( state < 2 ) {
6517
+ for( tmp in map ) {
6518
+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
5884
6519
  }
5885
- };
6520
+ } else {
6521
+ tmp = map[ jXHR.status ];
6522
+ jXHR.then( tmp, tmp );
6523
+ }
5886
6524
  }
6525
+ return this;
6526
+ };
5887
6527
 
5888
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
5889
- // This arises when a base node is used (#2709 and #4378).
5890
- head.insertBefore( script, head.firstChild );
6528
+ // Remove hash character (#7531: and string promotion)
6529
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
6530
+ // We also use the url parameter if available
6531
+ s.url = ( "" + ( url || s.url ) ).replace( rhash, "" ).replace( rprotocol, protocol + "//" );
6532
+
6533
+ // Extract dataTypes list
6534
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
6535
+
6536
+ // Determine if a cross-domain request is in order
6537
+ if ( !s.crossDomain ) {
6538
+ parts = rurl.exec( s.url.toLowerCase() );
6539
+ s.crossDomain = !!( parts &&
6540
+ ( parts[ 1 ] != protocol || parts[ 2 ] != loc.hostname ||
6541
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
6542
+ ( loc.port || ( protocol === "http:" ? 80 : 443 ) ) )
6543
+ );
6544
+ }
5891
6545
 
5892
- // We handle everything using the script element injection
5893
- return undefined;
6546
+ // Convert data if not already a string
6547
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
6548
+ s.data = jQuery.param( s.data, s.traditional );
5894
6549
  }
5895
6550
 
5896
- var requestDone = false;
6551
+ // Apply prefilters
6552
+ inspectPrefiltersOrTransports( prefilters, s, options, jXHR );
5897
6553
 
5898
- // Create the request object
5899
- var xhr = s.xhr();
6554
+ // Uppercase the type
6555
+ s.type = s.type.toUpperCase();
5900
6556
 
5901
- if ( !xhr ) {
5902
- return;
5903
- }
6557
+ // Determine if request has content
6558
+ s.hasContent = !rnoContent.test( s.type );
5904
6559
 
5905
- // Open the socket
5906
- // Passing null username, generates a login popup on Opera (#2865)
5907
- if ( s.username ) {
5908
- xhr.open(type, s.url, s.async, s.username, s.password);
5909
- } else {
5910
- xhr.open(type, s.url, s.async);
6560
+ // Watch for a new set of requests
6561
+ if ( s.global && jQuery.active++ === 0 ) {
6562
+ jQuery.event.trigger( "ajaxStart" );
5911
6563
  }
5912
6564
 
5913
- // Need an extra try/catch for cross domain requests in Firefox 3
5914
- try {
5915
- // Set content-type if data specified and content-body is valid for this type
5916
- if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
5917
- xhr.setRequestHeader("Content-Type", s.contentType);
5918
- }
6565
+ // More options handling for requests with no content
6566
+ if ( !s.hasContent ) {
5919
6567
 
5920
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
5921
- if ( s.ifModified ) {
5922
- if ( jQuery.lastModified[s.url] ) {
5923
- xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
5924
- }
5925
-
5926
- if ( jQuery.etag[s.url] ) {
5927
- xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
5928
- }
6568
+ // If data is available, append data to url
6569
+ if ( s.data ) {
6570
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
5929
6571
  }
5930
6572
 
5931
- // Set header so the called script knows that it's an XMLHttpRequest
5932
- // Only send the header if it's not a remote XHR
5933
- if ( !remote ) {
5934
- xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
5935
- }
6573
+ // Add anti-cache in url if needed
6574
+ if ( s.cache === false ) {
5936
6575
 
5937
- // Set the Accepts header for the server, depending on the dataType
5938
- xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
5939
- s.accepts[ s.dataType ] + ", */*; q=0.01" :
5940
- s.accepts._default );
5941
- } catch( headerError ) {}
6576
+ var ts = jQuery.now(),
6577
+ // try replacing _= if it is there
6578
+ ret = s.url.replace( rts, "$1_=" + ts );
5942
6579
 
5943
- // Allow custom headers/mimetypes and early abort
5944
- if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
5945
- // Handle the global AJAX counter
5946
- if ( s.global && jQuery.active-- === 1 ) {
5947
- jQuery.event.trigger( "ajaxStop" );
6580
+ // if nothing was replaced, add timestamp to the end
6581
+ s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
5948
6582
  }
5949
-
5950
- // close opended socket
5951
- xhr.abort();
5952
- return false;
5953
6583
  }
5954
6584
 
5955
- if ( s.global ) {
5956
- jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
6585
+ // Set the correct header, if data is being sent
6586
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
6587
+ requestHeaders[ "content-type" ] = s.contentType;
5957
6588
  }
5958
6589
 
5959
- // Wait for a response to come back
5960
- var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5961
- // The request was aborted
5962
- if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5963
- // Opera doesn't call onreadystatechange before this point
5964
- // so we simulate the call
5965
- if ( !requestDone ) {
5966
- jQuery.handleComplete( s, xhr, status, data );
5967
- }
6590
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
6591
+ if ( s.ifModified ) {
6592
+ if ( jQuery.lastModified[ s.url ] ) {
6593
+ requestHeaders[ "if-modified-since" ] = jQuery.lastModified[ s.url ];
6594
+ }
6595
+ if ( jQuery.etag[ s.url ] ) {
6596
+ requestHeaders[ "if-none-match" ] = jQuery.etag[ s.url ];
6597
+ }
6598
+ }
5968
6599
 
5969
- requestDone = true;
5970
- if ( xhr ) {
5971
- xhr.onreadystatechange = jQuery.noop;
5972
- }
6600
+ // Set the Accepts header for the server, depending on the dataType
6601
+ requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
6602
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
6603
+ s.accepts[ "*" ];
5973
6604
 
5974
- // The transfer is complete and the data is available, or the request timed out
5975
- } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5976
- requestDone = true;
5977
- xhr.onreadystatechange = jQuery.noop;
6605
+ // Check for headers option
6606
+ for ( i in s.headers ) {
6607
+ requestHeaders[ i.toLowerCase() ] = s.headers[ i ];
6608
+ }
5978
6609
 
5979
- status = isTimeout === "timeout" ?
5980
- "timeout" :
5981
- !jQuery.httpSuccess( xhr ) ?
5982
- "error" :
5983
- s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5984
- "notmodified" :
5985
- "success";
6610
+ // Allow custom headers/mimetypes and early abort
6611
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jXHR, s ) === false || state === 2 ) ) {
6612
+ // Abort if not done already
6613
+ done( 0, "abort" );
6614
+ // Return false
6615
+ jXHR = false;
5986
6616
 
5987
- var errMsg;
6617
+ } else {
5988
6618
 
5989
- if ( status === "success" ) {
5990
- // Watch for, and catch, XML document parse errors
5991
- try {
5992
- // process the data (runs the xml through httpData regardless of callback)
5993
- data = jQuery.httpData( xhr, s.dataType, s );
5994
- } catch( parserError ) {
5995
- status = "parsererror";
5996
- errMsg = parserError;
5997
- }
5998
- }
6619
+ // Install callbacks on deferreds
6620
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
6621
+ jXHR[ i ]( s[ i ] );
6622
+ }
5999
6623
 
6000
- // Make sure that the request was successful or notmodified
6001
- if ( status === "success" || status === "notmodified" ) {
6002
- // JSONP handles its own success callback
6003
- if ( !jsonp ) {
6004
- jQuery.handleSuccess( s, xhr, status, data );
6005
- }
6006
- } else {
6007
- jQuery.handleError( s, xhr, status, errMsg );
6008
- }
6624
+ // Get transport
6625
+ transport = inspectPrefiltersOrTransports( transports, s, options, jXHR );
6009
6626
 
6010
- // Fire the complete handlers
6011
- if ( !jsonp ) {
6012
- jQuery.handleComplete( s, xhr, status, data );
6627
+ // If no transport, we auto-abort
6628
+ if ( !transport ) {
6629
+ done( -1, "No Transport" );
6630
+ } else {
6631
+ // Set state as sending
6632
+ state = jXHR.readyState = 1;
6633
+ // Send global event
6634
+ if ( s.global ) {
6635
+ globalEventContext.trigger( "ajaxSend", [ jXHR, s ] );
6013
6636
  }
6014
-
6015
- if ( isTimeout === "timeout" ) {
6016
- xhr.abort();
6637
+ // Timeout
6638
+ if ( s.async && s.timeout > 0 ) {
6639
+ timeoutTimer = setTimeout( function(){
6640
+ jXHR.abort( "timeout" );
6641
+ }, s.timeout );
6017
6642
  }
6018
6643
 
6019
- // Stop memory leaks
6020
- if ( s.async ) {
6021
- xhr = null;
6644
+ try {
6645
+ transport.send( requestHeaders, done );
6646
+ } catch (e) {
6647
+ // Propagate exception as error if not done
6648
+ if ( status < 2 ) {
6649
+ done( -1, e );
6650
+ // Simply rethrow otherwise
6651
+ } else {
6652
+ jQuery.error( e );
6653
+ }
6022
6654
  }
6023
6655
  }
6024
- };
6025
-
6026
- // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
6027
- // Opera doesn't fire onreadystatechange at all on abort
6028
- try {
6029
- var oldAbort = xhr.abort;
6030
- xhr.abort = function() {
6031
- if ( xhr ) {
6032
- // oldAbort has no call property in IE7 so
6033
- // just do it this way, which works in all
6034
- // browsers
6035
- Function.prototype.call.call( oldAbort, xhr );
6036
- }
6037
-
6038
- onreadystatechange( "abort" );
6039
- };
6040
- } catch( abortError ) {}
6041
-
6042
- // Timeout checker
6043
- if ( s.async && s.timeout > 0 ) {
6044
- setTimeout(function() {
6045
- // Check to see if the request is still happening
6046
- if ( xhr && !requestDone ) {
6047
- onreadystatechange( "timeout" );
6048
- }
6049
- }, s.timeout);
6050
- }
6051
-
6052
- // Send the data
6053
- try {
6054
- xhr.send( noContent || s.data == null ? null : s.data );
6055
-
6056
- } catch( sendError ) {
6057
- jQuery.handleError( s, xhr, null, sendError );
6058
-
6059
- // Fire the complete handlers
6060
- jQuery.handleComplete( s, xhr, status, data );
6061
- }
6062
-
6063
- // firefox 1.5 doesn't fire statechange for sync requests
6064
- if ( !s.async ) {
6065
- onreadystatechange();
6066
6656
  }
6067
-
6068
- // return XMLHttpRequest to allow aborting the request etc.
6069
- return xhr;
6657
+ return jXHR;
6070
6658
  },
6071
6659
 
6072
6660
  // Serialize an array of form elements or a set of
@@ -6075,37 +6663,37 @@ jQuery.extend({
6075
6663
  var s = [],
6076
6664
  add = function( key, value ) {
6077
6665
  // If value is a function, invoke it and return its value
6078
- value = jQuery.isFunction(value) ? value() : value;
6079
- s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
6666
+ value = jQuery.isFunction( value ) ? value() : value;
6667
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
6080
6668
  };
6081
-
6669
+
6082
6670
  // Set traditional to true for jQuery <= 1.3.2 behavior.
6083
6671
  if ( traditional === undefined ) {
6084
6672
  traditional = jQuery.ajaxSettings.traditional;
6085
6673
  }
6086
-
6674
+
6087
6675
  // If an array was passed in, assume that it is an array of form elements.
6088
- if ( jQuery.isArray(a) || a.jquery ) {
6676
+ if ( jQuery.isArray( a ) || a.jquery ) {
6089
6677
  // Serialize the form elements
6090
6678
  jQuery.each( a, function() {
6091
6679
  add( this.name, this.value );
6092
- });
6093
-
6680
+ } );
6681
+
6094
6682
  } else {
6095
6683
  // If traditional, encode the "old" way (the way 1.3.2 or older
6096
6684
  // did it), otherwise encode params recursively.
6097
6685
  for ( var prefix in a ) {
6098
- buildParams( prefix, a[prefix], traditional, add );
6686
+ buildParams( prefix, a[ prefix ], traditional, add );
6099
6687
  }
6100
6688
  }
6101
6689
 
6102
6690
  // Return the resulting serialization
6103
- return s.join("&").replace(r20, "+");
6691
+ return s.join( "&" ).replace( r20, "+" );
6104
6692
  }
6105
6693
  });
6106
6694
 
6107
6695
  function buildParams( prefix, obj, traditional, add ) {
6108
- if ( jQuery.isArray(obj) && obj.length ) {
6696
+ if ( jQuery.isArray( obj ) && obj.length ) {
6109
6697
  // Serialize array item.
6110
6698
  jQuery.each( obj, function( i, v ) {
6111
6699
  if ( traditional || rbracket.test( prefix ) ) {
@@ -6123,9 +6711,11 @@ function buildParams( prefix, obj, traditional, add ) {
6123
6711
  buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
6124
6712
  }
6125
6713
  });
6126
-
6714
+
6127
6715
  } else if ( !traditional && obj != null && typeof obj === "object" ) {
6128
- if ( jQuery.isEmptyObject( obj ) ) {
6716
+ // If we see an array here, it is empty and should be treated as an empty
6717
+ // object
6718
+ if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) {
6129
6719
  add( prefix, "" );
6130
6720
 
6131
6721
  // Serialize object item.
@@ -6134,7 +6724,7 @@ function buildParams( prefix, obj, traditional, add ) {
6134
6724
  buildParams( prefix + "[" + k + "]", v, traditional, add );
6135
6725
  });
6136
6726
  }
6137
-
6727
+
6138
6728
  } else {
6139
6729
  // Serialize scalar item.
6140
6730
  add( prefix, obj );
@@ -6150,143 +6740,548 @@ jQuery.extend({
6150
6740
 
6151
6741
  // Last-Modified header cache for next request
6152
6742
  lastModified: {},
6153
- etag: {},
6743
+ etag: {}
6154
6744
 
6155
- handleError: function( s, xhr, status, e ) {
6156
- // If a local callback was specified, fire it
6157
- if ( s.error ) {
6158
- s.error.call( s.context, xhr, status, e );
6159
- }
6745
+ });
6160
6746
 
6161
- // Fire the global callback
6162
- if ( s.global ) {
6163
- jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
6747
+ /* Handles responses to an ajax request:
6748
+ * - sets all responseXXX fields accordingly
6749
+ * - finds the right dataType (mediates between content-type and expected dataType)
6750
+ * - returns the corresponding response
6751
+ */
6752
+ function ajaxHandleResponses( s, jXHR, responses ) {
6753
+
6754
+ var contents = s.contents,
6755
+ dataTypes = s.dataTypes,
6756
+ responseFields = s.responseFields,
6757
+ ct,
6758
+ type,
6759
+ finalDataType,
6760
+ firstDataType;
6761
+
6762
+ // Fill responseXXX fields
6763
+ for( type in responseFields ) {
6764
+ if ( type in responses ) {
6765
+ jXHR[ responseFields[type] ] = responses[ type ];
6164
6766
  }
6165
- },
6767
+ }
6166
6768
 
6167
- handleSuccess: function( s, xhr, status, data ) {
6168
- // If a local callback was specified, fire it and pass it the data
6169
- if ( s.success ) {
6170
- s.success.call( s.context, data, status, xhr );
6769
+ // Remove auto dataType and get content-type in the process
6770
+ while( dataTypes[ 0 ] === "*" ) {
6771
+ dataTypes.shift();
6772
+ if ( ct === undefined ) {
6773
+ ct = jXHR.getResponseHeader( "content-type" );
6171
6774
  }
6775
+ }
6172
6776
 
6173
- // Fire the global callback
6174
- if ( s.global ) {
6175
- jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
6777
+ // Check if we're dealing with a known content-type
6778
+ if ( ct ) {
6779
+ for ( type in contents ) {
6780
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
6781
+ dataTypes.unshift( type );
6782
+ break;
6783
+ }
6176
6784
  }
6177
- },
6785
+ }
6178
6786
 
6179
- handleComplete: function( s, xhr, status ) {
6180
- // Process result
6181
- if ( s.complete ) {
6182
- s.complete.call( s.context, xhr, status );
6787
+ // Check to see if we have a response for the expected dataType
6788
+ if ( dataTypes[ 0 ] in responses ) {
6789
+ finalDataType = dataTypes[ 0 ];
6790
+ } else {
6791
+ // Try convertible dataTypes
6792
+ for ( type in responses ) {
6793
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
6794
+ finalDataType = type;
6795
+ break;
6796
+ }
6797
+ if ( !firstDataType ) {
6798
+ firstDataType = type;
6799
+ }
6183
6800
  }
6801
+ // Or just use first one
6802
+ finalDataType = finalDataType || firstDataType;
6803
+ }
6184
6804
 
6185
- // The request was completed
6186
- if ( s.global ) {
6187
- jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
6805
+ // If we found a dataType
6806
+ // We add the dataType to the list if needed
6807
+ // and return the corresponding response
6808
+ if ( finalDataType ) {
6809
+ if ( finalDataType !== dataTypes[ 0 ] ) {
6810
+ dataTypes.unshift( finalDataType );
6188
6811
  }
6812
+ return responses[ finalDataType ];
6813
+ }
6814
+ }
6815
+
6816
+ // Chain conversions given the request and the original response
6817
+ function ajaxConvert( s, response ) {
6189
6818
 
6190
- // Handle the global AJAX counter
6191
- if ( s.global && jQuery.active-- === 1 ) {
6192
- jQuery.event.trigger( "ajaxStop" );
6819
+ // Apply the dataFilter if provided
6820
+ if ( s.dataFilter ) {
6821
+ response = s.dataFilter( response, s.dataType );
6822
+ }
6823
+
6824
+ var dataTypes = s.dataTypes,
6825
+ converters = s.converters,
6826
+ i,
6827
+ length = dataTypes.length,
6828
+ tmp,
6829
+ // Current and previous dataTypes
6830
+ current = dataTypes[ 0 ],
6831
+ prev,
6832
+ // Conversion expression
6833
+ conversion,
6834
+ // Conversion function
6835
+ conv,
6836
+ // Conversion functions (transitive conversion)
6837
+ conv1,
6838
+ conv2;
6839
+
6840
+ // For each dataType in the chain
6841
+ for( i = 1; i < length; i++ ) {
6842
+
6843
+ // Get the dataTypes
6844
+ prev = current;
6845
+ current = dataTypes[ i ];
6846
+
6847
+ // If current is auto dataType, update it to prev
6848
+ if( current === "*" ) {
6849
+ current = prev;
6850
+ // If no auto and dataTypes are actually different
6851
+ } else if ( prev !== "*" && prev !== current ) {
6852
+
6853
+ // Get the converter
6854
+ conversion = prev + " " + current;
6855
+ conv = converters[ conversion ] || converters[ "* " + current ];
6856
+
6857
+ // If there is no direct converter, search transitively
6858
+ if ( !conv ) {
6859
+ conv2 = undefined;
6860
+ for( conv1 in converters ) {
6861
+ tmp = conv1.split( " " );
6862
+ if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
6863
+ conv2 = converters[ tmp[1] + " " + current ];
6864
+ if ( conv2 ) {
6865
+ conv1 = converters[ conv1 ];
6866
+ if ( conv1 === true ) {
6867
+ conv = conv2;
6868
+ } else if ( conv2 === true ) {
6869
+ conv = conv1;
6870
+ }
6871
+ break;
6872
+ }
6873
+ }
6874
+ }
6875
+ }
6876
+ // If we found no converter, dispatch an error
6877
+ if ( !( conv || conv2 ) ) {
6878
+ jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
6879
+ }
6880
+ // If found converter is not an equivalence
6881
+ if ( conv !== true ) {
6882
+ // Convert with 1 or 2 converters accordingly
6883
+ response = conv ? conv( response ) : conv2( conv1(response) );
6884
+ }
6193
6885
  }
6194
- },
6195
-
6196
- triggerGlobal: function( s, type, args ) {
6197
- (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
6198
- },
6886
+ }
6887
+ return response;
6888
+ }
6199
6889
 
6200
- // Determines if an XMLHttpRequest was successful or not
6201
- httpSuccess: function( xhr ) {
6202
- try {
6203
- // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
6204
- return !xhr.status && location.protocol === "file:" ||
6205
- xhr.status >= 200 && xhr.status < 300 ||
6206
- xhr.status === 304 || xhr.status === 1223;
6207
- } catch(e) {}
6208
6890
 
6209
- return false;
6210
- },
6211
6891
 
6212
- // Determines if an XMLHttpRequest returns NotModified
6213
- httpNotModified: function( xhr, url ) {
6214
- var lastModified = xhr.getResponseHeader("Last-Modified"),
6215
- etag = xhr.getResponseHeader("Etag");
6216
6892
 
6217
- if ( lastModified ) {
6218
- jQuery.lastModified[url] = lastModified;
6219
- }
6893
+ var jsc = jQuery.now(),
6894
+ jsre = /(\=)\?(&|$)|()\?\?()/i;
6895
+
6896
+ // Default jsonp settings
6897
+ jQuery.ajaxSetup({
6898
+ jsonp: "callback",
6899
+ jsonpCallback: function() {
6900
+ return jQuery.expando + "_" + ( jsc++ );
6901
+ }
6902
+ });
6220
6903
 
6221
- if ( etag ) {
6222
- jQuery.etag[url] = etag;
6904
+ // Detect, normalize options and install callbacks for jsonp requests
6905
+ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, dataIsString /* internal */ ) {
6906
+
6907
+ dataIsString = ( typeof s.data === "string" );
6908
+
6909
+ if ( s.dataTypes[ 0 ] === "jsonp" ||
6910
+ originalSettings.jsonpCallback ||
6911
+ originalSettings.jsonp != null ||
6912
+ s.jsonp !== false && ( jsre.test( s.url ) ||
6913
+ dataIsString && jsre.test( s.data ) ) ) {
6914
+
6915
+ var responseContainer,
6916
+ jsonpCallback = s.jsonpCallback =
6917
+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
6918
+ previous = window[ jsonpCallback ],
6919
+ url = s.url,
6920
+ data = s.data,
6921
+ replace = "$1" + jsonpCallback + "$2";
6922
+
6923
+ if ( s.jsonp !== false ) {
6924
+ url = url.replace( jsre, replace );
6925
+ if ( s.url === url ) {
6926
+ if ( dataIsString ) {
6927
+ data = data.replace( jsre, replace );
6928
+ }
6929
+ if ( s.data === data ) {
6930
+ // Add callback manually
6931
+ url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
6932
+ }
6933
+ }
6223
6934
  }
6224
6935
 
6225
- return xhr.status === 304;
6226
- },
6936
+ s.url = url;
6937
+ s.data = data;
6938
+
6939
+ window[ jsonpCallback ] = function( response ) {
6940
+ responseContainer = [ response ];
6941
+ };
6227
6942
 
6228
- httpData: function( xhr, type, s ) {
6229
- var ct = xhr.getResponseHeader("content-type") || "",
6230
- xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
6231
- data = xml ? xhr.responseXML : xhr.responseText;
6943
+ s.complete = [ function() {
6232
6944
 
6233
- if ( xml && data.documentElement.nodeName === "parsererror" ) {
6234
- jQuery.error( "parsererror" );
6235
- }
6945
+ // Set callback back to previous value
6946
+ window[ jsonpCallback ] = previous;
6236
6947
 
6237
- // Allow a pre-filtering function to sanitize the response
6238
- // s is checked to keep backwards compatibility
6239
- if ( s && s.dataFilter ) {
6240
- data = s.dataFilter( data, type );
6241
- }
6948
+ // Call if it was a function and we have a response
6949
+ if ( previous) {
6950
+ if ( responseContainer && jQuery.isFunction( previous ) ) {
6951
+ window[ jsonpCallback ] ( responseContainer[ 0 ] );
6952
+ }
6953
+ } else {
6954
+ // else, more memory leak avoidance
6955
+ try{
6956
+ delete window[ jsonpCallback ];
6957
+ } catch( e ) {}
6958
+ }
6242
6959
 
6243
- // The filter can actually parse the response
6244
- if ( typeof data === "string" ) {
6245
- // Get the JavaScript object, if JSON is used.
6246
- if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
6247
- data = jQuery.parseJSON( data );
6960
+ }, s.complete ];
6248
6961
 
6249
- // If the type is "script", eval it in global context
6250
- } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
6251
- jQuery.globalEval( data );
6962
+ // Use data converter to retrieve json after script execution
6963
+ s.converters["script json"] = function() {
6964
+ if ( ! responseContainer ) {
6965
+ jQuery.error( jsonpCallback + " was not called" );
6252
6966
  }
6253
- }
6967
+ return responseContainer[ 0 ];
6968
+ };
6969
+
6970
+ // force json dataType
6971
+ s.dataTypes[ 0 ] = "json";
6254
6972
 
6255
- return data;
6973
+ // Delegate to script
6974
+ return "script";
6256
6975
  }
6976
+ } );
6977
+
6978
+
6257
6979
 
6980
+
6981
+ // Install script dataType
6982
+ jQuery.ajaxSetup({
6983
+ accepts: {
6984
+ script: "text/javascript, application/javascript"
6985
+ },
6986
+ contents: {
6987
+ script: /javascript/
6988
+ },
6989
+ converters: {
6990
+ "text script": function( text ) {
6991
+ jQuery.globalEval( text );
6992
+ return text;
6993
+ }
6994
+ }
6258
6995
  });
6259
6996
 
6260
- /*
6261
- * Create the request object; Microsoft failed to properly
6262
- * implement the XMLHttpRequest in IE7 (can't request local files),
6263
- * so we use the ActiveXObject when it is available
6264
- * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
6265
- * we need a fallback.
6266
- */
6267
- if ( window.ActiveXObject ) {
6268
- jQuery.ajaxSettings.xhr = function() {
6997
+ // Handle cache's special case and global
6998
+ jQuery.ajaxPrefilter( "script", function( s ) {
6999
+ if ( s.cache === undefined ) {
7000
+ s.cache = false;
7001
+ }
7002
+ if ( s.crossDomain ) {
7003
+ s.type = "GET";
7004
+ s.global = false;
7005
+ }
7006
+ } );
7007
+
7008
+ // Bind script tag hack transport
7009
+ jQuery.ajaxTransport( "script", function(s) {
7010
+
7011
+ // This transport only deals with cross domain requests
7012
+ if ( s.crossDomain ) {
7013
+
7014
+ var script,
7015
+ head = document.getElementsByTagName( "head" )[ 0 ] || document.documentElement;
7016
+
7017
+ return {
7018
+
7019
+ send: function( _, callback ) {
7020
+
7021
+ script = document.createElement( "script" );
7022
+
7023
+ script.async = "async";
7024
+
7025
+ if ( s.scriptCharset ) {
7026
+ script.charset = s.scriptCharset;
7027
+ }
7028
+
7029
+ script.src = s.url;
7030
+
7031
+ // Attach handlers for all browsers
7032
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
7033
+
7034
+ if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7035
+
7036
+ // Handle memory leak in IE
7037
+ script.onload = script.onreadystatechange = null;
7038
+
7039
+ // Remove the script
7040
+ if ( head && script.parentNode ) {
7041
+ head.removeChild( script );
7042
+ }
7043
+
7044
+ // Dereference the script
7045
+ script = undefined;
7046
+
7047
+ // Callback if not abort
7048
+ if ( !isAbort ) {
7049
+ callback( 200, "success" );
7050
+ }
7051
+ }
7052
+ };
7053
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
7054
+ // This arises when a base node is used (#2709 and #4378).
7055
+ head.insertBefore( script, head.firstChild );
7056
+ },
7057
+
7058
+ abort: function() {
7059
+ if ( script ) {
7060
+ script.onload( 0, 1 );
7061
+ }
7062
+ }
7063
+ };
7064
+ }
7065
+ } );
7066
+
7067
+
7068
+
7069
+
7070
+ var // Next active xhr id
7071
+ xhrId = jQuery.now(),
7072
+
7073
+ // active xhrs
7074
+ xhrs = {},
7075
+
7076
+ // #5280: see below
7077
+ xhrUnloadAbortInstalled,
7078
+
7079
+ // XHR used to determine supports properties
7080
+ testXHR;
7081
+
7082
+ // Create the request object
7083
+ // (This is still attached to ajaxSettings for backward compatibility)
7084
+ jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7085
+ /* Microsoft failed to properly
7086
+ * implement the XMLHttpRequest in IE7 (can't request local files),
7087
+ * so we use the ActiveXObject when it is available
7088
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7089
+ * we need a fallback.
7090
+ */
7091
+ function() {
6269
7092
  if ( window.location.protocol !== "file:" ) {
6270
7093
  try {
6271
7094
  return new window.XMLHttpRequest();
6272
- } catch(xhrError) {}
7095
+ } catch( xhrError ) {}
6273
7096
  }
6274
7097
 
6275
7098
  try {
6276
7099
  return new window.ActiveXObject("Microsoft.XMLHTTP");
6277
- } catch(activeError) {}
7100
+ } catch( activeError ) {}
7101
+ } :
7102
+ // For all other browsers, use the standard XMLHttpRequest object
7103
+ function() {
7104
+ return new window.XMLHttpRequest();
6278
7105
  };
6279
- }
6280
7106
 
6281
- // Does this browser support XHR requests?
6282
- jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
7107
+ // Test if we can create an xhr object
7108
+ try {
7109
+ testXHR = jQuery.ajaxSettings.xhr();
7110
+ } catch( xhrCreationException ) {}
7111
+
7112
+ //Does this browser support XHR requests?
7113
+ jQuery.support.ajax = !!testXHR;
7114
+
7115
+ // Does this browser support crossDomain XHR requests
7116
+ jQuery.support.cors = testXHR && ( "withCredentials" in testXHR );
7117
+
7118
+ // No need for the temporary xhr anymore
7119
+ testXHR = undefined;
7120
+
7121
+ // Create transport if the browser can provide an xhr
7122
+ if ( jQuery.support.ajax ) {
7123
+
7124
+ jQuery.ajaxTransport(function( s ) {
7125
+ // Cross domain only allowed if supported through XMLHttpRequest
7126
+ if ( !s.crossDomain || jQuery.support.cors ) {
7127
+
7128
+ var callback;
7129
+
7130
+ return {
7131
+ send: function( headers, complete ) {
7132
+
7133
+ // #5280: we need to abort on unload or IE will keep connections alive
7134
+ if ( !xhrUnloadAbortInstalled ) {
7135
+
7136
+ xhrUnloadAbortInstalled = 1;
7137
+
7138
+ jQuery(window).bind( "unload", function() {
7139
+
7140
+ // Abort all pending requests
7141
+ jQuery.each( xhrs, function( _, xhr ) {
7142
+ if ( xhr.onreadystatechange ) {
7143
+ xhr.onreadystatechange( 1 );
7144
+ }
7145
+ } );
7146
+
7147
+ } );
7148
+ }
7149
+
7150
+ // Get a new xhr
7151
+ var xhr = s.xhr(),
7152
+ handle;
7153
+
7154
+ // Open the socket
7155
+ // Passing null username, generates a login popup on Opera (#2865)
7156
+ if ( s.username ) {
7157
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
7158
+ } else {
7159
+ xhr.open( s.type, s.url, s.async );
7160
+ }
7161
+
7162
+ // Requested-With header
7163
+ // Not set for crossDomain requests with no content
7164
+ // (see why at http://trac.dojotoolkit.org/ticket/9486)
7165
+ // Won't change header if already provided
7166
+ if ( !( s.crossDomain && !s.hasContent ) && !headers["x-requested-with"] ) {
7167
+ headers[ "x-requested-with" ] = "XMLHttpRequest";
7168
+ }
7169
+
7170
+ // Need an extra try/catch for cross domain requests in Firefox 3
7171
+ try {
7172
+ jQuery.each( headers, function( key, value ) {
7173
+ xhr.setRequestHeader( key, value );
7174
+ } );
7175
+ } catch( _ ) {}
7176
+
7177
+ // Do send the request
7178
+ // This may raise an exception which is actually
7179
+ // handled in jQuery.ajax (so no try/catch here)
7180
+ xhr.send( ( s.hasContent && s.data ) || null );
7181
+
7182
+ // Listener
7183
+ callback = function( _, isAbort ) {
7184
+
7185
+ // Was never called and is aborted or complete
7186
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7187
+
7188
+ // Only called once
7189
+ callback = 0;
7190
+
7191
+ // Do not keep as active anymore
7192
+ if ( handle ) {
7193
+ xhr.onreadystatechange = jQuery.noop;
7194
+ delete xhrs[ handle ];
7195
+ }
7196
+
7197
+ // If it's an abort
7198
+ if ( isAbort ) {
7199
+ // Abort it manually if needed
7200
+ if ( xhr.readyState !== 4 ) {
7201
+ xhr.abort();
7202
+ }
7203
+ } else {
7204
+ // Get info
7205
+ var status = xhr.status,
7206
+ statusText,
7207
+ responseHeaders = xhr.getAllResponseHeaders(),
7208
+ responses = {},
7209
+ xml = xhr.responseXML;
7210
+
7211
+ // Construct response list
7212
+ if ( xml && xml.documentElement /* #4958 */ ) {
7213
+ responses.xml = xml;
7214
+ }
7215
+ responses.text = xhr.responseText;
7216
+
7217
+ // Firefox throws an exception when accessing
7218
+ // statusText for faulty cross-domain requests
7219
+ try {
7220
+ statusText = xhr.statusText;
7221
+ } catch( e ) {
7222
+ // We normalize with Webkit giving an empty statusText
7223
+ statusText = "";
7224
+ }
7225
+
7226
+ // Filter status for non standard behaviours
7227
+ status =
7228
+ // Opera returns 0 when it should be 304
7229
+ // Webkit returns 0 for failing cross-domain no matter the real status
7230
+ status === 0 ?
7231
+ (
7232
+ // Webkit, Firefox: filter out faulty cross-domain requests
7233
+ !s.crossDomain || statusText ?
7234
+ (
7235
+ // Opera: filter out real aborts #6060
7236
+ responseHeaders ?
7237
+ 304 :
7238
+ 0
7239
+ ) :
7240
+ // We assume 302 but could be anything cross-domain related
7241
+ 302
7242
+ ) :
7243
+ (
7244
+ // IE sometimes returns 1223 when it should be 204 (see #1450)
7245
+ status == 1223 ?
7246
+ 204 :
7247
+ status
7248
+ );
7249
+
7250
+ // Call complete
7251
+ complete( status, statusText, responses, responseHeaders );
7252
+ }
7253
+ }
7254
+ };
7255
+
7256
+ // if we're in sync mode or it's in cache
7257
+ // and has been retrieved directly (IE6 & IE7)
7258
+ // we need to manually fire the callback
7259
+ if ( !s.async || xhr.readyState === 4 ) {
7260
+ callback();
7261
+ } else {
7262
+ // Add to list of active xhrs
7263
+ handle = xhrId++;
7264
+ xhrs[ handle ] = xhr;
7265
+ xhr.onreadystatechange = callback;
7266
+ }
7267
+ },
7268
+
7269
+ abort: function() {
7270
+ if ( callback ) {
7271
+ callback(0,1);
7272
+ }
7273
+ }
7274
+ };
7275
+ }
7276
+ });
7277
+ }
6283
7278
 
6284
7279
 
6285
7280
 
6286
7281
 
6287
7282
  var elemdisplay = {},
6288
7283
  rfxtypes = /^(?:toggle|show|hide)$/,
6289
- rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
7284
+ rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
6290
7285
  timerId,
6291
7286
  fxAttrs = [
6292
7287
  // height animations
@@ -6311,7 +7306,7 @@ jQuery.fn.extend({
6311
7306
 
6312
7307
  // Reset the inline display of this element to learn if it is
6313
7308
  // being hidden by cascaded rules or not
6314
- if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
7309
+ if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
6315
7310
  display = elem.style.display = "";
6316
7311
  }
6317
7312
 
@@ -6319,7 +7314,7 @@ jQuery.fn.extend({
6319
7314
  // in a stylesheet to whatever the default browser style is
6320
7315
  // for such an element
6321
7316
  if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
6322
- jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
7317
+ jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
6323
7318
  }
6324
7319
  }
6325
7320
 
@@ -6330,7 +7325,7 @@ jQuery.fn.extend({
6330
7325
  display = elem.style.display;
6331
7326
 
6332
7327
  if ( display === "" || display === "none" ) {
6333
- elem.style.display = jQuery.data(elem, "olddisplay") || "";
7328
+ elem.style.display = jQuery._data(elem, "olddisplay") || "";
6334
7329
  }
6335
7330
  }
6336
7331
 
@@ -6346,8 +7341,8 @@ jQuery.fn.extend({
6346
7341
  for ( var i = 0, j = this.length; i < j; i++ ) {
6347
7342
  var display = jQuery.css( this[i], "display" );
6348
7343
 
6349
- if ( display !== "none" ) {
6350
- jQuery.data( this[i], "olddisplay", display );
7344
+ if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
7345
+ jQuery._data( this[i], "olddisplay", display );
6351
7346
  }
6352
7347
  }
6353
7348
 
@@ -6621,7 +7616,7 @@ jQuery.fx.prototype = {
6621
7616
  }
6622
7617
 
6623
7618
  var r = parseFloat( jQuery.css( this.elem, this.prop ) );
6624
- return r && r > -10000 ? r : 0;
7619
+ return r || 0;
6625
7620
  },
6626
7621
 
6627
7622
  // Start an animation from one number to another
@@ -6815,7 +7810,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
6815
7810
  jQuery.fn.offset = function( options ) {
6816
7811
  var elem = this[0], box;
6817
7812
 
6818
- if ( options ) {
7813
+ if ( options ) {
6819
7814
  return this.each(function( i ) {
6820
7815
  jQuery.offset.setOffset( this, options, i );
6821
7816
  });
@@ -6838,7 +7833,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
6838
7833
 
6839
7834
  // Make sure we're not dealing with a disconnected DOM node
6840
7835
  if ( !box || !jQuery.contains( docElem, elem ) ) {
6841
- return box || { top: 0, left: 0 };
7836
+ return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
6842
7837
  }
6843
7838
 
6844
7839
  var body = doc.body,
@@ -6857,7 +7852,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
6857
7852
  jQuery.fn.offset = function( options ) {
6858
7853
  var elem = this[0];
6859
7854
 
6860
- if ( options ) {
7855
+ if ( options ) {
6861
7856
  return this.each(function( i ) {
6862
7857
  jQuery.offset.setOffset( this, options, i );
6863
7858
  });
@@ -6976,7 +7971,7 @@ jQuery.offset = {
6976
7971
 
6977
7972
  return { top: top, left: left };
6978
7973
  },
6979
-
7974
+
6980
7975
  setOffset: function( elem, options, i ) {
6981
7976
  var position = jQuery.css( elem, "position" );
6982
7977
 
@@ -7010,7 +8005,7 @@ jQuery.offset = {
7010
8005
  if (options.left != null) {
7011
8006
  props.left = (options.left - curOffset.left) + curLeft;
7012
8007
  }
7013
-
8008
+
7014
8009
  if ( "using" in options ) {
7015
8010
  options.using.call( elem, props );
7016
8011
  } else {
@@ -7070,7 +8065,7 @@ jQuery.each( ["Left", "Top"], function( i, name ) {
7070
8065
 
7071
8066
  jQuery.fn[ method ] = function(val) {
7072
8067
  var elem = this[0], win;
7073
-
8068
+
7074
8069
  if ( !elem ) {
7075
8070
  return null;
7076
8071
  }
@@ -7138,7 +8133,7 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
7138
8133
  if ( !elem ) {
7139
8134
  return size == null ? null : this;
7140
8135
  }
7141
-
8136
+
7142
8137
  if ( jQuery.isFunction( size ) ) {
7143
8138
  return this.each(function( i ) {
7144
8139
  var self = jQuery( this );
@@ -7148,8 +8143,10 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
7148
8143
 
7149
8144
  if ( jQuery.isWindow( elem ) ) {
7150
8145
  // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
7151
- return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
7152
- elem.document.body[ "client" + name ];
8146
+ // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8147
+ var docElemProp = elem.document.documentElement[ "client" + name ];
8148
+ return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8149
+ elem.document.body[ "client" + name ] || docElemProp;
7153
8150
 
7154
8151
  // Get document width or height
7155
8152
  } else if ( elem.nodeType === 9 ) {