html5-starter 0.1.3b → 0.1.4b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 ) {
@@ -7176,4 +8173,4 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
7176
8173
  });
7177
8174
 
7178
8175
 
7179
- })(window);
8176
+ })(window);