bowline 0.1.6 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/README.txt +26 -23
  2. data/Rakefile +18 -23
  3. data/VERSION +1 -0
  4. data/assets/jquery.bowline.js +51 -29
  5. data/assets/jquery.js +2122 -1295
  6. data/bin/bowline-gen +1 -1
  7. data/bowline.gemspec +94 -17
  8. data/examples/twitter.html +18 -18
  9. data/lib/bowline.rb +10 -14
  10. data/lib/bowline/async.rb +29 -0
  11. data/lib/bowline/binders.rb +11 -40
  12. data/lib/bowline/binders/collection.rb +11 -8
  13. data/lib/bowline/binders/singleton.rb +9 -6
  14. data/lib/bowline/commands/run.rb +4 -11
  15. data/lib/bowline/dependencies/FAQ.markdown +6 -0
  16. data/lib/bowline/dependencies/MIT-LICENSE +20 -0
  17. data/lib/bowline/dependencies/README.markdown +51 -0
  18. data/lib/bowline/dependencies/Rakefile +10 -0
  19. data/lib/bowline/dependencies/TODO.markdown +4 -0
  20. data/lib/bowline/dependencies/init.rb +41 -0
  21. data/lib/bowline/dependencies/lib/dependencies.rb +9 -0
  22. data/lib/bowline/dependencies/lib/dependencies/dependency.rb +12 -0
  23. data/lib/bowline/dependencies/lib/dependencies/reader.rb +30 -0
  24. data/lib/bowline/dependencies/lib/dependencies/repository.rb +64 -0
  25. data/lib/bowline/dependencies/lib/ext/rubygems.rb +125 -0
  26. data/lib/bowline/dependencies/lib/template/app_script.rb +31 -0
  27. data/lib/bowline/dependencies/spec/spec.opts +4 -0
  28. data/lib/bowline/dependencies/tasks/dependencies.rake +164 -0
  29. data/lib/bowline/ext/array.rb +1 -1
  30. data/lib/bowline/generators.rb +1 -0
  31. data/lib/bowline/generators/application.rb +7 -2
  32. data/lib/bowline/generators/helper.rb +28 -0
  33. data/lib/bowline/helpers.rb +7 -0
  34. data/lib/bowline/initializer.rb +75 -41
  35. data/lib/bowline/observer.rb +42 -19
  36. data/lib/bowline/tasks/app.rake +143 -77
  37. data/lib/bowline/tasks/gems.rake +34 -0
  38. data/lib/bowline/tasks/{misk.rake → misc.rake} +0 -0
  39. data/lib/bowline/version.rb +11 -0
  40. data/lib/bowline/window.rb +19 -0
  41. data/templates/config/boot.rb +4 -3
  42. data/templates/config/environment.rb +8 -4
  43. data/templates/gitignore +0 -2
  44. data/templates/helper.rb +2 -0
  45. data/templates/public/icon.png +0 -0
  46. data/templates/public/index.html +8 -10
  47. metadata +38 -41
  48. data/Manifest.txt +0 -58
  49. data/lib/bowline/gem_dependency.rb +0 -42
  50. data/templates/config/manifest +0 -18
  51. data/templates/config/tiapp.xml +0 -24
data/README.txt CHANGED
@@ -22,8 +22,8 @@ http://twitter.com/maccman
22
22
 
23
23
  = Usage - Building a basic Twitter client
24
24
 
25
- Build Titanium by following the instructions here:
26
- http://wiki.github.com/marshall/titanium/build-instructions
25
+ Install the Titanium SDK:
26
+ http://www.appcelerator.com/products/download-titanium/download/
27
27
 
28
28
  Install the gem:
29
29
  >> sudo gem install maccman-bowline --source http://gems.github.com
@@ -43,12 +43,9 @@ Install the Twitter gem:
43
43
 
44
44
  Add the Twitter gem to config/environment.rb:
45
45
  config.gem "twitter"
46
-
47
- run:
48
- >> rake app:bundle TIPATH=~/path/to/titanium
49
46
 
50
47
  run:
51
- ./script/run
48
+ >> script/run
52
49
 
53
50
  That's it
54
51
 
@@ -98,27 +95,33 @@ Usage for a collection (of users):
98
95
 
99
96
  <html>
100
97
  <head>
101
- <script src="jquery.js" type="text/javascript" charset="utf-8"></script>
102
- <script src="chain.js" type="text/javascript" charset="utf-8"></script>
103
- <script src="bowline.js" type="text/javascript" charset="utf-8"></script>
98
+ <script src="javascripts/jquery.js" type="text/javascript"></script>
99
+ <script src="javascripts/jquery.chain.js" type="text/javascript"></script>
100
+ <script src="javascripts/jquery.bowline.js" type="text/javascript"></script>
101
+ <script src="javascripts/application.js" type="text/javascript"></script>
104
102
  <script type="text/javascript" charset="utf-8">
105
103
  jQuery(function($){
106
- // Bind the element users to UserBinder
107
- var users = $('#users').bowline('users', function(){
108
- var self = $(this);
109
- self.find('.destroy').click(function(){
110
- self.invoke('destroy');
111
- return false;
112
- })
113
- });
104
+ $.bowline.ready(function(){
105
+ // Bind the element users to UserBinder
106
+ var users = $('#users').bowline('users', function(){
107
+ var self = $(this);
108
+ self.find('.destroy').click(function(){
109
+ self.invoke('destroy');
110
+ return false;
111
+ })
112
+ });
114
113
 
115
- $('#showAdmins').click(function(){
116
- users.invoke('admins');
117
- return false;
118
- });
114
+ $('#showAdmins').click(function(){
115
+ users.invoke('admins');
116
+ return false;
117
+ });
119
118
 
120
- // Populate with all the users
121
- users.invoke('index');
119
+ // Populate with all the users
120
+ users.invoke('index');
121
+
122
+ // Invoke a helper
123
+ var time = $.bowline.helper('current_time');
124
+ });
122
125
  });
123
126
  </script>
124
127
  </head>
data/Rakefile CHANGED
@@ -1,25 +1,20 @@
1
- %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
- require File.dirname(__FILE__) + '/lib/bowline'
3
-
4
- # Generate all the Rake tasks
5
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
- $hoe = Hoe.new('bowline', Bowline::VERSION) do |p|
7
- p.developer('Alex MacCaw', 'info@eribium.org')
8
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
- p.rubyforge_name = 'maccman'
10
- p.extra_deps << ['templater', '>=0.3.2']
11
- p.extra_deps << ['activesupport', '>=2.3.2']
12
- p.extra_dev_deps = [
13
- ['newgem', ">= #{::Newgem::VERSION}"]
14
- ]
15
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
16
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
17
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
18
- p.rsync_args = '-av --delete --ignore-errors'
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "bowline"
5
+ gemspec.summary = "Bowline GUI framework"
6
+ gemspec.email = "alex@leadthinking.com"
7
+ gemspec.homepage = "http://github.com/maccman/bowline"
8
+ gemspec.description = "Ruby/JS GUI framework"
9
+ gemspec.authors = ["Alex MacCaw"]
10
+ gemspec.add_dependency('templater', '>= 0.3.2')
11
+ gemspec.add_dependency('activesupport', '>= 2.3.2')
12
+ end
13
+ rescue LoadError
14
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
15
  end
20
16
 
21
- require 'newgem/tasks' # load /tasks/*.rake
22
- Dir['tasks/**/*.rake'].each { |t| load t }
23
-
24
- # TODO - want other tests/tasks run by default? Add them to the list
25
- # task :default => [:spec, :features]
17
+ task :write_version do
18
+ require File.join(File.dirname(__FILE__), *%w[lib bowline])
19
+ File.open('VERSION', 'w') {|f| f.write Bowline::Version::STRING }
20
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.9
@@ -1,4 +1,6 @@
1
1
  (function($){
2
+ var init = false;
3
+
2
4
  $.bowline = {
3
5
  setup: function(name, el){
4
6
  var rb = eval("bowline_" + name + "_setup");
@@ -18,6 +20,20 @@
18
20
  return rb(el);
19
21
  },
20
22
 
23
+ helper: function(){
24
+ return(
25
+ bowline_helper.apply(
26
+ bowline_helper,
27
+ arguments
28
+ )
29
+ );
30
+ },
31
+
32
+ ready: function(func){
33
+ if(init) return func();
34
+ $(document).bind('loaded.bowline', func);
35
+ },
36
+
21
37
  setupForms: function(){
22
38
  // $('form').bind('submit', function(e){
23
39
  // var src = $(this).attr('src').split('.');
@@ -30,37 +46,33 @@
30
46
 
31
47
  // A lot of JS libs require hashes
32
48
  // without any functions in them
33
- rubyHash: function( hsh ) {
49
+ _rubyHash: function( hsh ) {
34
50
  res = {};
35
- $.each(hsh, function(key, value){
51
+ var key;
52
+ for(key in hsh){
53
+ var value = hsh[key];
36
54
  if(typeof(value) != 'function'){
37
55
  res[key] = value;
38
- }
39
- });
56
+ }
57
+ }
40
58
  return res;
41
- },
42
-
43
- // Length on a Ruby array is a function
44
- rubyMap: function( elems, callback ) {
45
- var ret = [];
46
-
47
- for ( var i = 0, length = elems.length(); i < length; i++ ) {
48
- var value = callback( elems[ i ], i );
49
-
50
- if ( value != null )
51
- ret[ ret.length ] = value;
52
- }
53
-
54
- return ret.concat.apply( [], ret );
55
- }
59
+ }
56
60
  },
57
61
 
62
+ window.bowline_loaded = function(){
63
+ init = true;
64
+ $(document.body).trigger('loaded.bowline');
65
+ }
66
+
58
67
  $.fn.bowline = function(name, options){
59
- $(this).chain(options);
60
- $.bowline.setup(name, $(this));
61
- $(this).data('bowline', name);
62
- $(this).trigger('setup:bowline');
63
- return this;
68
+ var self = $(this);
69
+ $.bowline.ready(function(){
70
+ self.chain(options);
71
+ $.bowline.setup(name, self);
72
+ self.data('bowline', name);
73
+ self.trigger('setup.bowline');
74
+ });
75
+ return self;
64
76
  };
65
77
 
66
78
  $.fn.invoke = function(){
@@ -81,16 +93,26 @@
81
93
  };
82
94
 
83
95
  $.fn.updateCollection = function( items ){
84
- items = $.bowline.rubyMap(items, function(n){
85
- return $.bowline.rubyHash(n);
96
+ items = $.map(items, function(n){
97
+ return $.bowline._rubyHash(n);
86
98
  });
87
99
  $(this).items('replace', items);
88
- $(this).trigger('update:bowline');
100
+ $(this).trigger('update.bowline');
89
101
  };
90
102
 
91
103
  $.fn.updateSingleton = function( item ){
92
- item = $.bowline.rubyHash(item);
104
+ item = $.bowline._rubyHash(item);
93
105
  $(this).item('replace', item);
94
- $(this).trigger('update:bowline');
106
+ $(this).trigger('update.bowline');
95
107
  };
108
+
109
+ $(function(){
110
+ setTimeout(function(){
111
+ $(document.body).trigger('loading.bowline');
112
+ var script = $("<script />");
113
+ script.attr('type', 'text/ruby');
114
+ script.attr('src', '../script/init');
115
+ $('head').append(script);
116
+ }, 100);
117
+ })
96
118
  })(jQuery)
@@ -1,34 +1,36 @@
1
- (function(){
2
- /*
3
- * jQuery 1.2.6 - New Wave Javascript
1
+ /*!
2
+ * jQuery JavaScript Library v1.3.2
3
+ * http://jquery.com/
4
4
  *
5
- * Copyright (c) 2008 John Resig (jquery.com)
6
- * Dual licensed under the MIT (MIT-LICENSE.txt)
7
- * and GPL (GPL-LICENSE.txt) licenses.
5
+ * Copyright (c) 2009 John Resig
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ * http://docs.jquery.com/License
8
8
  *
9
- * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
10
- * $Rev: 5685 $
9
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
10
+ * Revision: 6246
11
11
  */
12
+ (function(){
12
13
 
13
- // Map over jQuery in case of overwrite
14
- var _jQuery = window.jQuery,
15
- // Map over the $ in case of overwrite
16
- _$ = window.$;
17
-
18
- var jQuery = window.jQuery = window.$ = function( selector, context ) {
19
- // The jQuery object is actually just the init constructor 'enhanced'
20
- return new jQuery.fn.init( selector, context );
21
- };
22
-
23
- // A simple way to check for HTML strings or ID strings
24
- // (both of which we optimize for)
25
- var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
26
-
27
- // Is it a simple selector
28
- isSimple = /^.[^:#\[\.]*$/,
14
+ var
15
+ // Will speed up references to window, and allows munging its name.
16
+ window = this,
17
+ // Will speed up references to undefined, and allows munging its name.
18
+ undefined,
19
+ // Map over jQuery in case of overwrite
20
+ _jQuery = window.jQuery,
21
+ // Map over the $ in case of overwrite
22
+ _$ = window.$,
23
+
24
+ jQuery = window.jQuery = window.$ = function( selector, context ) {
25
+ // The jQuery object is actually just the init constructor 'enhanced'
26
+ return new jQuery.fn.init( selector, context );
27
+ },
29
28
 
30
- // Will speed up references to undefined, and allows munging its name.
31
- undefined;
29
+ // A simple way to check for HTML strings or ID strings
30
+ // (both of which we optimize for)
31
+ quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
32
+ // Is it a simple selector
33
+ isSimple = /^.[^:#\[\.,]*$/;
32
34
 
33
35
  jQuery.fn = jQuery.prototype = {
34
36
  init: function( selector, context ) {
@@ -39,10 +41,11 @@ jQuery.fn = jQuery.prototype = {
39
41
  if ( selector.nodeType ) {
40
42
  this[0] = selector;
41
43
  this.length = 1;
44
+ this.context = selector;
42
45
  return this;
43
46
  }
44
47
  // Handle HTML strings
45
- if ( typeof selector == "string" ) {
48
+ if ( typeof selector === "string" ) {
46
49
  // Are we dealing with HTML string or an ID?
47
50
  var match = quickExpr.exec( selector );
48
51
 
@@ -57,17 +60,16 @@ jQuery.fn = jQuery.prototype = {
57
60
  else {
58
61
  var elem = document.getElementById( match[3] );
59
62
 
60
- // Make sure an element was located
61
- if ( elem ){
62
- // Handle the case where IE and Opera return items
63
- // by name instead of ID
64
- if ( elem.id != match[3] )
65
- return jQuery().find( selector );
63
+ // Handle the case where IE and Opera return items
64
+ // by name instead of ID
65
+ if ( elem && elem.id != match[3] )
66
+ return jQuery().find( selector );
66
67
 
67
- // Otherwise, we inject the element directly into the jQuery object
68
- return jQuery( elem );
69
- }
70
- selector = [];
68
+ // Otherwise, we inject the element directly into the jQuery object
69
+ var ret = jQuery( elem || [] );
70
+ ret.context = document;
71
+ ret.selector = selector;
72
+ return ret;
71
73
  }
72
74
 
73
75
  // HANDLE: $(expr, [context])
@@ -78,29 +80,37 @@ jQuery.fn = jQuery.prototype = {
78
80
  // HANDLE: $(function)
79
81
  // Shortcut for document ready
80
82
  } else if ( jQuery.isFunction( selector ) )
81
- return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
83
+ return jQuery( document ).ready( selector );
84
+
85
+ // Make sure that old selector state is passed along
86
+ if ( selector.selector && selector.context ) {
87
+ this.selector = selector.selector;
88
+ this.context = selector.context;
89
+ }
82
90
 
83
- return this.setArray(jQuery.makeArray(selector));
91
+ return this.setArray(jQuery.isArray( selector ) ?
92
+ selector :
93
+ jQuery.makeArray(selector));
84
94
  },
85
95
 
96
+ // Start with an empty selector
97
+ selector: "",
98
+
86
99
  // The current version of jQuery being used
87
- jquery: "1.2.6",
100
+ jquery: "1.3.2",
88
101
 
89
102
  // The number of elements contained in the matched element set
90
103
  size: function() {
91
104
  return this.length;
92
105
  },
93
106
 
94
- // The number of elements contained in the matched element set
95
- length: 0,
96
-
97
107
  // Get the Nth element in the matched element set OR
98
108
  // Get the whole matched element set as a clean array
99
109
  get: function( num ) {
100
- return num == undefined ?
110
+ return num === undefined ?
101
111
 
102
112
  // Return a 'clean' array
103
- jQuery.makeArray( this ) :
113
+ Array.prototype.slice.call( this ) :
104
114
 
105
115
  // Return just the object
106
116
  this[ num ];
@@ -108,13 +118,20 @@ jQuery.fn = jQuery.prototype = {
108
118
 
109
119
  // Take an array of elements and push it onto the stack
110
120
  // (returning the new matched element set)
111
- pushStack: function( elems ) {
121
+ pushStack: function( elems, name, selector ) {
112
122
  // Build a new jQuery matched element set
113
123
  var ret = jQuery( elems );
114
124
 
115
125
  // Add the old object onto the stack (as a reference)
116
126
  ret.prevObject = this;
117
127
 
128
+ ret.context = this.context;
129
+
130
+ if ( name === "find" )
131
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
132
+ else if ( name )
133
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
134
+
118
135
  // Return the newly-formed element set
119
136
  return ret;
120
137
  },
@@ -141,8 +158,6 @@ jQuery.fn = jQuery.prototype = {
141
158
  // Determine the position of an element within
142
159
  // the matched set of elements
143
160
  index: function( elem ) {
144
- var ret = -1;
145
-
146
161
  // Locate the position of the desired element
147
162
  return jQuery.inArray(
148
163
  // If it receives a jQuery object, the first element is used
@@ -154,7 +169,7 @@ jQuery.fn = jQuery.prototype = {
154
169
  var options = name;
155
170
 
156
171
  // Look for the case where we're accessing a style value
157
- if ( name.constructor == String )
172
+ if ( typeof name === "string" )
158
173
  if ( value === undefined )
159
174
  return this[0] && jQuery[ type || "attr" ]( this[0], name );
160
175
 
@@ -184,7 +199,7 @@ jQuery.fn = jQuery.prototype = {
184
199
  },
185
200
 
186
201
  text: function( text ) {
187
- if ( typeof text != "object" && text != null )
202
+ if ( typeof text !== "object" && text != null )
188
203
  return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
189
204
 
190
205
  var ret = "";
@@ -202,20 +217,22 @@ jQuery.fn = jQuery.prototype = {
202
217
  },
203
218
 
204
219
  wrapAll: function( html ) {
205
- if ( this[0] )
220
+ if ( this[0] ) {
206
221
  // The elements to wrap the target around
207
- jQuery( html, this[0].ownerDocument )
208
- .clone()
209
- .insertBefore( this[0] )
210
- .map(function(){
211
- var elem = this;
222
+ var wrap = jQuery( html, this[0].ownerDocument ).clone();
223
+
224
+ if ( this[0].parentNode )
225
+ wrap.insertBefore( this[0] );
226
+
227
+ wrap.map(function(){
228
+ var elem = this;
212
229
 
213
- while ( elem.firstChild )
214
- elem = elem.firstChild;
230
+ while ( elem.firstChild )
231
+ elem = elem.firstChild;
215
232
 
216
- return elem;
217
- })
218
- .append(this);
233
+ return elem;
234
+ }).append(this);
235
+ }
219
236
 
220
237
  return this;
221
238
  },
@@ -233,27 +250,27 @@ jQuery.fn = jQuery.prototype = {
233
250
  },
234
251
 
235
252
  append: function() {
236
- return this.domManip(arguments, true, false, function(elem){
253
+ return this.domManip(arguments, true, function(elem){
237
254
  if (this.nodeType == 1)
238
255
  this.appendChild( elem );
239
256
  });
240
257
  },
241
258
 
242
259
  prepend: function() {
243
- return this.domManip(arguments, true, true, function(elem){
260
+ return this.domManip(arguments, true, function(elem){
244
261
  if (this.nodeType == 1)
245
262
  this.insertBefore( elem, this.firstChild );
246
263
  });
247
264
  },
248
265
 
249
266
  before: function() {
250
- return this.domManip(arguments, false, false, function(elem){
267
+ return this.domManip(arguments, false, function(elem){
251
268
  this.parentNode.insertBefore( elem, this );
252
269
  });
253
270
  },
254
271
 
255
272
  after: function() {
256
- return this.domManip(arguments, false, true, function(elem){
273
+ return this.domManip(arguments, false, function(elem){
257
274
  this.parentNode.insertBefore( elem, this.nextSibling );
258
275
  });
259
276
  },
@@ -262,20 +279,29 @@ jQuery.fn = jQuery.prototype = {
262
279
  return this.prevObject || jQuery( [] );
263
280
  },
264
281
 
265
- find: function( selector ) {
266
- var elems = jQuery.map(this, function(elem){
267
- return jQuery.find( selector, elem );
268
- });
282
+ // For internal use only.
283
+ // Behaves like an Array's method, not like a jQuery method.
284
+ push: [].push,
285
+ sort: [].sort,
286
+ splice: [].splice,
269
287
 
270
- return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
271
- jQuery.unique( elems ) :
272
- elems );
288
+ find: function( selector ) {
289
+ if ( this.length === 1 ) {
290
+ var ret = this.pushStack( [], "find", selector );
291
+ ret.length = 0;
292
+ jQuery.find( selector, this[0], ret );
293
+ return ret;
294
+ } else {
295
+ return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
296
+ return jQuery.find( selector, elem );
297
+ })), "find", selector );
298
+ }
273
299
  },
274
300
 
275
301
  clone: function( events ) {
276
302
  // Do the clone
277
303
  var ret = this.map(function(){
278
- if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
304
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
279
305
  // IE copies events bound via attachEvent when
280
306
  // using cloneNode. Calling detachEvent on the
281
307
  // clone will also remove the events from the orignal
@@ -284,33 +310,37 @@ jQuery.fn = jQuery.prototype = {
284
310
  // attributes in IE that are actually only stored
285
311
  // as properties will not be copied (such as the
286
312
  // the name attribute on an input).
287
- var clone = this.cloneNode(true),
288
- container = document.createElement("div");
289
- container.appendChild(clone);
290
- return jQuery.clean([container.innerHTML])[0];
313
+ var html = this.outerHTML;
314
+ if ( !html ) {
315
+ var div = this.ownerDocument.createElement("div");
316
+ div.appendChild( this.cloneNode(true) );
317
+ html = div.innerHTML;
318
+ }
319
+
320
+ return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
291
321
  } else
292
322
  return this.cloneNode(true);
293
323
  });
294
324
 
295
- // Need to set the expando to null on the cloned set if it exists
296
- // removeData doesn't work here, IE removes it from the original as well
297
- // this is primarily for IE but the data expando shouldn't be copied over in any browser
298
- var clone = ret.find("*").andSelf().each(function(){
299
- if ( this[ expando ] != undefined )
300
- this[ expando ] = null;
301
- });
302
-
303
325
  // Copy the events from the original to the clone
304
- if ( events === true )
305
- this.find("*").andSelf().each(function(i){
306
- if (this.nodeType == 3)
326
+ if ( events === true ) {
327
+ var orig = this.find("*").andSelf(), i = 0;
328
+
329
+ ret.find("*").andSelf().each(function(){
330
+ if ( this.nodeName !== orig[i].nodeName )
307
331
  return;
308
- var events = jQuery.data( this, "events" );
309
332
 
310
- for ( var type in events )
311
- for ( var handler in events[ type ] )
312
- jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
333
+ var events = jQuery.data( orig[i], "events" );
334
+
335
+ for ( var type in events ) {
336
+ for ( var handler in events[ type ] ) {
337
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
338
+ }
339
+ }
340
+
341
+ i++;
313
342
  });
343
+ }
314
344
 
315
345
  // Return the cloned set
316
346
  return ret;
@@ -323,14 +353,33 @@ jQuery.fn = jQuery.prototype = {
323
353
  return selector.call( elem, i );
324
354
  }) ||
325
355
 
326
- jQuery.multiFilter( selector, this ) );
356
+ jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
357
+ return elem.nodeType === 1;
358
+ }) ), "filter", selector );
359
+ },
360
+
361
+ closest: function( selector ) {
362
+ var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
363
+ closer = 0;
364
+
365
+ return this.map(function(){
366
+ var cur = this;
367
+ while ( cur && cur.ownerDocument ) {
368
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
369
+ jQuery.data(cur, "closest", closer);
370
+ return cur;
371
+ }
372
+ cur = cur.parentNode;
373
+ closer++;
374
+ }
375
+ });
327
376
  },
328
377
 
329
378
  not: function( selector ) {
330
- if ( selector.constructor == String )
379
+ if ( typeof selector === "string" )
331
380
  // test special case where just one selector is passed in
332
381
  if ( isSimple.test( selector ) )
333
- return this.pushStack( jQuery.multiFilter( selector, this, true ) );
382
+ return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
334
383
  else
335
384
  selector = jQuery.multiFilter( selector, this );
336
385
 
@@ -343,7 +392,7 @@ jQuery.fn = jQuery.prototype = {
343
392
  add: function( selector ) {
344
393
  return this.pushStack( jQuery.unique( jQuery.merge(
345
394
  this.get(),
346
- typeof selector == 'string' ?
395
+ typeof selector === "string" ?
347
396
  jQuery( selector ) :
348
397
  jQuery.makeArray( selector )
349
398
  )));
@@ -354,15 +403,17 @@ jQuery.fn = jQuery.prototype = {
354
403
  },
355
404
 
356
405
  hasClass: function( selector ) {
357
- return this.is( "." + selector );
406
+ return !!selector && this.is( "." + selector );
358
407
  },
359
408
 
360
409
  val: function( value ) {
361
- if ( value == undefined ) {
362
-
363
- if ( this.length ) {
364
- var elem = this[0];
410
+ if ( value === undefined ) {
411
+ var elem = this[0];
365
412
 
413
+ if ( elem ) {
414
+ if( jQuery.nodeName( elem, 'option' ) )
415
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
416
+
366
417
  // We need to handle select boxes special
367
418
  if ( jQuery.nodeName( elem, "select" ) ) {
368
419
  var index = elem.selectedIndex,
@@ -380,7 +431,7 @@ jQuery.fn = jQuery.prototype = {
380
431
 
381
432
  if ( option.selected ) {
382
433
  // Get the specifc value for the option
383
- value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
434
+ value = jQuery(option).val();
384
435
 
385
436
  // We don't need an array for one selects
386
437
  if ( one )
@@ -391,25 +442,25 @@ jQuery.fn = jQuery.prototype = {
391
442
  }
392
443
  }
393
444
 
394
- return values;
445
+ return values;
446
+ }
395
447
 
396
448
  // Everything else, we just grab the value
397
- } else
398
- return (this[0].value || "").replace(/\r/g, "");
449
+ return (elem.value || "").replace(/\r/g, "");
399
450
 
400
451
  }
401
452
 
402
453
  return undefined;
403
454
  }
404
455
 
405
- if( value.constructor == Number )
456
+ if ( typeof value === "number" )
406
457
  value += '';
407
458
 
408
459
  return this.each(function(){
409
460
  if ( this.nodeType != 1 )
410
461
  return;
411
462
 
412
- if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
463
+ if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
413
464
  this.checked = (jQuery.inArray(this.value, value) >= 0 ||
414
465
  jQuery.inArray(this.name, value) >= 0);
415
466
 
@@ -430,9 +481,9 @@ jQuery.fn = jQuery.prototype = {
430
481
  },
431
482
 
432
483
  html: function( value ) {
433
- return value == undefined ?
484
+ return value === undefined ?
434
485
  (this[0] ?
435
- this[0].innerHTML :
486
+ this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
436
487
  null) :
437
488
  this.empty().append( value );
438
489
  },
@@ -442,11 +493,12 @@ jQuery.fn = jQuery.prototype = {
442
493
  },
443
494
 
444
495
  eq: function( i ) {
445
- return this.slice( i, i + 1 );
496
+ return this.slice( i, +i + 1 );
446
497
  },
447
498
 
448
499
  slice: function() {
449
- return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
500
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ),
501
+ "slice", Array.prototype.slice.call(arguments).join(",") );
450
502
  },
451
503
 
452
504
  map: function( callback ) {
@@ -459,69 +511,29 @@ jQuery.fn = jQuery.prototype = {
459
511
  return this.add( this.prevObject );
460
512
  },
461
513
 
462
- data: function( key, value ){
463
- var parts = key.split(".");
464
- parts[1] = parts[1] ? "." + parts[1] : "";
465
-
466
- if ( value === undefined ) {
467
- var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
468
-
469
- if ( data === undefined && this.length )
470
- data = jQuery.data( this[0], key );
471
-
472
- return data === undefined && parts[1] ?
473
- this.data( parts[0] ) :
474
- data;
475
- } else
476
- return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
477
- jQuery.data( this, key, value );
478
- });
479
- },
480
-
481
- removeData: function( key ){
482
- return this.each(function(){
483
- jQuery.removeData( this, key );
484
- });
485
- },
486
-
487
- domManip: function( args, table, reverse, callback ) {
488
- var clone = this.length > 1, elems;
489
-
490
- return this.each(function(){
491
- if ( !elems ) {
492
- elems = jQuery.clean( args, this.ownerDocument );
493
-
494
- if ( reverse )
495
- elems.reverse();
496
- }
497
-
498
- var obj = this;
499
-
500
- if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
501
- obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
502
-
503
- var scripts = jQuery( [] );
504
-
505
- jQuery.each(elems, function(){
506
- var elem = clone ?
507
- jQuery( this ).clone( true )[0] :
508
- this;
509
-
510
- // execute all scripts after the elements have been injected
511
- if ( jQuery.nodeName( elem, "script" ) )
512
- scripts = scripts.add( elem );
513
- else {
514
- // Remove any inner scripts for later evaluation
515
- if ( elem.nodeType == 1 )
516
- scripts = scripts.add( jQuery( "script", elem ).remove() );
517
-
518
- // Inject the elements into the document
519
- callback.call( obj, elem );
520
- }
521
- });
514
+ domManip: function( args, table, callback ) {
515
+ if ( this[0] ) {
516
+ var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
517
+ scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
518
+ first = fragment.firstChild;
519
+
520
+ if ( first )
521
+ for ( var i = 0, l = this.length; i < l; i++ )
522
+ callback.call( root(this[i], first), this.length > 1 || i > 0 ?
523
+ fragment.cloneNode(true) : fragment );
524
+
525
+ if ( scripts )
526
+ jQuery.each( scripts, evalScript );
527
+ }
522
528
 
523
- scripts.each( evalScript );
524
- });
529
+ return this;
530
+
531
+ function root( elem, cur ) {
532
+ return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
533
+ (elem.getElementsByTagName("tbody")[0] ||
534
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
535
+ elem;
536
+ }
525
537
  }
526
538
  };
527
539
 
@@ -552,7 +564,7 @@ jQuery.extend = jQuery.fn.extend = function() {
552
564
  var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
553
565
 
554
566
  // Handle a deep copy situation
555
- if ( target.constructor == Boolean ) {
567
+ if ( typeof target === "boolean" ) {
556
568
  deep = target;
557
569
  target = arguments[1] || {};
558
570
  // skip the boolean and the target
@@ -560,7 +572,7 @@ jQuery.extend = jQuery.fn.extend = function() {
560
572
  }
561
573
 
562
574
  // Handle case when target is a string or something (possible in deep copy)
563
- if ( typeof target != "object" && typeof target != "function" )
575
+ if ( typeof target !== "object" && !jQuery.isFunction(target) )
564
576
  target = {};
565
577
 
566
578
  // extend jQuery itself if only one argument is passed
@@ -581,7 +593,7 @@ jQuery.extend = jQuery.fn.extend = function() {
581
593
  continue;
582
594
 
583
595
  // Recurse if we're merging object values
584
- if ( deep && copy && typeof copy == "object" && !copy.nodeType )
596
+ if ( deep && copy && typeof copy === "object" && !copy.nodeType )
585
597
  target[ name ] = jQuery.extend( deep,
586
598
  // Never move original objects, clone them
587
599
  src || ( copy.length != null ? [ ] : { } )
@@ -597,11 +609,11 @@ jQuery.extend = jQuery.fn.extend = function() {
597
609
  return target;
598
610
  };
599
611
 
600
- var expando = "jQuery" + now(), uuid = 0, windowData = {},
601
- // exclude the following css properties to add px
602
- exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
612
+ // exclude the following css properties to add px
613
+ var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
603
614
  // cache defaultView
604
- defaultView = document.defaultView || {};
615
+ defaultView = document.defaultView || {},
616
+ toString = Object.prototype.toString;
605
617
 
606
618
  jQuery.extend({
607
619
  noConflict: function( deep ) {
@@ -613,33 +625,36 @@ jQuery.extend({
613
625
  return jQuery;
614
626
  },
615
627
 
616
- // See test/unit/core.js for details concerning this function.
617
- isFunction: function( fn ) {
618
- return !!fn && typeof fn != "string" && !fn.nodeName &&
619
- fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
628
+ // See test/unit/core.js for details concerning isFunction.
629
+ // Since version 1.3, DOM methods and functions like alert
630
+ // aren't supported. They return false on IE (#2968).
631
+ isFunction: function( obj ) {
632
+ return toString.call(obj) === "[object Function]";
633
+ },
634
+
635
+ isArray: function( obj ) {
636
+ return toString.call(obj) === "[object Array]";
620
637
  },
621
638
 
622
639
  // check if an element is in a (or is an) XML document
623
640
  isXMLDoc: function( elem ) {
624
- return elem.documentElement && !elem.body ||
625
- elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
641
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
642
+ !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
626
643
  },
627
644
 
628
645
  // Evalulates a script in a global context
629
646
  globalEval: function( data ) {
630
- data = jQuery.trim( data );
631
-
632
- if ( data ) {
647
+ if ( data && /\S/.test(data) ) {
633
648
  // Inspired by code by Andrea Giammarchi
634
649
  // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
635
650
  var head = document.getElementsByTagName("head")[0] || document.documentElement,
636
651
  script = document.createElement("script");
637
652
 
638
653
  script.type = "text/javascript";
639
- if ( jQuery.browser.msie )
640
- script.text = data;
641
- else
654
+ if ( jQuery.support.scriptEval )
642
655
  script.appendChild( document.createTextNode( data ) );
656
+ else
657
+ script.text = data;
643
658
 
644
659
  // Use insertBefore instead of appendChild to circumvent an IE6 bug.
645
660
  // This arises when a base node is used (#2709).
@@ -652,80 +667,12 @@ jQuery.extend({
652
667
  return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
653
668
  },
654
669
 
655
- cache: {},
656
-
657
- data: function( elem, name, data ) {
658
- elem = elem == window ?
659
- windowData :
660
- elem;
661
-
662
- var id = elem[ expando ];
663
-
664
- // Compute a unique ID for the element
665
- if ( !id )
666
- id = elem[ expando ] = ++uuid;
667
-
668
- // Only generate the data cache if we're
669
- // trying to access or manipulate it
670
- if ( name && !jQuery.cache[ id ] )
671
- jQuery.cache[ id ] = {};
672
-
673
- // Prevent overriding the named cache with undefined values
674
- if ( data !== undefined )
675
- jQuery.cache[ id ][ name ] = data;
676
-
677
- // Return the named cache data, or the ID for the element
678
- return name ?
679
- jQuery.cache[ id ][ name ] :
680
- id;
681
- },
682
-
683
- removeData: function( elem, name ) {
684
- elem = elem == window ?
685
- windowData :
686
- elem;
687
-
688
- var id = elem[ expando ];
689
-
690
- // If we want to remove a specific section of the element's data
691
- if ( name ) {
692
- if ( jQuery.cache[ id ] ) {
693
- // Remove the section of cache data
694
- delete jQuery.cache[ id ][ name ];
695
-
696
- // If we've removed all the data, remove the element's cache
697
- name = "";
698
-
699
- for ( name in jQuery.cache[ id ] )
700
- break;
701
-
702
- if ( !name )
703
- jQuery.removeData( elem );
704
- }
705
-
706
- // Otherwise, we want to remove all of the element's data
707
- } else {
708
- // Clean up the element expando
709
- try {
710
- delete elem[ expando ];
711
- } catch(e){
712
- // IE has trouble directly removing the expando
713
- // but it's ok with using removeAttribute
714
- if ( elem.removeAttribute )
715
- elem.removeAttribute( expando );
716
- }
717
-
718
- // Completely remove the data cache
719
- delete jQuery.cache[ id ];
720
- }
721
- },
722
-
723
670
  // args is for internal usage only
724
671
  each: function( object, callback, args ) {
725
672
  var name, i = 0, length = object.length;
726
673
 
727
674
  if ( args ) {
728
- if ( length == undefined ) {
675
+ if ( length === undefined ) {
729
676
  for ( name in object )
730
677
  if ( callback.apply( object[ name ], args ) === false )
731
678
  break;
@@ -736,7 +683,7 @@ jQuery.extend({
736
683
 
737
684
  // A special, fast, case for the most common use of each
738
685
  } else {
739
- if ( length == undefined ) {
686
+ if ( length === undefined ) {
740
687
  for ( name in object )
741
688
  if ( callback.call( object[ name ], name, object[ name ] ) === false )
742
689
  break;
@@ -754,7 +701,7 @@ jQuery.extend({
754
701
  value = value.call( elem, i );
755
702
 
756
703
  // Handle passing in a number to a CSS property
757
- return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
704
+ return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
758
705
  value + "px" :
759
706
  value;
760
707
  },
@@ -771,7 +718,7 @@ jQuery.extend({
771
718
  // internal only, use removeClass("class")
772
719
  remove: function( elem, classNames ) {
773
720
  if (elem.nodeType == 1)
774
- elem.className = classNames != undefined ?
721
+ elem.className = classNames !== undefined ?
775
722
  jQuery.grep(elem.className.split(/\s+/), function(className){
776
723
  return !jQuery.className.has( classNames, className );
777
724
  }).join(" ") :
@@ -780,7 +727,7 @@ jQuery.extend({
780
727
 
781
728
  // internal only, use hasClass("class")
782
729
  has: function( elem, className ) {
783
- return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
730
+ return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
784
731
  }
785
732
  },
786
733
 
@@ -800,26 +747,32 @@ jQuery.extend({
800
747
  elem.style[ name ] = old[ name ];
801
748
  },
802
749
 
803
- css: function( elem, name, force ) {
750
+ css: function( elem, name, force, extra ) {
804
751
  if ( name == "width" || name == "height" ) {
805
752
  var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
806
753
 
807
754
  function getWH() {
808
755
  val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
809
- var padding = 0, border = 0;
756
+
757
+ if ( extra === "border" )
758
+ return;
759
+
810
760
  jQuery.each( which, function() {
811
- padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
812
- border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
761
+ if ( !extra )
762
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
763
+ if ( extra === "margin" )
764
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
765
+ else
766
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
813
767
  });
814
- val -= Math.round(padding + border);
815
768
  }
816
769
 
817
- if ( jQuery(elem).is(":visible") )
770
+ if ( elem.offsetWidth !== 0 )
818
771
  getWH();
819
772
  else
820
773
  jQuery.swap( elem, props, getWH );
821
774
 
822
- return Math.max(0, val);
775
+ return Math.max(0, Math.round(val));
823
776
  }
824
777
 
825
778
  return jQuery.curCSS( elem, name, force );
@@ -828,30 +781,14 @@ jQuery.extend({
828
781
  curCSS: function( elem, name, force ) {
829
782
  var ret, style = elem.style;
830
783
 
831
- // A helper method for determining if an element's values are broken
832
- function color( elem ) {
833
- if ( !jQuery.browser.safari )
834
- return false;
835
-
836
- // defaultView is cached
837
- var ret = defaultView.getComputedStyle( elem, null );
838
- return !ret || ret.getPropertyValue("color") == "";
839
- }
840
-
841
784
  // We need to handle opacity special in IE
842
- if ( name == "opacity" && jQuery.browser.msie ) {
785
+ if ( name == "opacity" && !jQuery.support.opacity ) {
843
786
  ret = jQuery.attr( style, "opacity" );
844
787
 
845
788
  return ret == "" ?
846
789
  "1" :
847
790
  ret;
848
791
  }
849
- // Opera sometimes will give the wrong display answer, this fixes it, see #2037
850
- if ( jQuery.browser.opera && name == "display" ) {
851
- var save = style.outline;
852
- style.outline = "0 solid black";
853
- style.outline = save;
854
- }
855
792
 
856
793
  // Make sure we're using the right name for getting the float value
857
794
  if ( name.match( /float/i ) )
@@ -870,38 +807,9 @@ jQuery.extend({
870
807
 
871
808
  var computedStyle = defaultView.getComputedStyle( elem, null );
872
809
 
873
- if ( computedStyle && !color( elem ) )
810
+ if ( computedStyle )
874
811
  ret = computedStyle.getPropertyValue( name );
875
812
 
876
- // If the element isn't reporting its values properly in Safari
877
- // then some display: none elements are involved
878
- else {
879
- var swap = [], stack = [], a = elem, i = 0;
880
-
881
- // Locate all of the parent display: none elements
882
- for ( ; a && color(a); a = a.parentNode )
883
- stack.unshift(a);
884
-
885
- // Go through and make them visible, but in reverse
886
- // (It would be better if we knew the exact display type that they had)
887
- for ( ; i < stack.length; i++ )
888
- if ( color( stack[ i ] ) ) {
889
- swap[ i ] = stack[ i ].style.display;
890
- stack[ i ].style.display = "block";
891
- }
892
-
893
- // Since we flip the display style, we have to handle that
894
- // one special, otherwise get the value
895
- ret = name == "display" && swap[ stack.length - 1 ] != null ?
896
- "none" :
897
- ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
898
-
899
- // Finally, revert the display styles back
900
- for ( i = 0; i < swap.length; i++ )
901
- if ( swap[ i ] != null )
902
- stack[ i ].style.display = swap[ i ];
903
- }
904
-
905
813
  // We should always get a number back from opacity
906
814
  if ( name == "opacity" && ret == "" )
907
815
  ret = "1";
@@ -936,22 +844,32 @@ jQuery.extend({
936
844
  return ret;
937
845
  },
938
846
 
939
- clean: function( elems, context ) {
940
- var ret = [];
847
+ clean: function( elems, context, fragment ) {
941
848
  context = context || document;
849
+
942
850
  // !context.createElement fails in IE with an error but returns typeof 'object'
943
- if (typeof context.createElement == 'undefined')
851
+ if ( typeof context.createElement === "undefined" )
944
852
  context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
945
853
 
854
+ // If a single string is passed in and it's a single tag
855
+ // just do a createElement and skip the rest
856
+ if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
857
+ var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
858
+ if ( match )
859
+ return [ context.createElement( match[1] ) ];
860
+ }
861
+
862
+ var ret = [], scripts = [], div = context.createElement("div");
863
+
946
864
  jQuery.each(elems, function(i, elem){
865
+ if ( typeof elem === "number" )
866
+ elem += '';
867
+
947
868
  if ( !elem )
948
869
  return;
949
870
 
950
- if ( elem.constructor == Number )
951
- elem += '';
952
-
953
871
  // Convert html string into DOM nodes
954
- if ( typeof elem == "string" ) {
872
+ if ( typeof elem === "string" ) {
955
873
  // Fix "XHTML"-style tags in all browsers
956
874
  elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
957
875
  return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
@@ -960,7 +878,7 @@ jQuery.extend({
960
878
  });
961
879
 
962
880
  // Trim whitespace, otherwise indexOf won't work as expected
963
- var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
881
+ var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
964
882
 
965
883
  var wrap =
966
884
  // option or optgroup
@@ -984,7 +902,7 @@ jQuery.extend({
984
902
  [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
985
903
 
986
904
  // IE can't serialize <link> and <script> tags normally
987
- jQuery.browser.msie &&
905
+ !jQuery.support.htmlSerialize &&
988
906
  [ 1, "div<div>", "</div>" ] ||
989
907
 
990
908
  [ 0, "", "" ];
@@ -997,14 +915,15 @@ jQuery.extend({
997
915
  div = div.lastChild;
998
916
 
999
917
  // Remove IE's autoinserted <tbody> from table fragments
1000
- if ( jQuery.browser.msie ) {
918
+ if ( !jQuery.support.tbody ) {
1001
919
 
1002
920
  // String was a <table>, *may* have spurious <tbody>
1003
- var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
1004
- div.firstChild && div.firstChild.childNodes :
921
+ var hasBody = /<tbody/i.test(elem),
922
+ tbody = !tags.indexOf("<table") && !hasBody ?
923
+ div.firstChild && div.firstChild.childNodes :
1005
924
 
1006
925
  // String was a bare <thead> or <tfoot>
1007
- wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
926
+ wrap[1] == "<table>" && !hasBody ?
1008
927
  div.childNodes :
1009
928
  [];
1010
929
 
@@ -1012,26 +931,36 @@ jQuery.extend({
1012
931
  if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
1013
932
  tbody[ j ].parentNode.removeChild( tbody[ j ] );
1014
933
 
1015
- // IE completely kills leading whitespace when innerHTML is used
1016
- if ( /^\s/.test( elem ) )
1017
- div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
1018
-
1019
- }
934
+ }
1020
935
 
936
+ // IE completely kills leading whitespace when innerHTML is used
937
+ if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
938
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
939
+
1021
940
  elem = jQuery.makeArray( div.childNodes );
1022
941
  }
1023
942
 
1024
- if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
1025
- return;
1026
-
1027
- if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
943
+ if ( elem.nodeType )
1028
944
  ret.push( elem );
1029
-
1030
945
  else
1031
946
  ret = jQuery.merge( ret, elem );
1032
947
 
1033
948
  });
1034
949
 
950
+ if ( fragment ) {
951
+ for ( var i = 0; ret[i]; i++ ) {
952
+ if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
953
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
954
+ } else {
955
+ if ( ret[i].nodeType === 1 )
956
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
957
+ fragment.appendChild( ret[i] );
958
+ }
959
+ }
960
+
961
+ return scripts;
962
+ }
963
+
1035
964
  return ret;
1036
965
  },
1037
966
 
@@ -1042,8 +971,7 @@ jQuery.extend({
1042
971
 
1043
972
  var notxml = !jQuery.isXMLDoc( elem ),
1044
973
  // Whether we are setting (or getting)
1045
- set = value !== undefined,
1046
- msie = jQuery.browser.msie;
974
+ set = value !== undefined;
1047
975
 
1048
976
  // Try to normalize/fix the name
1049
977
  name = notxml && jQuery.props[ name ] || name;
@@ -1057,7 +985,7 @@ jQuery.extend({
1057
985
 
1058
986
  // Safari mis-reports the default selected property of a hidden option
1059
987
  // Accessing the parent's selectedIndex property fixes it
1060
- if ( name == "selected" && jQuery.browser.safari )
988
+ if ( name == "selected" && elem.parentNode )
1061
989
  elem.parentNode.selectedIndex;
1062
990
 
1063
991
  // If applicable, access the attribute via the DOM 0 way
@@ -1074,17 +1002,30 @@ jQuery.extend({
1074
1002
  if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1075
1003
  return elem.getAttributeNode( name ).nodeValue;
1076
1004
 
1005
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1006
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1007
+ if ( name == "tabIndex" ) {
1008
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
1009
+ return attributeNode && attributeNode.specified
1010
+ ? attributeNode.value
1011
+ : elem.nodeName.match(/(button|input|object|select|textarea)/i)
1012
+ ? 0
1013
+ : elem.nodeName.match(/^(a|area)$/i) && elem.href
1014
+ ? 0
1015
+ : undefined;
1016
+ }
1017
+
1077
1018
  return elem[ name ];
1078
1019
  }
1079
1020
 
1080
- if ( msie && notxml && name == "style" )
1021
+ if ( !jQuery.support.style && notxml && name == "style" )
1081
1022
  return jQuery.attr( elem.style, "cssText", value );
1082
1023
 
1083
1024
  if ( set )
1084
1025
  // convert the value to a string (all browsers do this but IE) see #1070
1085
1026
  elem.setAttribute( name, "" + value );
1086
1027
 
1087
- var attr = msie && notxml && special
1028
+ var attr = !jQuery.support.hrefNormalized && notxml && special
1088
1029
  // Some attributes require a special call on IE
1089
1030
  ? elem.getAttribute( name, 2 )
1090
1031
  : elem.getAttribute( name );
@@ -1096,7 +1037,7 @@ jQuery.extend({
1096
1037
  // elem is actually elem.style ... set the style
1097
1038
 
1098
1039
  // IE uses filters for opacity
1099
- if ( msie && name == "opacity" ) {
1040
+ if ( !jQuery.support.opacity && name == "opacity" ) {
1100
1041
  if ( set ) {
1101
1042
  // IE has trouble with opacity if it does not have layout
1102
1043
  // Force it by setting the zoom level
@@ -1131,8 +1072,8 @@ jQuery.extend({
1131
1072
 
1132
1073
  if( array != null ){
1133
1074
  var i = array.length;
1134
- //the window, strings and functions also have 'length'
1135
- if( i == null || array.split || array.setInterval || array.call )
1075
+ // The window, strings (and functions) also have 'length'
1076
+ if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1136
1077
  ret[0] = array;
1137
1078
  else
1138
1079
  while( i )
@@ -1157,13 +1098,13 @@ jQuery.extend({
1157
1098
  var i = 0, elem, pos = first.length;
1158
1099
  // Also, we need to make sure that the correct elements are being returned
1159
1100
  // (IE returns comment nodes in a '*' query)
1160
- if ( jQuery.browser.msie ) {
1161
- while ( elem = second[ i++ ] )
1101
+ if ( !jQuery.support.getAll ) {
1102
+ while ( (elem = second[ i++ ]) != null )
1162
1103
  if ( elem.nodeType != 8 )
1163
1104
  first[ pos++ ] = elem;
1164
1105
 
1165
1106
  } else
1166
- while ( elem = second[ i++ ] )
1107
+ while ( (elem = second[ i++ ]) != null )
1167
1108
  first[ pos++ ] = elem;
1168
1109
 
1169
1110
  return first;
@@ -1218,37 +1159,21 @@ jQuery.extend({
1218
1159
  }
1219
1160
  });
1220
1161
 
1162
+ // Use of jQuery.browser is deprecated.
1163
+ // It's included for backwards compatibility and plugins,
1164
+ // although they should work to migrate away.
1165
+
1221
1166
  var userAgent = navigator.userAgent.toLowerCase();
1222
1167
 
1223
1168
  // Figure out what browser is being used
1224
1169
  jQuery.browser = {
1225
- version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
1170
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1226
1171
  safari: /webkit/.test( userAgent ),
1227
1172
  opera: /opera/.test( userAgent ),
1228
1173
  msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1229
1174
  mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1230
1175
  };
1231
1176
 
1232
- var styleFloat = jQuery.browser.msie ?
1233
- "styleFloat" :
1234
- "cssFloat";
1235
-
1236
- jQuery.extend({
1237
- // Check to see if the W3C box model is being used
1238
- boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1239
-
1240
- props: {
1241
- "for": "htmlFor",
1242
- "class": "className",
1243
- "float": styleFloat,
1244
- cssFloat: styleFloat,
1245
- styleFloat: styleFloat,
1246
- readonly: "readOnly",
1247
- maxlength: "maxLength",
1248
- cellspacing: "cellSpacing"
1249
- }
1250
- });
1251
-
1252
1177
  jQuery.each({
1253
1178
  parent: function(elem){return elem.parentNode;},
1254
1179
  parents: function(elem){return jQuery.dir(elem,"parentNode");},
@@ -1266,7 +1191,7 @@ jQuery.each({
1266
1191
  if ( selector && typeof selector == "string" )
1267
1192
  ret = jQuery.multiFilter( selector, ret );
1268
1193
 
1269
- return this.pushStack( jQuery.unique( ret ) );
1194
+ return this.pushStack( jQuery.unique( ret ), name, selector );
1270
1195
  };
1271
1196
  });
1272
1197
 
@@ -1277,13 +1202,16 @@ jQuery.each({
1277
1202
  insertAfter: "after",
1278
1203
  replaceAll: "replaceWith"
1279
1204
  }, function(name, original){
1280
- jQuery.fn[ name ] = function() {
1281
- var args = arguments;
1205
+ jQuery.fn[ name ] = function( selector ) {
1206
+ var ret = [], insert = jQuery( selector );
1282
1207
 
1283
- return this.each(function(){
1284
- for ( var i = 0, length = args.length; i < length; i++ )
1285
- jQuery( args[ i ] )[ original ]( this );
1286
- });
1208
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
1209
+ var elems = (i > 0 ? this.clone(true) : this).get();
1210
+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1211
+ ret = ret.concat( elems );
1212
+ }
1213
+
1214
+ return this.pushStack( ret, name, selector );
1287
1215
  };
1288
1216
  });
1289
1217
 
@@ -1302,14 +1230,16 @@ jQuery.each({
1302
1230
  jQuery.className.remove( this, classNames );
1303
1231
  },
1304
1232
 
1305
- toggleClass: function( classNames ) {
1306
- jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
1233
+ toggleClass: function( classNames, state ) {
1234
+ if( typeof state !== "boolean" )
1235
+ state = !jQuery.className.has( this, classNames );
1236
+ jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1307
1237
  },
1308
1238
 
1309
1239
  remove: function( selector ) {
1310
- if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
1240
+ if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1311
1241
  // Prevent memory leaks
1312
- jQuery( "*", this ).add(this).each(function(){
1242
+ jQuery( "*", this ).add([this]).each(function(){
1313
1243
  jQuery.event.remove(this);
1314
1244
  jQuery.removeData(this);
1315
1245
  });
@@ -1320,7 +1250,7 @@ jQuery.each({
1320
1250
 
1321
1251
  empty: function() {
1322
1252
  // Remove element nodes and prevent memory leaks
1323
- jQuery( ">*", this ).remove();
1253
+ jQuery(this).children().remove();
1324
1254
 
1325
1255
  // Remove any remaining nodes
1326
1256
  while ( this.firstChild )
@@ -1332,489 +1262,1172 @@ jQuery.each({
1332
1262
  };
1333
1263
  });
1334
1264
 
1335
- jQuery.each([ "Height", "Width" ], function(i, name){
1336
- var type = name.toLowerCase();
1337
-
1338
- jQuery.fn[ type ] = function( size ) {
1339
- // Get window width or height
1340
- return this[0] == window ?
1341
- // Opera reports document.body.client[Width/Height] properly in both quirks and standards
1342
- jQuery.browser.opera && document.body[ "client" + name ] ||
1343
-
1344
- // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
1345
- jQuery.browser.safari && window[ "inner" + name ] ||
1346
-
1347
- // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
1348
- document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
1349
-
1350
- // Get document width or height
1351
- this[0] == document ?
1352
- // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
1353
- Math.max(
1354
- Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
1355
- Math.max(document.body["offset" + name], document.documentElement["offset" + name])
1356
- ) :
1357
-
1358
- // Get or set width or height on the element
1359
- size == undefined ?
1360
- // Get width or height on the element
1361
- (this.length ? jQuery.css( this[0], type ) : null) :
1362
-
1363
- // Set the width or height on the element (default to pixels if value is unitless)
1364
- this.css( type, size.constructor == String ? size : size + "px" );
1365
- };
1366
- });
1367
-
1368
1265
  // Helper function used by the dimensions and offset modules
1369
1266
  function num(elem, prop) {
1370
1267
  return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1371
- }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
1372
- "(?:[\\w*_-]|\\\\.)" :
1373
- "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
1374
- quickChild = new RegExp("^>\\s*(" + chars + "+)"),
1375
- quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
1376
- quickClass = new RegExp("^([#.]?)(" + chars + "*)");
1268
+ }
1269
+ var expando = "jQuery" + now(), uuid = 0, windowData = {};
1377
1270
 
1378
1271
  jQuery.extend({
1379
- expr: {
1380
- "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1381
- "#": function(a,i,m){return a.getAttribute("id")==m[2];},
1382
- ":": {
1383
- // Position Checks
1384
- lt: function(a,i,m){return i<m[3]-0;},
1385
- gt: function(a,i,m){return i>m[3]-0;},
1386
- nth: function(a,i,m){return m[3]-0==i;},
1387
- eq: function(a,i,m){return m[3]-0==i;},
1388
- first: function(a,i){return i==0;},
1389
- last: function(a,i,m,r){return i==r.length-1;},
1390
- even: function(a,i){return i%2==0;},
1391
- odd: function(a,i){return i%2;},
1392
-
1393
- // Child Checks
1394
- "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
1395
- "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
1396
- "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
1397
-
1398
- // Parent Checks
1399
- parent: function(a){return a.firstChild;},
1400
- empty: function(a){return !a.firstChild;},
1401
-
1402
- // Text Check
1403
- contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1404
-
1405
- // Visibility
1406
- visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
1407
- hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
1408
-
1409
- // Form attributes
1410
- enabled: function(a){return !a.disabled;},
1411
- disabled: function(a){return a.disabled;},
1412
- checked: function(a){return a.checked;},
1413
- selected: function(a){return a.selected||jQuery.attr(a,"selected");},
1414
-
1415
- // Form elements
1416
- text: function(a){return "text"==a.type;},
1417
- radio: function(a){return "radio"==a.type;},
1418
- checkbox: function(a){return "checkbox"==a.type;},
1419
- file: function(a){return "file"==a.type;},
1420
- password: function(a){return "password"==a.type;},
1421
- submit: function(a){return "submit"==a.type;},
1422
- image: function(a){return "image"==a.type;},
1423
- reset: function(a){return "reset"==a.type;},
1424
- button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
1425
- input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
1426
-
1427
- // :has()
1428
- has: function(a,i,m){return jQuery.find(m[3],a).length;},
1429
-
1430
- // :header
1431
- header: function(a){return /h\d/i.test(a.nodeName);},
1432
-
1433
- // :animated
1434
- animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
1435
- }
1436
- },
1437
-
1438
- // The regular expressions that power the parsing engine
1439
- parse: [
1440
- // Match: [@value='test'], [@foo]
1441
- /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
1442
-
1443
- // Match: :contains('foo')
1444
- /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
1445
-
1446
- // Match: :even, :last-child, #id, .class
1447
- new RegExp("^([:.#]*)(" + chars + "+)")
1448
- ],
1449
-
1450
- multiFilter: function( expr, elems, not ) {
1451
- var old, cur = [];
1452
-
1453
- while ( expr && expr != old ) {
1454
- old = expr;
1455
- var f = jQuery.filter( expr, elems, not );
1456
- expr = f.t.replace(/^\s*,\s*/, "" );
1457
- cur = not ? elems = f.r : jQuery.merge( cur, f.r );
1458
- }
1459
-
1460
- return cur;
1461
- },
1462
-
1463
- find: function( t, context ) {
1464
- // Quickly handle non-string expressions
1465
- if ( typeof t != "string" )
1466
- return [ t ];
1467
-
1468
- // check to make sure context is a DOM element or a document
1469
- if ( context && context.nodeType != 1 && context.nodeType != 9)
1470
- return [ ];
1471
-
1472
- // Set the correct context (if none is provided)
1473
- context = context || document;
1272
+ cache: {},
1474
1273
 
1475
- // Initialize the search
1476
- var ret = [context], done = [], last, nodeName;
1274
+ data: function( elem, name, data ) {
1275
+ elem = elem == window ?
1276
+ windowData :
1277
+ elem;
1477
1278
 
1478
- // Continue while a selector expression exists, and while
1479
- // we're no longer looping upon ourselves
1480
- while ( t && last != t ) {
1481
- var r = [];
1482
- last = t;
1279
+ var id = elem[ expando ];
1483
1280
 
1484
- t = jQuery.trim(t);
1281
+ // Compute a unique ID for the element
1282
+ if ( !id )
1283
+ id = elem[ expando ] = ++uuid;
1485
1284
 
1486
- var foundToken = false,
1285
+ // Only generate the data cache if we're
1286
+ // trying to access or manipulate it
1287
+ if ( name && !jQuery.cache[ id ] )
1288
+ jQuery.cache[ id ] = {};
1487
1289
 
1488
- // An attempt at speeding up child selectors that
1489
- // point to a specific element tag
1490
- re = quickChild,
1290
+ // Prevent overriding the named cache with undefined values
1291
+ if ( data !== undefined )
1292
+ jQuery.cache[ id ][ name ] = data;
1491
1293
 
1492
- m = re.exec(t);
1294
+ // Return the named cache data, or the ID for the element
1295
+ return name ?
1296
+ jQuery.cache[ id ][ name ] :
1297
+ id;
1298
+ },
1493
1299
 
1494
- if ( m ) {
1495
- nodeName = m[1].toUpperCase();
1300
+ removeData: function( elem, name ) {
1301
+ elem = elem == window ?
1302
+ windowData :
1303
+ elem;
1496
1304
 
1497
- // Perform our own iteration and filter
1498
- for ( var i = 0; ret[i]; i++ )
1499
- for ( var c = ret[i].firstChild; c; c = c.nextSibling )
1500
- if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
1501
- r.push( c );
1305
+ var id = elem[ expando ];
1502
1306
 
1503
- ret = r;
1504
- t = t.replace( re, "" );
1505
- if ( t.indexOf(" ") == 0 ) continue;
1506
- foundToken = true;
1507
- } else {
1508
- re = /^([>+~])\s*(\w*)/i;
1307
+ // If we want to remove a specific section of the element's data
1308
+ if ( name ) {
1309
+ if ( jQuery.cache[ id ] ) {
1310
+ // Remove the section of cache data
1311
+ delete jQuery.cache[ id ][ name ];
1509
1312
 
1510
- if ( (m = re.exec(t)) != null ) {
1511
- r = [];
1313
+ // If we've removed all the data, remove the element's cache
1314
+ name = "";
1512
1315
 
1513
- var merge = {};
1514
- nodeName = m[2].toUpperCase();
1515
- m = m[1];
1316
+ for ( name in jQuery.cache[ id ] )
1317
+ break;
1516
1318
 
1517
- for ( var j = 0, rl = ret.length; j < rl; j++ ) {
1518
- var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
1519
- for ( ; n; n = n.nextSibling )
1520
- if ( n.nodeType == 1 ) {
1521
- var id = jQuery.data(n);
1319
+ if ( !name )
1320
+ jQuery.removeData( elem );
1321
+ }
1522
1322
 
1523
- if ( m == "~" && merge[id] ) break;
1323
+ // Otherwise, we want to remove all of the element's data
1324
+ } else {
1325
+ // Clean up the element expando
1326
+ try {
1327
+ delete elem[ expando ];
1328
+ } catch(e){
1329
+ // IE has trouble directly removing the expando
1330
+ // but it's ok with using removeAttribute
1331
+ if ( elem.removeAttribute )
1332
+ elem.removeAttribute( expando );
1333
+ }
1524
1334
 
1525
- if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
1526
- if ( m == "~" ) merge[id] = true;
1527
- r.push( n );
1528
- }
1335
+ // Completely remove the data cache
1336
+ delete jQuery.cache[ id ];
1337
+ }
1338
+ },
1339
+ queue: function( elem, type, data ) {
1340
+ if ( elem ){
1341
+
1342
+ type = (type || "fx") + "queue";
1343
+
1344
+ var q = jQuery.data( elem, type );
1345
+
1346
+ if ( !q || jQuery.isArray(data) )
1347
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
1348
+ else if( data )
1349
+ q.push( data );
1350
+
1351
+ }
1352
+ return q;
1353
+ },
1529
1354
 
1530
- if ( m == "+" ) break;
1531
- }
1532
- }
1355
+ dequeue: function( elem, type ){
1356
+ var queue = jQuery.queue( elem, type ),
1357
+ fn = queue.shift();
1358
+
1359
+ if( !type || type === "fx" )
1360
+ fn = queue[0];
1361
+
1362
+ if( fn !== undefined )
1363
+ fn.call(elem);
1364
+ }
1365
+ });
1366
+
1367
+ jQuery.fn.extend({
1368
+ data: function( key, value ){
1369
+ var parts = key.split(".");
1370
+ parts[1] = parts[1] ? "." + parts[1] : "";
1533
1371
 
1534
- ret = r;
1372
+ if ( value === undefined ) {
1373
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1535
1374
 
1536
- // And remove the token
1537
- t = jQuery.trim( t.replace( re, "" ) );
1538
- foundToken = true;
1539
- }
1375
+ if ( data === undefined && this.length )
1376
+ data = jQuery.data( this[0], key );
1377
+
1378
+ return data === undefined && parts[1] ?
1379
+ this.data( parts[0] ) :
1380
+ data;
1381
+ } else
1382
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1383
+ jQuery.data( this, key, value );
1384
+ });
1385
+ },
1386
+
1387
+ removeData: function( key ){
1388
+ return this.each(function(){
1389
+ jQuery.removeData( this, key );
1390
+ });
1391
+ },
1392
+ queue: function(type, data){
1393
+ if ( typeof type !== "string" ) {
1394
+ data = type;
1395
+ type = "fx";
1396
+ }
1397
+
1398
+ if ( data === undefined )
1399
+ return jQuery.queue( this[0], type );
1400
+
1401
+ return this.each(function(){
1402
+ var queue = jQuery.queue( this, type, data );
1403
+
1404
+ if( type == "fx" && queue.length == 1 )
1405
+ queue[0].call(this);
1406
+ });
1407
+ },
1408
+ dequeue: function(type){
1409
+ return this.each(function(){
1410
+ jQuery.dequeue( this, type );
1411
+ });
1412
+ }
1413
+ });/*!
1414
+ * Sizzle CSS Selector Engine - v0.9.3
1415
+ * Copyright 2009, The Dojo Foundation
1416
+ * Released under the MIT, BSD, and GPL Licenses.
1417
+ * More information: http://sizzlejs.com/
1418
+ */
1419
+ (function(){
1420
+
1421
+ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1422
+ done = 0,
1423
+ toString = Object.prototype.toString;
1424
+
1425
+ var Sizzle = function(selector, context, results, seed) {
1426
+ results = results || [];
1427
+ context = context || document;
1428
+
1429
+ if ( context.nodeType !== 1 && context.nodeType !== 9 )
1430
+ return [];
1431
+
1432
+ if ( !selector || typeof selector !== "string" ) {
1433
+ return results;
1434
+ }
1435
+
1436
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1437
+
1438
+ // Reset the position of the chunker regexp (start from head)
1439
+ chunker.lastIndex = 0;
1440
+
1441
+ while ( (m = chunker.exec(selector)) !== null ) {
1442
+ parts.push( m[1] );
1443
+
1444
+ if ( m[2] ) {
1445
+ extra = RegExp.rightContext;
1446
+ break;
1447
+ }
1448
+ }
1449
+
1450
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
1451
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1452
+ set = posProcess( parts[0] + parts[1], context );
1453
+ } else {
1454
+ set = Expr.relative[ parts[0] ] ?
1455
+ [ context ] :
1456
+ Sizzle( parts.shift(), context );
1457
+
1458
+ while ( parts.length ) {
1459
+ selector = parts.shift();
1460
+
1461
+ if ( Expr.relative[ selector ] )
1462
+ selector += parts.shift();
1463
+
1464
+ set = posProcess( selector, set );
1540
1465
  }
1466
+ }
1467
+ } else {
1468
+ var ret = seed ?
1469
+ { expr: parts.pop(), set: makeArray(seed) } :
1470
+ Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
1471
+ set = Sizzle.filter( ret.expr, ret.set );
1472
+
1473
+ if ( parts.length > 0 ) {
1474
+ checkSet = makeArray(set);
1475
+ } else {
1476
+ prune = false;
1477
+ }
1541
1478
 
1542
- // See if there's still an expression, and that we haven't already
1543
- // matched a token
1544
- if ( t && !foundToken ) {
1545
- // Handle multiple expressions
1546
- if ( !t.indexOf(",") ) {
1547
- // Clean the result set
1548
- if ( context == ret[0] ) ret.shift();
1479
+ while ( parts.length ) {
1480
+ var cur = parts.pop(), pop = cur;
1549
1481
 
1550
- // Merge the result sets
1551
- done = jQuery.merge( done, ret );
1482
+ if ( !Expr.relative[ cur ] ) {
1483
+ cur = "";
1484
+ } else {
1485
+ pop = parts.pop();
1486
+ }
1552
1487
 
1553
- // Reset the context
1554
- r = ret = [context];
1488
+ if ( pop == null ) {
1489
+ pop = context;
1490
+ }
1555
1491
 
1556
- // Touch up the selector string
1557
- t = " " + t.substr(1,t.length);
1492
+ Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1493
+ }
1494
+ }
1558
1495
 
1559
- } else {
1560
- // Optimize for the case nodeName#idName
1561
- var re2 = quickID;
1562
- var m = re2.exec(t);
1496
+ if ( !checkSet ) {
1497
+ checkSet = set;
1498
+ }
1563
1499
 
1564
- // Re-organize the results, so that they're consistent
1565
- if ( m ) {
1566
- m = [ 0, m[2], m[3], m[1] ];
1500
+ if ( !checkSet ) {
1501
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
1502
+ }
1567
1503
 
1568
- } else {
1569
- // Otherwise, do a traditional filter check for
1570
- // ID, class, and element selectors
1571
- re2 = quickClass;
1572
- m = re2.exec(t);
1504
+ if ( toString.call(checkSet) === "[object Array]" ) {
1505
+ if ( !prune ) {
1506
+ results.push.apply( results, checkSet );
1507
+ } else if ( context.nodeType === 1 ) {
1508
+ for ( var i = 0; checkSet[i] != null; i++ ) {
1509
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1510
+ results.push( set[i] );
1511
+ }
1512
+ }
1513
+ } else {
1514
+ for ( var i = 0; checkSet[i] != null; i++ ) {
1515
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1516
+ results.push( set[i] );
1517
+ }
1518
+ }
1519
+ }
1520
+ } else {
1521
+ makeArray( checkSet, results );
1522
+ }
1523
+
1524
+ if ( extra ) {
1525
+ Sizzle( extra, context, results, seed );
1526
+
1527
+ if ( sortOrder ) {
1528
+ hasDuplicate = false;
1529
+ results.sort(sortOrder);
1530
+
1531
+ if ( hasDuplicate ) {
1532
+ for ( var i = 1; i < results.length; i++ ) {
1533
+ if ( results[i] === results[i-1] ) {
1534
+ results.splice(i--, 1);
1573
1535
  }
1536
+ }
1537
+ }
1538
+ }
1539
+ }
1574
1540
 
1575
- m[2] = m[2].replace(/\\/g, "");
1541
+ return results;
1542
+ };
1576
1543
 
1577
- var elem = ret[ret.length-1];
1544
+ Sizzle.matches = function(expr, set){
1545
+ return Sizzle(expr, null, null, set);
1546
+ };
1578
1547
 
1579
- // Try to do a global search by ID, where we can
1580
- if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
1581
- // Optimization for HTML document case
1582
- var oid = elem.getElementById(m[2]);
1548
+ Sizzle.find = function(expr, context, isXML){
1549
+ var set, match;
1583
1550
 
1584
- // Do a quick check for the existence of the actual ID attribute
1585
- // to avoid selecting by the name attribute in IE
1586
- // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
1587
- if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
1588
- oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
1551
+ if ( !expr ) {
1552
+ return [];
1553
+ }
1589
1554
 
1590
- // Do a quick check for node name (where applicable) so
1591
- // that div#foo searches will be really fast
1592
- ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
1593
- } else {
1594
- // We need to find all descendant elements
1595
- for ( var i = 0; ret[i]; i++ ) {
1596
- // Grab the tag name being searched for
1597
- var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
1555
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1556
+ var type = Expr.order[i], match;
1557
+
1558
+ if ( (match = Expr.match[ type ].exec( expr )) ) {
1559
+ var left = RegExp.leftContext;
1560
+
1561
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
1562
+ match[1] = (match[1] || "").replace(/\\/g, "");
1563
+ set = Expr.find[ type ]( match, context, isXML );
1564
+ if ( set != null ) {
1565
+ expr = expr.replace( Expr.match[ type ], "" );
1566
+ break;
1567
+ }
1568
+ }
1569
+ }
1570
+ }
1598
1571
 
1599
- // Handle IE7 being really dumb about <object>s
1600
- if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
1601
- tag = "param";
1572
+ if ( !set ) {
1573
+ set = context.getElementsByTagName("*");
1574
+ }
1602
1575
 
1603
- r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1604
- }
1576
+ return {set: set, expr: expr};
1577
+ };
1605
1578
 
1606
- // It's faster to filter by class and be done with it
1607
- if ( m[1] == "." )
1608
- r = jQuery.classFilter( r, m[2] );
1579
+ Sizzle.filter = function(expr, set, inplace, not){
1580
+ var old = expr, result = [], curLoop = set, match, anyFound,
1581
+ isXMLFilter = set && set[0] && isXML(set[0]);
1609
1582
 
1610
- // Same with ID filtering
1611
- if ( m[1] == "#" ) {
1612
- var tmp = [];
1583
+ while ( expr && set.length ) {
1584
+ for ( var type in Expr.filter ) {
1585
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1586
+ var filter = Expr.filter[ type ], found, item;
1587
+ anyFound = false;
1613
1588
 
1614
- // Try to find the element with the ID
1615
- for ( var i = 0; r[i]; i++ )
1616
- if ( r[i].getAttribute("id") == m[2] ) {
1617
- tmp = [ r[i] ];
1618
- break;
1619
- }
1589
+ if ( curLoop == result ) {
1590
+ result = [];
1591
+ }
1620
1592
 
1621
- r = tmp;
1622
- }
1593
+ if ( Expr.preFilter[ type ] ) {
1594
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1623
1595
 
1624
- ret = r;
1596
+ if ( !match ) {
1597
+ anyFound = found = true;
1598
+ } else if ( match === true ) {
1599
+ continue;
1625
1600
  }
1601
+ }
1626
1602
 
1627
- t = t.replace( re2, "" );
1603
+ if ( match ) {
1604
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1605
+ if ( item ) {
1606
+ found = filter( item, match, i, curLoop );
1607
+ var pass = not ^ !!found;
1608
+
1609
+ if ( inplace && found != null ) {
1610
+ if ( pass ) {
1611
+ anyFound = true;
1612
+ } else {
1613
+ curLoop[i] = false;
1614
+ }
1615
+ } else if ( pass ) {
1616
+ result.push( item );
1617
+ anyFound = true;
1618
+ }
1619
+ }
1620
+ }
1628
1621
  }
1629
1622
 
1630
- }
1623
+ if ( found !== undefined ) {
1624
+ if ( !inplace ) {
1625
+ curLoop = result;
1626
+ }
1631
1627
 
1632
- // If a selector string still exists
1633
- if ( t ) {
1634
- // Attempt to filter it
1635
- var val = jQuery.filter(t,r);
1636
- ret = r = val.r;
1637
- t = jQuery.trim(val.t);
1628
+ expr = expr.replace( Expr.match[ type ], "" );
1629
+
1630
+ if ( !anyFound ) {
1631
+ return [];
1632
+ }
1633
+
1634
+ break;
1635
+ }
1638
1636
  }
1639
1637
  }
1640
1638
 
1641
- // An error occurred with the selector;
1642
- // just return an empty set instead
1643
- if ( t )
1644
- ret = [];
1639
+ // Improper expression
1640
+ if ( expr == old ) {
1641
+ if ( anyFound == null ) {
1642
+ throw "Syntax error, unrecognized expression: " + expr;
1643
+ } else {
1644
+ break;
1645
+ }
1646
+ }
1645
1647
 
1646
- // Remove the root context
1647
- if ( ret && context == ret[0] )
1648
- ret.shift();
1648
+ old = expr;
1649
+ }
1649
1650
 
1650
- // And combine the results
1651
- done = jQuery.merge( done, ret );
1651
+ return curLoop;
1652
+ };
1652
1653
 
1653
- return done;
1654
+ var Expr = Sizzle.selectors = {
1655
+ order: [ "ID", "NAME", "TAG" ],
1656
+ match: {
1657
+ ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1658
+ CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1659
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1660
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1661
+ TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1662
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1663
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1664
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1654
1665
  },
1655
-
1656
- classFilter: function(r,m,not){
1657
- m = " " + m + " ";
1658
- var tmp = [];
1659
- for ( var i = 0; r[i]; i++ ) {
1660
- var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1661
- if ( !not && pass || not && !pass )
1662
- tmp.push( r[i] );
1666
+ attrMap: {
1667
+ "class": "className",
1668
+ "for": "htmlFor"
1669
+ },
1670
+ attrHandle: {
1671
+ href: function(elem){
1672
+ return elem.getAttribute("href");
1663
1673
  }
1664
- return tmp;
1665
1674
  },
1675
+ relative: {
1676
+ "+": function(checkSet, part, isXML){
1677
+ var isPartStr = typeof part === "string",
1678
+ isTag = isPartStr && !/\W/.test(part),
1679
+ isPartStrNotTag = isPartStr && !isTag;
1680
+
1681
+ if ( isTag && !isXML ) {
1682
+ part = part.toUpperCase();
1683
+ }
1666
1684
 
1667
- filter: function(t,r,not) {
1668
- var last;
1685
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
1686
+ if ( (elem = checkSet[i]) ) {
1687
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
1669
1688
 
1670
- // Look for common filter expressions
1671
- while ( t && t != last ) {
1672
- last = t;
1689
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1690
+ elem || false :
1691
+ elem === part;
1692
+ }
1693
+ }
1673
1694
 
1674
- var p = jQuery.parse, m;
1695
+ if ( isPartStrNotTag ) {
1696
+ Sizzle.filter( part, checkSet, true );
1697
+ }
1698
+ },
1699
+ ">": function(checkSet, part, isXML){
1700
+ var isPartStr = typeof part === "string";
1675
1701
 
1676
- for ( var i = 0; p[i]; i++ ) {
1677
- m = p[i].exec( t );
1702
+ if ( isPartStr && !/\W/.test(part) ) {
1703
+ part = isXML ? part : part.toUpperCase();
1678
1704
 
1679
- if ( m ) {
1680
- // Remove what we just matched
1681
- t = t.substring( m[0].length );
1705
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1706
+ var elem = checkSet[i];
1707
+ if ( elem ) {
1708
+ var parent = elem.parentNode;
1709
+ checkSet[i] = parent.nodeName === part ? parent : false;
1710
+ }
1711
+ }
1712
+ } else {
1713
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1714
+ var elem = checkSet[i];
1715
+ if ( elem ) {
1716
+ checkSet[i] = isPartStr ?
1717
+ elem.parentNode :
1718
+ elem.parentNode === part;
1719
+ }
1720
+ }
1682
1721
 
1683
- m[2] = m[2].replace(/\\/g, "");
1684
- break;
1722
+ if ( isPartStr ) {
1723
+ Sizzle.filter( part, checkSet, true );
1685
1724
  }
1686
1725
  }
1726
+ },
1727
+ "": function(checkSet, part, isXML){
1728
+ var doneName = done++, checkFn = dirCheck;
1687
1729
 
1688
- if ( !m )
1689
- break;
1730
+ if ( !part.match(/\W/) ) {
1731
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
1732
+ checkFn = dirNodeCheck;
1733
+ }
1734
+
1735
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1736
+ },
1737
+ "~": function(checkSet, part, isXML){
1738
+ var doneName = done++, checkFn = dirCheck;
1739
+
1740
+ if ( typeof part === "string" && !part.match(/\W/) ) {
1741
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
1742
+ checkFn = dirNodeCheck;
1743
+ }
1690
1744
 
1691
- // :not() is a special case that can be optimized by
1692
- // keeping it out of the expression list
1693
- if ( m[1] == ":" && m[2] == "not" )
1694
- // optimize if only one selector found (most common case)
1695
- r = isSimple.test( m[3] ) ?
1696
- jQuery.filter(m[3], r, true).r :
1697
- jQuery( r ).not( m[3] );
1698
-
1699
- // We can get a big speed boost by filtering by class here
1700
- else if ( m[1] == "." )
1701
- r = jQuery.classFilter(r, m[2], not);
1702
-
1703
- else if ( m[1] == "[" ) {
1704
- var tmp = [], type = m[3];
1705
-
1706
- for ( var i = 0, rl = r.length; i < rl; i++ ) {
1707
- var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
1708
-
1709
- if ( z == null || /href|src|selected/.test(m[2]) )
1710
- z = jQuery.attr(a,m[2]) || '';
1711
-
1712
- if ( (type == "" && !!z ||
1713
- type == "=" && z == m[5] ||
1714
- type == "!=" && z != m[5] ||
1715
- type == "^=" && z && !z.indexOf(m[5]) ||
1716
- type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
1717
- (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
1718
- tmp.push( a );
1745
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1746
+ }
1747
+ },
1748
+ find: {
1749
+ ID: function(match, context, isXML){
1750
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
1751
+ var m = context.getElementById(match[1]);
1752
+ return m ? [m] : [];
1753
+ }
1754
+ },
1755
+ NAME: function(match, context, isXML){
1756
+ if ( typeof context.getElementsByName !== "undefined" ) {
1757
+ var ret = [], results = context.getElementsByName(match[1]);
1758
+
1759
+ for ( var i = 0, l = results.length; i < l; i++ ) {
1760
+ if ( results[i].getAttribute("name") === match[1] ) {
1761
+ ret.push( results[i] );
1762
+ }
1719
1763
  }
1720
1764
 
1721
- r = tmp;
1765
+ return ret.length === 0 ? null : ret;
1766
+ }
1767
+ },
1768
+ TAG: function(match, context){
1769
+ return context.getElementsByTagName(match[1]);
1770
+ }
1771
+ },
1772
+ preFilter: {
1773
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
1774
+ match = " " + match[1].replace(/\\/g, "") + " ";
1775
+
1776
+ if ( isXML ) {
1777
+ return match;
1778
+ }
1779
+
1780
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1781
+ if ( elem ) {
1782
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1783
+ if ( !inplace )
1784
+ result.push( elem );
1785
+ } else if ( inplace ) {
1786
+ curLoop[i] = false;
1787
+ }
1788
+ }
1789
+ }
1722
1790
 
1723
- // We can get a speed boost by handling nth-child here
1724
- } else if ( m[1] == ":" && m[2] == "nth-child" ) {
1725
- var merge = {}, tmp = [],
1726
- // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1727
- test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1728
- m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
1729
- !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
1730
- // calculate the numbers (first)n+(last) including if they are negative
1731
- first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
1791
+ return false;
1792
+ },
1793
+ ID: function(match){
1794
+ return match[1].replace(/\\/g, "");
1795
+ },
1796
+ TAG: function(match, curLoop){
1797
+ for ( var i = 0; curLoop[i] === false; i++ ){}
1798
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1799
+ },
1800
+ CHILD: function(match){
1801
+ if ( match[1] == "nth" ) {
1802
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1803
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1804
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1805
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1806
+
1807
+ // calculate the numbers (first)n+(last) including if they are negative
1808
+ match[2] = (test[1] + (test[2] || 1)) - 0;
1809
+ match[3] = test[3] - 0;
1810
+ }
1732
1811
 
1733
- // loop through all the elements left in the jQuery object
1734
- for ( var i = 0, rl = r.length; i < rl; i++ ) {
1735
- var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
1812
+ // TODO: Move to normal caching system
1813
+ match[0] = done++;
1736
1814
 
1737
- if ( !merge[id] ) {
1738
- var c = 1;
1815
+ return match;
1816
+ },
1817
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
1818
+ var name = match[1].replace(/\\/g, "");
1819
+
1820
+ if ( !isXML && Expr.attrMap[name] ) {
1821
+ match[1] = Expr.attrMap[name];
1822
+ }
1739
1823
 
1740
- for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1741
- if ( n.nodeType == 1 )
1742
- n.nodeIndex = c++;
1824
+ if ( match[2] === "~=" ) {
1825
+ match[4] = " " + match[4] + " ";
1826
+ }
1743
1827
 
1744
- merge[id] = true;
1828
+ return match;
1829
+ },
1830
+ PSEUDO: function(match, curLoop, inplace, result, not){
1831
+ if ( match[1] === "not" ) {
1832
+ // If we're dealing with a complex expression, or a simple one
1833
+ if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
1834
+ match[3] = Sizzle(match[3], null, null, curLoop);
1835
+ } else {
1836
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1837
+ if ( !inplace ) {
1838
+ result.push.apply( result, ret );
1745
1839
  }
1840
+ return false;
1841
+ }
1842
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1843
+ return true;
1844
+ }
1845
+
1846
+ return match;
1847
+ },
1848
+ POS: function(match){
1849
+ match.unshift( true );
1850
+ return match;
1851
+ }
1852
+ },
1853
+ filters: {
1854
+ enabled: function(elem){
1855
+ return elem.disabled === false && elem.type !== "hidden";
1856
+ },
1857
+ disabled: function(elem){
1858
+ return elem.disabled === true;
1859
+ },
1860
+ checked: function(elem){
1861
+ return elem.checked === true;
1862
+ },
1863
+ selected: function(elem){
1864
+ // Accessing this property makes selected-by-default
1865
+ // options in Safari work properly
1866
+ elem.parentNode.selectedIndex;
1867
+ return elem.selected === true;
1868
+ },
1869
+ parent: function(elem){
1870
+ return !!elem.firstChild;
1871
+ },
1872
+ empty: function(elem){
1873
+ return !elem.firstChild;
1874
+ },
1875
+ has: function(elem, i, match){
1876
+ return !!Sizzle( match[3], elem ).length;
1877
+ },
1878
+ header: function(elem){
1879
+ return /h\d/i.test( elem.nodeName );
1880
+ },
1881
+ text: function(elem){
1882
+ return "text" === elem.type;
1883
+ },
1884
+ radio: function(elem){
1885
+ return "radio" === elem.type;
1886
+ },
1887
+ checkbox: function(elem){
1888
+ return "checkbox" === elem.type;
1889
+ },
1890
+ file: function(elem){
1891
+ return "file" === elem.type;
1892
+ },
1893
+ password: function(elem){
1894
+ return "password" === elem.type;
1895
+ },
1896
+ submit: function(elem){
1897
+ return "submit" === elem.type;
1898
+ },
1899
+ image: function(elem){
1900
+ return "image" === elem.type;
1901
+ },
1902
+ reset: function(elem){
1903
+ return "reset" === elem.type;
1904
+ },
1905
+ button: function(elem){
1906
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1907
+ },
1908
+ input: function(elem){
1909
+ return /input|select|textarea|button/i.test(elem.nodeName);
1910
+ }
1911
+ },
1912
+ setFilters: {
1913
+ first: function(elem, i){
1914
+ return i === 0;
1915
+ },
1916
+ last: function(elem, i, match, array){
1917
+ return i === array.length - 1;
1918
+ },
1919
+ even: function(elem, i){
1920
+ return i % 2 === 0;
1921
+ },
1922
+ odd: function(elem, i){
1923
+ return i % 2 === 1;
1924
+ },
1925
+ lt: function(elem, i, match){
1926
+ return i < match[3] - 0;
1927
+ },
1928
+ gt: function(elem, i, match){
1929
+ return i > match[3] - 0;
1930
+ },
1931
+ nth: function(elem, i, match){
1932
+ return match[3] - 0 == i;
1933
+ },
1934
+ eq: function(elem, i, match){
1935
+ return match[3] - 0 == i;
1936
+ }
1937
+ },
1938
+ filter: {
1939
+ PSEUDO: function(elem, match, i, array){
1940
+ var name = match[1], filter = Expr.filters[ name ];
1941
+
1942
+ if ( filter ) {
1943
+ return filter( elem, i, match, array );
1944
+ } else if ( name === "contains" ) {
1945
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1946
+ } else if ( name === "not" ) {
1947
+ var not = match[3];
1948
+
1949
+ for ( var i = 0, l = not.length; i < l; i++ ) {
1950
+ if ( not[i] === elem ) {
1951
+ return false;
1952
+ }
1953
+ }
1746
1954
 
1747
- var add = false;
1955
+ return true;
1956
+ }
1957
+ },
1958
+ CHILD: function(elem, match){
1959
+ var type = match[1], node = elem;
1960
+ switch (type) {
1961
+ case 'only':
1962
+ case 'first':
1963
+ while (node = node.previousSibling) {
1964
+ if ( node.nodeType === 1 ) return false;
1965
+ }
1966
+ if ( type == 'first') return true;
1967
+ node = elem;
1968
+ case 'last':
1969
+ while (node = node.nextSibling) {
1970
+ if ( node.nodeType === 1 ) return false;
1971
+ }
1972
+ return true;
1973
+ case 'nth':
1974
+ var first = match[2], last = match[3];
1748
1975
 
1976
+ if ( first == 1 && last == 0 ) {
1977
+ return true;
1978
+ }
1979
+
1980
+ var doneName = match[0],
1981
+ parent = elem.parentNode;
1982
+
1983
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
1984
+ var count = 0;
1985
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
1986
+ if ( node.nodeType === 1 ) {
1987
+ node.nodeIndex = ++count;
1988
+ }
1989
+ }
1990
+ parent.sizcache = doneName;
1991
+ }
1992
+
1993
+ var diff = elem.nodeIndex - last;
1749
1994
  if ( first == 0 ) {
1750
- if ( node.nodeIndex == last )
1751
- add = true;
1752
- } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1753
- add = true;
1995
+ return diff == 0;
1996
+ } else {
1997
+ return ( diff % first == 0 && diff / first >= 0 );
1998
+ }
1999
+ }
2000
+ },
2001
+ ID: function(elem, match){
2002
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
2003
+ },
2004
+ TAG: function(elem, match){
2005
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
2006
+ },
2007
+ CLASS: function(elem, match){
2008
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
2009
+ .indexOf( match ) > -1;
2010
+ },
2011
+ ATTR: function(elem, match){
2012
+ var name = match[1],
2013
+ result = Expr.attrHandle[ name ] ?
2014
+ Expr.attrHandle[ name ]( elem ) :
2015
+ elem[ name ] != null ?
2016
+ elem[ name ] :
2017
+ elem.getAttribute( name ),
2018
+ value = result + "",
2019
+ type = match[2],
2020
+ check = match[4];
2021
+
2022
+ return result == null ?
2023
+ type === "!=" :
2024
+ type === "=" ?
2025
+ value === check :
2026
+ type === "*=" ?
2027
+ value.indexOf(check) >= 0 :
2028
+ type === "~=" ?
2029
+ (" " + value + " ").indexOf(check) >= 0 :
2030
+ !check ?
2031
+ value && result !== false :
2032
+ type === "!=" ?
2033
+ value != check :
2034
+ type === "^=" ?
2035
+ value.indexOf(check) === 0 :
2036
+ type === "$=" ?
2037
+ value.substr(value.length - check.length) === check :
2038
+ type === "|=" ?
2039
+ value === check || value.substr(0, check.length + 1) === check + "-" :
2040
+ false;
2041
+ },
2042
+ POS: function(elem, match, i, array){
2043
+ var name = match[2], filter = Expr.setFilters[ name ];
1754
2044
 
1755
- if ( add ^ not )
1756
- tmp.push( node );
1757
- }
2045
+ if ( filter ) {
2046
+ return filter( elem, i, match, array );
2047
+ }
2048
+ }
2049
+ }
2050
+ };
2051
+
2052
+ var origPOS = Expr.match.POS;
2053
+
2054
+ for ( var type in Expr.match ) {
2055
+ Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2056
+ }
2057
+
2058
+ var makeArray = function(array, results) {
2059
+ array = Array.prototype.slice.call( array );
2060
+
2061
+ if ( results ) {
2062
+ results.push.apply( results, array );
2063
+ return results;
2064
+ }
2065
+
2066
+ return array;
2067
+ };
2068
+
2069
+ // Perform a simple check to determine if the browser is capable of
2070
+ // converting a NodeList to an array using builtin methods.
2071
+ try {
2072
+ Array.prototype.slice.call( document.documentElement.childNodes );
1758
2073
 
1759
- r = tmp;
2074
+ // Provide a fallback method if it does not work
2075
+ } catch(e){
2076
+ makeArray = function(array, results) {
2077
+ var ret = results || [];
1760
2078
 
1761
- // Otherwise, find the expression to execute
2079
+ if ( toString.call(array) === "[object Array]" ) {
2080
+ Array.prototype.push.apply( ret, array );
2081
+ } else {
2082
+ if ( typeof array.length === "number" ) {
2083
+ for ( var i = 0, l = array.length; i < l; i++ ) {
2084
+ ret.push( array[i] );
2085
+ }
1762
2086
  } else {
1763
- var fn = jQuery.expr[ m[1] ];
1764
- if ( typeof fn == "object" )
1765
- fn = fn[ m[2] ];
2087
+ for ( var i = 0; array[i]; i++ ) {
2088
+ ret.push( array[i] );
2089
+ }
2090
+ }
2091
+ }
2092
+
2093
+ return ret;
2094
+ };
2095
+ }
1766
2096
 
1767
- if ( typeof fn == "string" )
1768
- fn = eval("false||function(a,i){return " + fn + ";}");
2097
+ var sortOrder;
2098
+
2099
+ if ( document.documentElement.compareDocumentPosition ) {
2100
+ sortOrder = function( a, b ) {
2101
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2102
+ if ( ret === 0 ) {
2103
+ hasDuplicate = true;
2104
+ }
2105
+ return ret;
2106
+ };
2107
+ } else if ( "sourceIndex" in document.documentElement ) {
2108
+ sortOrder = function( a, b ) {
2109
+ var ret = a.sourceIndex - b.sourceIndex;
2110
+ if ( ret === 0 ) {
2111
+ hasDuplicate = true;
2112
+ }
2113
+ return ret;
2114
+ };
2115
+ } else if ( document.createRange ) {
2116
+ sortOrder = function( a, b ) {
2117
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
2118
+ aRange.selectNode(a);
2119
+ aRange.collapse(true);
2120
+ bRange.selectNode(b);
2121
+ bRange.collapse(true);
2122
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
2123
+ if ( ret === 0 ) {
2124
+ hasDuplicate = true;
2125
+ }
2126
+ return ret;
2127
+ };
2128
+ }
2129
+
2130
+ // Check to see if the browser returns elements by name when
2131
+ // querying by getElementById (and provide a workaround)
2132
+ (function(){
2133
+ // We're going to inject a fake input element with a specified name
2134
+ var form = document.createElement("form"),
2135
+ id = "script" + (new Date).getTime();
2136
+ form.innerHTML = "<input name='" + id + "'/>";
2137
+
2138
+ // Inject it into the root element, check its status, and remove it quickly
2139
+ var root = document.documentElement;
2140
+ root.insertBefore( form, root.firstChild );
2141
+
2142
+ // The workaround has to do additional checks after a getElementById
2143
+ // Which slows things down for other browsers (hence the branching)
2144
+ if ( !!document.getElementById( id ) ) {
2145
+ Expr.find.ID = function(match, context, isXML){
2146
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
2147
+ var m = context.getElementById(match[1]);
2148
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2149
+ }
2150
+ };
2151
+
2152
+ Expr.filter.ID = function(elem, match){
2153
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
2154
+ return elem.nodeType === 1 && node && node.nodeValue === match;
2155
+ };
2156
+ }
2157
+
2158
+ root.removeChild( form );
2159
+ })();
2160
+
2161
+ (function(){
2162
+ // Check to see if the browser returns only elements
2163
+ // when doing getElementsByTagName("*")
2164
+
2165
+ // Create a fake element
2166
+ var div = document.createElement("div");
2167
+ div.appendChild( document.createComment("") );
2168
+
2169
+ // Make sure no comments are found
2170
+ if ( div.getElementsByTagName("*").length > 0 ) {
2171
+ Expr.find.TAG = function(match, context){
2172
+ var results = context.getElementsByTagName(match[1]);
2173
+
2174
+ // Filter out possible comments
2175
+ if ( match[1] === "*" ) {
2176
+ var tmp = [];
2177
+
2178
+ for ( var i = 0; results[i]; i++ ) {
2179
+ if ( results[i].nodeType === 1 ) {
2180
+ tmp.push( results[i] );
2181
+ }
2182
+ }
1769
2183
 
1770
- // Execute it against the current filter
1771
- r = jQuery.grep( r, function(elem, i){
1772
- return fn(elem, i, m, r);
1773
- }, not );
2184
+ results = tmp;
1774
2185
  }
2186
+
2187
+ return results;
2188
+ };
2189
+ }
2190
+
2191
+ // Check to see if an attribute returns normalized href attributes
2192
+ div.innerHTML = "<a href='#'></a>";
2193
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
2194
+ div.firstChild.getAttribute("href") !== "#" ) {
2195
+ Expr.attrHandle.href = function(elem){
2196
+ return elem.getAttribute("href", 2);
2197
+ };
2198
+ }
2199
+ })();
2200
+
2201
+ if ( document.querySelectorAll ) (function(){
2202
+ var oldSizzle = Sizzle, div = document.createElement("div");
2203
+ div.innerHTML = "<p class='TEST'></p>";
2204
+
2205
+ // Safari can't handle uppercase or unicode characters when
2206
+ // in quirks mode.
2207
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2208
+ return;
2209
+ }
2210
+
2211
+ Sizzle = function(query, context, extra, seed){
2212
+ context = context || document;
2213
+
2214
+ // Only use querySelectorAll on non-XML documents
2215
+ // (ID selectors don't work in non-HTML documents)
2216
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
2217
+ try {
2218
+ return makeArray( context.querySelectorAll(query), extra );
2219
+ } catch(e){}
1775
2220
  }
2221
+
2222
+ return oldSizzle(query, context, extra, seed);
2223
+ };
1776
2224
 
1777
- // Return an array of filtered elements (r)
1778
- // and the modified expression string (t)
1779
- return { r: r, t: t };
1780
- },
2225
+ Sizzle.find = oldSizzle.find;
2226
+ Sizzle.filter = oldSizzle.filter;
2227
+ Sizzle.selectors = oldSizzle.selectors;
2228
+ Sizzle.matches = oldSizzle.matches;
2229
+ })();
2230
+
2231
+ if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
2232
+ var div = document.createElement("div");
2233
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
2234
+
2235
+ // Opera can't find a second classname (in 9.6)
2236
+ if ( div.getElementsByClassName("e").length === 0 )
2237
+ return;
1781
2238
 
1782
- dir: function( elem, dir ){
1783
- var matched = [],
1784
- cur = elem[dir];
1785
- while ( cur && cur != document ) {
1786
- if ( cur.nodeType == 1 )
1787
- matched.push( cur );
1788
- cur = cur[dir];
2239
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
2240
+ div.lastChild.className = "e";
2241
+
2242
+ if ( div.getElementsByClassName("e").length === 1 )
2243
+ return;
2244
+
2245
+ Expr.order.splice(1, 0, "CLASS");
2246
+ Expr.find.CLASS = function(match, context, isXML) {
2247
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
2248
+ return context.getElementsByClassName(match[1]);
1789
2249
  }
1790
- return matched;
1791
- },
2250
+ };
2251
+ })();
2252
+
2253
+ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2254
+ var sibDir = dir == "previousSibling" && !isXML;
2255
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2256
+ var elem = checkSet[i];
2257
+ if ( elem ) {
2258
+ if ( sibDir && elem.nodeType === 1 ){
2259
+ elem.sizcache = doneName;
2260
+ elem.sizset = i;
2261
+ }
2262
+ elem = elem[dir];
2263
+ var match = false;
1792
2264
 
1793
- nth: function(cur,result,dir,elem){
1794
- result = result || 1;
1795
- var num = 0;
2265
+ while ( elem ) {
2266
+ if ( elem.sizcache === doneName ) {
2267
+ match = checkSet[elem.sizset];
2268
+ break;
2269
+ }
1796
2270
 
1797
- for ( ; cur; cur = cur[dir] )
1798
- if ( cur.nodeType == 1 && ++num == result )
1799
- break;
2271
+ if ( elem.nodeType === 1 && !isXML ){
2272
+ elem.sizcache = doneName;
2273
+ elem.sizset = i;
2274
+ }
1800
2275
 
1801
- return cur;
1802
- },
2276
+ if ( elem.nodeName === cur ) {
2277
+ match = elem;
2278
+ break;
2279
+ }
1803
2280
 
1804
- sibling: function( n, elem ) {
1805
- var r = [];
2281
+ elem = elem[dir];
2282
+ }
1806
2283
 
1807
- for ( ; n; n = n.nextSibling ) {
1808
- if ( n.nodeType == 1 && n != elem )
1809
- r.push( n );
2284
+ checkSet[i] = match;
1810
2285
  }
2286
+ }
2287
+ }
2288
+
2289
+ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2290
+ var sibDir = dir == "previousSibling" && !isXML;
2291
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2292
+ var elem = checkSet[i];
2293
+ if ( elem ) {
2294
+ if ( sibDir && elem.nodeType === 1 ) {
2295
+ elem.sizcache = doneName;
2296
+ elem.sizset = i;
2297
+ }
2298
+ elem = elem[dir];
2299
+ var match = false;
2300
+
2301
+ while ( elem ) {
2302
+ if ( elem.sizcache === doneName ) {
2303
+ match = checkSet[elem.sizset];
2304
+ break;
2305
+ }
2306
+
2307
+ if ( elem.nodeType === 1 ) {
2308
+ if ( !isXML ) {
2309
+ elem.sizcache = doneName;
2310
+ elem.sizset = i;
2311
+ }
2312
+ if ( typeof cur !== "string" ) {
2313
+ if ( elem === cur ) {
2314
+ match = true;
2315
+ break;
2316
+ }
2317
+
2318
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2319
+ match = elem;
2320
+ break;
2321
+ }
2322
+ }
2323
+
2324
+ elem = elem[dir];
2325
+ }
1811
2326
 
1812
- return r;
2327
+ checkSet[i] = match;
2328
+ }
1813
2329
  }
1814
- });
2330
+ }
2331
+
2332
+ var contains = document.compareDocumentPosition ? function(a, b){
2333
+ return a.compareDocumentPosition(b) & 16;
2334
+ } : function(a, b){
2335
+ return a !== b && (a.contains ? a.contains(b) : true);
2336
+ };
2337
+
2338
+ var isXML = function(elem){
2339
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
2340
+ !!elem.ownerDocument && isXML( elem.ownerDocument );
2341
+ };
2342
+
2343
+ var posProcess = function(selector, context){
2344
+ var tmpSet = [], later = "", match,
2345
+ root = context.nodeType ? [context] : context;
2346
+
2347
+ // Position selectors must be done after the filter
2348
+ // And so must :not(positional) so we move all PSEUDOs to the end
2349
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
2350
+ later += match[0];
2351
+ selector = selector.replace( Expr.match.PSEUDO, "" );
2352
+ }
2353
+
2354
+ selector = Expr.relative[selector] ? selector + "*" : selector;
2355
+
2356
+ for ( var i = 0, l = root.length; i < l; i++ ) {
2357
+ Sizzle( selector, root[i], tmpSet );
2358
+ }
2359
+
2360
+ return Sizzle.filter( later, tmpSet );
2361
+ };
2362
+
2363
+ // EXPOSE
2364
+ jQuery.find = Sizzle;
2365
+ jQuery.filter = Sizzle.filter;
2366
+ jQuery.expr = Sizzle.selectors;
2367
+ jQuery.expr[":"] = jQuery.expr.filters;
2368
+
2369
+ Sizzle.selectors.filters.hidden = function(elem){
2370
+ return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2371
+ };
2372
+
2373
+ Sizzle.selectors.filters.visible = function(elem){
2374
+ return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2375
+ };
2376
+
2377
+ Sizzle.selectors.filters.animated = function(elem){
2378
+ return jQuery.grep(jQuery.timers, function(fn){
2379
+ return elem === fn.elem;
2380
+ }).length;
2381
+ };
2382
+
2383
+ jQuery.multiFilter = function( expr, elems, not ) {
2384
+ if ( not ) {
2385
+ expr = ":not(" + expr + ")";
2386
+ }
2387
+
2388
+ return Sizzle.matches(expr, elems);
2389
+ };
2390
+
2391
+ jQuery.dir = function( elem, dir ){
2392
+ var matched = [], cur = elem[dir];
2393
+ while ( cur && cur != document ) {
2394
+ if ( cur.nodeType == 1 )
2395
+ matched.push( cur );
2396
+ cur = cur[dir];
2397
+ }
2398
+ return matched;
2399
+ };
2400
+
2401
+ jQuery.nth = function(cur, result, dir, elem){
2402
+ result = result || 1;
2403
+ var num = 0;
2404
+
2405
+ for ( ; cur; cur = cur[dir] )
2406
+ if ( cur.nodeType == 1 && ++num == result )
2407
+ break;
2408
+
2409
+ return cur;
2410
+ };
2411
+
2412
+ jQuery.sibling = function(n, elem){
2413
+ var r = [];
2414
+
2415
+ for ( ; n; n = n.nextSibling ) {
2416
+ if ( n.nodeType == 1 && n != elem )
2417
+ r.push( n );
2418
+ }
2419
+
2420
+ return r;
2421
+ };
2422
+
2423
+ return;
2424
+
2425
+ window.Sizzle = Sizzle;
2426
+
2427
+ })();
1815
2428
  /*
1816
2429
  * A number of helper functions used for managing events.
1817
- * Many of the ideas behind this code orignated from
2430
+ * Many of the ideas behind this code originated from
1818
2431
  * Dean Edwards' addEvent library.
1819
2432
  */
1820
2433
  jQuery.event = {
@@ -1827,7 +2440,7 @@ jQuery.event = {
1827
2440
 
1828
2441
  // For whatever reason, IE has trouble passing the window object
1829
2442
  // around, causing it to be cloned in the process
1830
- if ( jQuery.browser.msie && elem.setInterval )
2443
+ if ( elem.setInterval && elem != window )
1831
2444
  elem = window;
1832
2445
 
1833
2446
  // Make sure that the function being executed has a unique ID
@@ -1835,15 +2448,12 @@ jQuery.event = {
1835
2448
  handler.guid = this.guid++;
1836
2449
 
1837
2450
  // if data is passed, bind to handler
1838
- if( data != undefined ) {
2451
+ if ( data !== undefined ) {
1839
2452
  // Create temporary function pointer to original handler
1840
2453
  var fn = handler;
1841
2454
 
1842
2455
  // Create unique handler function, wrapped around original handler
1843
- handler = this.proxy( fn, function() {
1844
- // Pass arguments and context to original handler
1845
- return fn.apply(this, arguments);
1846
- });
2456
+ handler = this.proxy( fn );
1847
2457
 
1848
2458
  // Store data in unique handler
1849
2459
  handler.data = data;
@@ -1854,8 +2464,9 @@ jQuery.event = {
1854
2464
  handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
1855
2465
  // Handle the second event of a trigger and when
1856
2466
  // an event is called after a page has unloaded
1857
- if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
1858
- return jQuery.event.handle.apply(arguments.callee.elem, arguments);
2467
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2468
+ jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2469
+ undefined;
1859
2470
  });
1860
2471
  // Add elem as a property of the handle function
1861
2472
  // This is to prevent a memory leak with non-native
@@ -1866,12 +2477,15 @@ jQuery.event = {
1866
2477
  // jQuery(...).bind("mouseover mouseout", fn);
1867
2478
  jQuery.each(types.split(/\s+/), function(index, type) {
1868
2479
  // Namespaced event handlers
1869
- var parts = type.split(".");
1870
- type = parts[0];
1871
- handler.type = parts[1];
2480
+ var namespaces = type.split(".");
2481
+ type = namespaces.shift();
2482
+ handler.type = namespaces.slice().sort().join(".");
1872
2483
 
1873
2484
  // Get the current list of functions bound to this event
1874
2485
  var handlers = events[type];
2486
+
2487
+ if ( jQuery.event.specialAll[type] )
2488
+ jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
1875
2489
 
1876
2490
  // Init the event handler queue
1877
2491
  if (!handlers) {
@@ -1880,7 +2494,7 @@ jQuery.event = {
1880
2494
  // Check for a special event handler
1881
2495
  // Only use addEventListener/attachEvent if the special
1882
2496
  // events handler returns false
1883
- if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
2497
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
1884
2498
  // Bind the global event handler to the element
1885
2499
  if (elem.addEventListener)
1886
2500
  elem.addEventListener(type, handle, false);
@@ -1913,7 +2527,7 @@ jQuery.event = {
1913
2527
 
1914
2528
  if ( events ) {
1915
2529
  // Unbind all events for the element
1916
- if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
2530
+ if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
1917
2531
  for ( var type in events )
1918
2532
  this.remove( elem, type + (types || "") );
1919
2533
  else {
@@ -1927,8 +2541,9 @@ jQuery.event = {
1927
2541
  // jQuery(...).unbind("mouseover mouseout", fn);
1928
2542
  jQuery.each(types.split(/\s+/), function(index, type){
1929
2543
  // Namespaced event handlers
1930
- var parts = type.split(".");
1931
- type = parts[0];
2544
+ var namespaces = type.split(".");
2545
+ type = namespaces.shift();
2546
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
1932
2547
 
1933
2548
  if ( events[type] ) {
1934
2549
  // remove the given handler for the given type
@@ -1937,15 +2552,18 @@ jQuery.event = {
1937
2552
 
1938
2553
  // remove all handlers for the given type
1939
2554
  else
1940
- for ( handler in events[type] )
2555
+ for ( var handle in events[type] )
1941
2556
  // Handle the removal of namespaced events
1942
- if ( !parts[1] || events[type][handler].type == parts[1] )
1943
- delete events[type][handler];
2557
+ if ( namespace.test(events[type][handle].type) )
2558
+ delete events[type][handle];
2559
+
2560
+ if ( jQuery.event.specialAll[type] )
2561
+ jQuery.event.specialAll[type].teardown.call(elem, namespaces);
1944
2562
 
1945
2563
  // remove generic event handler if no more handlers exist
1946
2564
  for ( ret in events[type] ) break;
1947
2565
  if ( !ret ) {
1948
- if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
2566
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
1949
2567
  if (elem.removeEventListener)
1950
2568
  elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
1951
2569
  else if (elem.detachEvent)
@@ -1969,97 +2587,96 @@ jQuery.event = {
1969
2587
  }
1970
2588
  },
1971
2589
 
1972
- trigger: function(type, data, elem, donative, extra) {
1973
- // Clone the incoming data, if any
1974
- data = jQuery.makeArray(data);
2590
+ // bubbling is internal
2591
+ trigger: function( event, data, elem, bubbling ) {
2592
+ // Event object or event type
2593
+ var type = event.type || event;
2594
+
2595
+ if( !bubbling ){
2596
+ event = typeof event === "object" ?
2597
+ // jQuery.Event object
2598
+ event[expando] ? event :
2599
+ // Object literal
2600
+ jQuery.extend( jQuery.Event(type), event ) :
2601
+ // Just the event type (string)
2602
+ jQuery.Event(type);
2603
+
2604
+ if ( type.indexOf("!") >= 0 ) {
2605
+ event.type = type = type.slice(0, -1);
2606
+ event.exclusive = true;
2607
+ }
1975
2608
 
1976
- if ( type.indexOf("!") >= 0 ) {
1977
- type = type.slice(0, -1);
1978
- var exclusive = true;
1979
- }
2609
+ // Handle a global trigger
2610
+ if ( !elem ) {
2611
+ // Don't bubble custom events when global (to avoid too much overhead)
2612
+ event.stopPropagation();
2613
+ // Only trigger if we've ever bound an event for it
2614
+ if ( this.global[type] )
2615
+ jQuery.each( jQuery.cache, function(){
2616
+ if ( this.events && this.events[type] )
2617
+ jQuery.event.trigger( event, data, this.handle.elem );
2618
+ });
2619
+ }
1980
2620
 
1981
- // Handle a global trigger
1982
- if ( !elem ) {
1983
- // Only trigger if we've ever bound an event for it
1984
- if ( this.global[type] )
1985
- jQuery("*").add([window, document]).trigger(type, data);
2621
+ // Handle triggering a single element
1986
2622
 
1987
- // Handle triggering a single element
1988
- } else {
1989
2623
  // don't do events on text and comment nodes
1990
- if ( elem.nodeType == 3 || elem.nodeType == 8 )
2624
+ if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
1991
2625
  return undefined;
2626
+
2627
+ // Clean up in case it is reused
2628
+ event.result = undefined;
2629
+ event.target = elem;
2630
+
2631
+ // Clone the incoming data, if any
2632
+ data = jQuery.makeArray(data);
2633
+ data.unshift( event );
2634
+ }
1992
2635
 
1993
- var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
1994
- // Check to see if we need to provide a fake event, or not
1995
- event = !data[0] || !data[0].preventDefault;
1996
-
1997
- // Pass along a fake event
1998
- if ( event ) {
1999
- data.unshift({
2000
- type: type,
2001
- target: elem,
2002
- preventDefault: function(){},
2003
- stopPropagation: function(){},
2004
- timeStamp: now()
2005
- });
2006
- data[0][expando] = true; // no need to fix fake event
2007
- }
2008
-
2009
- // Enforce the right trigger type
2010
- data[0].type = type;
2011
- if ( exclusive )
2012
- data[0].exclusive = true;
2013
-
2014
- // Trigger the event, it is assumed that "handle" is a function
2015
- var handle = jQuery.data(elem, "handle");
2016
- if ( handle )
2017
- val = handle.apply( elem, data );
2018
-
2019
- // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2020
- if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2021
- val = false;
2022
-
2023
- // Extra functions don't get the custom event object
2024
- if ( event )
2025
- data.shift();
2636
+ event.currentTarget = elem;
2026
2637
 
2027
- // Handle triggering of extra function
2028
- if ( extra && jQuery.isFunction( extra ) ) {
2029
- // call the extra function and tack the current return value on the end for possible inspection
2030
- ret = extra.apply( elem, val == null ? data : data.concat( val ) );
2031
- // if anything is returned, give it precedence and have it overwrite the previous value
2032
- if (ret !== undefined)
2033
- val = ret;
2034
- }
2638
+ // Trigger the event, it is assumed that "handle" is a function
2639
+ var handle = jQuery.data(elem, "handle");
2640
+ if ( handle )
2641
+ handle.apply( elem, data );
2035
2642
 
2036
- // Trigger the native events (except for clicks on links)
2037
- if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2038
- this.triggered = true;
2039
- try {
2040
- elem[ type ]();
2041
- // prevent IE from throwing an error for some hidden elements
2042
- } catch (e) {}
2043
- }
2643
+ // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2644
+ if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2645
+ event.result = false;
2044
2646
 
2045
- this.triggered = false;
2647
+ // Trigger the native events (except for clicks on links)
2648
+ if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2649
+ this.triggered = true;
2650
+ try {
2651
+ elem[ type ]();
2652
+ // prevent IE from throwing an error for some hidden elements
2653
+ } catch (e) {}
2046
2654
  }
2047
2655
 
2048
- return val;
2656
+ this.triggered = false;
2657
+
2658
+ if ( !event.isPropagationStopped() ) {
2659
+ var parent = elem.parentNode || elem.ownerDocument;
2660
+ if ( parent )
2661
+ jQuery.event.trigger(event, data, parent, true);
2662
+ }
2049
2663
  },
2050
2664
 
2051
2665
  handle: function(event) {
2052
2666
  // returned undefined or false
2053
- var val, ret, namespace, all, handlers;
2667
+ var all, handlers;
2054
2668
 
2055
2669
  event = arguments[0] = jQuery.event.fix( event || window.event );
2056
-
2670
+ event.currentTarget = this;
2671
+
2057
2672
  // Namespaced event handlers
2058
- namespace = event.type.split(".");
2059
- event.type = namespace[0];
2060
- namespace = namespace[1];
2673
+ var namespaces = event.type.split(".");
2674
+ event.type = namespaces.shift();
2675
+
2061
2676
  // Cache this now, all = true means, any handler
2062
- all = !namespace && !event.exclusive;
2677
+ all = !namespaces.length && !event.exclusive;
2678
+
2679
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2063
2680
 
2064
2681
  handlers = ( jQuery.data(this, "events") || {} )[event.type];
2065
2682
 
@@ -2067,61 +2684,44 @@ jQuery.event = {
2067
2684
  var handler = handlers[j];
2068
2685
 
2069
2686
  // Filter the functions by class
2070
- if ( all || handler.type == namespace ) {
2687
+ if ( all || namespace.test(handler.type) ) {
2071
2688
  // Pass in a reference to the handler function itself
2072
2689
  // So that we can later remove it
2073
2690
  event.handler = handler;
2074
2691
  event.data = handler.data;
2075
2692
 
2076
- ret = handler.apply( this, arguments );
2693
+ var ret = handler.apply(this, arguments);
2077
2694
 
2078
- if ( val !== false )
2079
- val = ret;
2080
-
2081
- if ( ret === false ) {
2082
- event.preventDefault();
2083
- event.stopPropagation();
2695
+ if( ret !== undefined ){
2696
+ event.result = ret;
2697
+ if ( ret === false ) {
2698
+ event.preventDefault();
2699
+ event.stopPropagation();
2700
+ }
2084
2701
  }
2702
+
2703
+ if( event.isImmediatePropagationStopped() )
2704
+ break;
2705
+
2085
2706
  }
2086
2707
  }
2087
-
2088
- return val;
2089
2708
  },
2090
2709
 
2710
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2711
+
2091
2712
  fix: function(event) {
2092
- if ( event[expando] == true )
2713
+ if ( event[expando] )
2093
2714
  return event;
2094
2715
 
2095
2716
  // store a copy of the original event object
2096
2717
  // and "clone" to set read-only properties
2097
2718
  var originalEvent = event;
2098
- event = { originalEvent: originalEvent };
2099
- var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
2100
- for ( var i=props.length; i; i-- )
2101
- event[ props[i] ] = originalEvent[ props[i] ];
2102
-
2103
- // Mark it as fixed
2104
- event[expando] = true;
2105
-
2106
- // add preventDefault and stopPropagation since
2107
- // they will not work on the clone
2108
- event.preventDefault = function() {
2109
- // if preventDefault exists run it on the original event
2110
- if (originalEvent.preventDefault)
2111
- originalEvent.preventDefault();
2112
- // otherwise set the returnValue property of the original event to false (IE)
2113
- originalEvent.returnValue = false;
2114
- };
2115
- event.stopPropagation = function() {
2116
- // if stopPropagation exists run it on the original event
2117
- if (originalEvent.stopPropagation)
2118
- originalEvent.stopPropagation();
2119
- // otherwise set the cancelBubble property of the original event to true (IE)
2120
- originalEvent.cancelBubble = true;
2121
- };
2719
+ event = jQuery.Event( originalEvent );
2122
2720
 
2123
- // Fix timeStamp
2124
- event.timeStamp = event.timeStamp || now();
2721
+ for ( var i = this.props.length, prop; i; ){
2722
+ prop = this.props[ --i ];
2723
+ event[ prop ] = originalEvent[ prop ];
2724
+ }
2125
2725
 
2126
2726
  // Fix target property, if necessary
2127
2727
  if ( !event.target )
@@ -2159,6 +2759,7 @@ jQuery.event = {
2159
2759
  },
2160
2760
 
2161
2761
  proxy: function( fn, proxy ){
2762
+ proxy = proxy || function(){ return fn.apply(this, arguments); };
2162
2763
  // Set the guid of unique handler to the same of original handler, so it can be removed
2163
2764
  proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2164
2765
  // So proxy can be declared as an argument
@@ -2167,60 +2768,128 @@ jQuery.event = {
2167
2768
 
2168
2769
  special: {
2169
2770
  ready: {
2170
- setup: function() {
2171
- // Make sure the ready event is setup
2172
- bindReady();
2173
- return;
2174
- },
2175
-
2176
- teardown: function() { return; }
2177
- },
2178
-
2179
- mouseenter: {
2180
- setup: function() {
2181
- if ( jQuery.browser.msie ) return false;
2182
- jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2183
- return true;
2771
+ // Make sure the ready event is setup
2772
+ setup: bindReady,
2773
+ teardown: function() {}
2774
+ }
2775
+ },
2776
+
2777
+ specialAll: {
2778
+ live: {
2779
+ setup: function( selector, namespaces ){
2780
+ jQuery.event.add( this, namespaces[0], liveHandler );
2184
2781
  },
2782
+ teardown: function( namespaces ){
2783
+ if ( namespaces.length ) {
2784
+ var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2785
+
2786
+ jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2787
+ if ( name.test(this.type) )
2788
+ remove++;
2789
+ });
2790
+
2791
+ if ( remove < 1 )
2792
+ jQuery.event.remove( this, namespaces[0], liveHandler );
2793
+ }
2794
+ }
2795
+ }
2796
+ }
2797
+ };
2185
2798
 
2186
- teardown: function() {
2187
- if ( jQuery.browser.msie ) return false;
2188
- jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2189
- return true;
2190
- },
2799
+ jQuery.Event = function( src ){
2800
+ // Allow instantiation without the 'new' keyword
2801
+ if( !this.preventDefault )
2802
+ return new jQuery.Event(src);
2803
+
2804
+ // Event object
2805
+ if( src && src.type ){
2806
+ this.originalEvent = src;
2807
+ this.type = src.type;
2808
+ // Event type
2809
+ }else
2810
+ this.type = src;
2811
+
2812
+ // timeStamp is buggy for some events on Firefox(#3843)
2813
+ // So we won't rely on the native value
2814
+ this.timeStamp = now();
2815
+
2816
+ // Mark it as fixed
2817
+ this[expando] = true;
2818
+ };
2191
2819
 
2192
- handler: function(event) {
2193
- // If we actually just moused on to a sub-element, ignore it
2194
- if ( withinElement(event, this) ) return true;
2195
- // Execute the right handlers by setting the event type to mouseenter
2196
- event.type = "mouseenter";
2197
- return jQuery.event.handle.apply(this, arguments);
2198
- }
2199
- },
2820
+ function returnFalse(){
2821
+ return false;
2822
+ }
2823
+ function returnTrue(){
2824
+ return true;
2825
+ }
2200
2826
 
2201
- mouseleave: {
2202
- setup: function() {
2203
- if ( jQuery.browser.msie ) return false;
2204
- jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2205
- return true;
2206
- },
2827
+ // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2828
+ // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2829
+ jQuery.Event.prototype = {
2830
+ preventDefault: function() {
2831
+ this.isDefaultPrevented = returnTrue;
2207
2832
 
2208
- teardown: function() {
2209
- if ( jQuery.browser.msie ) return false;
2210
- jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2211
- return true;
2212
- },
2833
+ var e = this.originalEvent;
2834
+ if( !e )
2835
+ return;
2836
+ // if preventDefault exists run it on the original event
2837
+ if (e.preventDefault)
2838
+ e.preventDefault();
2839
+ // otherwise set the returnValue property of the original event to false (IE)
2840
+ e.returnValue = false;
2841
+ },
2842
+ stopPropagation: function() {
2843
+ this.isPropagationStopped = returnTrue;
2213
2844
 
2214
- handler: function(event) {
2215
- // If we actually just moused on to a sub-element, ignore it
2216
- if ( withinElement(event, this) ) return true;
2217
- // Execute the right handlers by setting the event type to mouseleave
2218
- event.type = "mouseleave";
2219
- return jQuery.event.handle.apply(this, arguments);
2220
- }
2221
- }
2845
+ var e = this.originalEvent;
2846
+ if( !e )
2847
+ return;
2848
+ // if stopPropagation exists run it on the original event
2849
+ if (e.stopPropagation)
2850
+ e.stopPropagation();
2851
+ // otherwise set the cancelBubble property of the original event to true (IE)
2852
+ e.cancelBubble = true;
2853
+ },
2854
+ stopImmediatePropagation:function(){
2855
+ this.isImmediatePropagationStopped = returnTrue;
2856
+ this.stopPropagation();
2857
+ },
2858
+ isDefaultPrevented: returnFalse,
2859
+ isPropagationStopped: returnFalse,
2860
+ isImmediatePropagationStopped: returnFalse
2861
+ };
2862
+ // Checks if an event happened on an element within another element
2863
+ // Used in jQuery.event.special.mouseenter and mouseleave handlers
2864
+ var withinElement = function(event) {
2865
+ // Check if mouse(over|out) are still within the same parent element
2866
+ var parent = event.relatedTarget;
2867
+ // Traverse up the tree
2868
+ while ( parent && parent != this )
2869
+ try { parent = parent.parentNode; }
2870
+ catch(e) { parent = this; }
2871
+
2872
+ if( parent != this ){
2873
+ // set the correct event type
2874
+ event.type = event.data;
2875
+ // handle event if we actually just moused on to a non sub-element
2876
+ jQuery.event.handle.apply( this, arguments );
2222
2877
  }
2223
2878
  };
2879
+
2880
+ jQuery.each({
2881
+ mouseover: 'mouseenter',
2882
+ mouseout: 'mouseleave'
2883
+ }, function( orig, fix ){
2884
+ jQuery.event.special[ fix ] = {
2885
+ setup: function(){
2886
+ jQuery.event.add( this, orig, withinElement, fix );
2887
+ },
2888
+ teardown: function(){
2889
+ jQuery.event.remove( this, orig, withinElement );
2890
+ }
2891
+ };
2892
+ });
2224
2893
 
2225
2894
  jQuery.fn.extend({
2226
2895
  bind: function( type, data, fn ) {
@@ -2245,14 +2914,20 @@ jQuery.fn.extend({
2245
2914
  });
2246
2915
  },
2247
2916
 
2248
- trigger: function( type, data, fn ) {
2917
+ trigger: function( type, data ) {
2249
2918
  return this.each(function(){
2250
- jQuery.event.trigger( type, data, this, true, fn );
2919
+ jQuery.event.trigger( type, data, this );
2251
2920
  });
2252
2921
  },
2253
2922
 
2254
- triggerHandler: function( type, data, fn ) {
2255
- return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
2923
+ triggerHandler: function( type, data ) {
2924
+ if( this[0] ){
2925
+ var event = jQuery.Event(type);
2926
+ event.preventDefault();
2927
+ event.stopPropagation();
2928
+ jQuery.event.trigger( event, data, this[0] );
2929
+ return event.result;
2930
+ }
2256
2931
  },
2257
2932
 
2258
2933
  toggle: function( fn ) {
@@ -2276,7 +2951,7 @@ jQuery.fn.extend({
2276
2951
  },
2277
2952
 
2278
2953
  hover: function(fnOver, fnOut) {
2279
- return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2954
+ return this.mouseenter(fnOver).mouseleave(fnOut);
2280
2955
  },
2281
2956
 
2282
2957
  ready: function(fn) {
@@ -2291,12 +2966,55 @@ jQuery.fn.extend({
2291
2966
  // Otherwise, remember the function for later
2292
2967
  else
2293
2968
  // Add the function to the wait list
2294
- jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2969
+ jQuery.readyList.push( fn );
2970
+
2971
+ return this;
2972
+ },
2973
+
2974
+ live: function( type, fn ){
2975
+ var proxy = jQuery.event.proxy( fn );
2976
+ proxy.guid += this.selector + type;
2977
+
2978
+ jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2295
2979
 
2980
+ return this;
2981
+ },
2982
+
2983
+ die: function( type, fn ){
2984
+ jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
2296
2985
  return this;
2297
2986
  }
2298
2987
  });
2299
2988
 
2989
+ function liveHandler( event ){
2990
+ var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
2991
+ stop = true,
2992
+ elems = [];
2993
+
2994
+ jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
2995
+ if ( check.test(fn.type) ) {
2996
+ var elem = jQuery(event.target).closest(fn.data)[0];
2997
+ if ( elem )
2998
+ elems.push({ elem: elem, fn: fn });
2999
+ }
3000
+ });
3001
+
3002
+ elems.sort(function(a,b) {
3003
+ return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
3004
+ });
3005
+
3006
+ jQuery.each(elems, function(){
3007
+ if ( this.fn.call(this.elem, event, this.fn.data) === false )
3008
+ return (stop = false);
3009
+ });
3010
+
3011
+ return stop;
3012
+ }
3013
+
3014
+ function liveConvert(type, selector){
3015
+ return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
3016
+ }
3017
+
2300
3018
  jQuery.extend({
2301
3019
  isReady: false,
2302
3020
  readyList: [],
@@ -2311,7 +3029,7 @@ jQuery.extend({
2311
3029
  if ( jQuery.readyList ) {
2312
3030
  // Execute all of them
2313
3031
  jQuery.each( jQuery.readyList, function(){
2314
- this.call( document );
3032
+ this.call( document, jQuery );
2315
3033
  });
2316
3034
 
2317
3035
  // Reset the list of functions
@@ -2330,53 +3048,39 @@ function bindReady(){
2330
3048
  if ( readyBound ) return;
2331
3049
  readyBound = true;
2332
3050
 
2333
- // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
2334
- if ( document.addEventListener && !jQuery.browser.opera)
3051
+ // Mozilla, Opera and webkit nightlies currently support this event
3052
+ if ( document.addEventListener ) {
2335
3053
  // Use the handy event callback
2336
- document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
2337
-
2338
- // If IE is used and is not in a frame
2339
- // Continually check to see if the document is ready
2340
- if ( jQuery.browser.msie && window == top ) (function(){
2341
- if (jQuery.isReady) return;
2342
- try {
2343
- // If IE is used, use the trick by Diego Perini
2344
- // http://javascript.nwbox.com/IEContentLoaded/
2345
- document.documentElement.doScroll("left");
2346
- } catch( error ) {
2347
- setTimeout( arguments.callee, 0 );
2348
- return;
2349
- }
2350
- // and execute any waiting functions
2351
- jQuery.ready();
2352
- })();
2353
-
2354
- if ( jQuery.browser.opera )
2355
- document.addEventListener( "DOMContentLoaded", function () {
2356
- if (jQuery.isReady) return;
2357
- for (var i = 0; i < document.styleSheets.length; i++)
2358
- if (document.styleSheets[i].disabled) {
2359
- setTimeout( arguments.callee, 0 );
2360
- return;
2361
- }
2362
- // and execute any waiting functions
3054
+ document.addEventListener( "DOMContentLoaded", function(){
3055
+ document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
2363
3056
  jQuery.ready();
2364
- }, false);
2365
-
2366
- if ( jQuery.browser.safari ) {
2367
- var numStyles;
2368
- (function(){
2369
- if (jQuery.isReady) return;
2370
- if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2371
- setTimeout( arguments.callee, 0 );
2372
- return;
3057
+ }, false );
3058
+
3059
+ // If IE event model is used
3060
+ } else if ( document.attachEvent ) {
3061
+ // ensure firing before onload,
3062
+ // maybe late but safe also for iframes
3063
+ document.attachEvent("onreadystatechange", function(){
3064
+ if ( document.readyState === "complete" ) {
3065
+ document.detachEvent( "onreadystatechange", arguments.callee );
3066
+ jQuery.ready();
2373
3067
  }
2374
- if ( numStyles === undefined )
2375
- numStyles = jQuery("style, link[rel=stylesheet]").length;
2376
- if ( document.styleSheets.length != numStyles ) {
3068
+ });
3069
+
3070
+ // If IE and not an iframe
3071
+ // continually check to see if the document is ready
3072
+ if ( document.documentElement.doScroll && window == window.top ) (function(){
3073
+ if ( jQuery.isReady ) return;
3074
+
3075
+ try {
3076
+ // If IE is used, use the trick by Diego Perini
3077
+ // http://javascript.nwbox.com/IEContentLoaded/
3078
+ document.documentElement.doScroll("left");
3079
+ } catch( error ) {
2377
3080
  setTimeout( arguments.callee, 0 );
2378
3081
  return;
2379
3082
  }
3083
+
2380
3084
  // and execute any waiting functions
2381
3085
  jQuery.ready();
2382
3086
  })();
@@ -2387,8 +3091,8 @@ function bindReady(){
2387
3091
  }
2388
3092
 
2389
3093
  jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2390
- "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
2391
- "submit,keydown,keypress,keyup,error").split(","), function(i, name){
3094
+ "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
3095
+ "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
2392
3096
 
2393
3097
  // Handle event binding
2394
3098
  jQuery.fn[name] = function(fn){
@@ -2396,29 +3100,133 @@ jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2396
3100
  };
2397
3101
  });
2398
3102
 
2399
- // Checks if an event happened on an element within another element
2400
- // Used in jQuery.event.special.mouseenter and mouseleave handlers
2401
- var withinElement = function(event, elem) {
2402
- // Check if mouse(over|out) are still within the same parent element
2403
- var parent = event.relatedTarget;
2404
- // Traverse up the tree
2405
- while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
2406
- // Return true if we actually just moused on to a sub-element
2407
- return parent == elem;
2408
- };
2409
-
2410
3103
  // Prevent memory leaks in IE
2411
3104
  // And prevent errors on refresh with events like mouseover in other browsers
2412
3105
  // Window isn't included so as not to unbind existing unload events
2413
- jQuery(window).bind("unload", function() {
2414
- jQuery("*").add(document).unbind();
2415
- });
3106
+ jQuery( window ).bind( 'unload', function(){
3107
+ for ( var id in jQuery.cache )
3108
+ // Skip the window
3109
+ if ( id != 1 && jQuery.cache[ id ].handle )
3110
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
3111
+ });
3112
+ (function(){
3113
+
3114
+ jQuery.support = {};
3115
+
3116
+ var root = document.documentElement,
3117
+ script = document.createElement("script"),
3118
+ div = document.createElement("div"),
3119
+ id = "script" + (new Date).getTime();
3120
+
3121
+ div.style.display = "none";
3122
+ div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
3123
+
3124
+ var all = div.getElementsByTagName("*"),
3125
+ a = div.getElementsByTagName("a")[0];
3126
+
3127
+ // Can't get basic test support
3128
+ if ( !all || !all.length || !a ) {
3129
+ return;
3130
+ }
3131
+
3132
+ jQuery.support = {
3133
+ // IE strips leading whitespace when .innerHTML is used
3134
+ leadingWhitespace: div.firstChild.nodeType == 3,
3135
+
3136
+ // Make sure that tbody elements aren't automatically inserted
3137
+ // IE will insert them into empty tables
3138
+ tbody: !div.getElementsByTagName("tbody").length,
3139
+
3140
+ // Make sure that you can get all elements in an <object> element
3141
+ // IE 7 always returns no results
3142
+ objectAll: !!div.getElementsByTagName("object")[0]
3143
+ .getElementsByTagName("*").length,
3144
+
3145
+ // Make sure that link elements get serialized correctly by innerHTML
3146
+ // This requires a wrapper element in IE
3147
+ htmlSerialize: !!div.getElementsByTagName("link").length,
3148
+
3149
+ // Get the style information from getAttribute
3150
+ // (IE uses .cssText insted)
3151
+ style: /red/.test( a.getAttribute("style") ),
3152
+
3153
+ // Make sure that URLs aren't manipulated
3154
+ // (IE normalizes it by default)
3155
+ hrefNormalized: a.getAttribute("href") === "/a",
3156
+
3157
+ // Make sure that element opacity exists
3158
+ // (IE uses filter instead)
3159
+ opacity: a.style.opacity === "0.5",
3160
+
3161
+ // Verify style float existence
3162
+ // (IE uses styleFloat instead of cssFloat)
3163
+ cssFloat: !!a.style.cssFloat,
3164
+
3165
+ // Will be defined later
3166
+ scriptEval: false,
3167
+ noCloneEvent: true,
3168
+ boxModel: null
3169
+ };
3170
+
3171
+ script.type = "text/javascript";
3172
+ try {
3173
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
3174
+ } catch(e){}
3175
+
3176
+ root.insertBefore( script, root.firstChild );
3177
+
3178
+ // Make sure that the execution of code works by injecting a script
3179
+ // tag with appendChild/createTextNode
3180
+ // (IE doesn't support this, fails, and uses .text instead)
3181
+ if ( window[ id ] ) {
3182
+ jQuery.support.scriptEval = true;
3183
+ delete window[ id ];
3184
+ }
3185
+
3186
+ root.removeChild( script );
3187
+
3188
+ if ( div.attachEvent && div.fireEvent ) {
3189
+ div.attachEvent("onclick", function(){
3190
+ // Cloning a node shouldn't copy over any
3191
+ // bound event handlers (IE does this)
3192
+ jQuery.support.noCloneEvent = false;
3193
+ div.detachEvent("onclick", arguments.callee);
3194
+ });
3195
+ div.cloneNode(true).fireEvent("onclick");
3196
+ }
3197
+
3198
+ // Figure out if the W3C box model works as expected
3199
+ // document.body must exist before we can do this
3200
+ jQuery(function(){
3201
+ var div = document.createElement("div");
3202
+ div.style.width = div.style.paddingLeft = "1px";
3203
+
3204
+ document.body.appendChild( div );
3205
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3206
+ document.body.removeChild( div ).style.display = 'none';
3207
+ });
3208
+ })();
3209
+
3210
+ var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
3211
+
3212
+ jQuery.props = {
3213
+ "for": "htmlFor",
3214
+ "class": "className",
3215
+ "float": styleFloat,
3216
+ cssFloat: styleFloat,
3217
+ styleFloat: styleFloat,
3218
+ readonly: "readOnly",
3219
+ maxlength: "maxLength",
3220
+ cellspacing: "cellSpacing",
3221
+ rowspan: "rowSpan",
3222
+ tabindex: "tabIndex"
3223
+ };
2416
3224
  jQuery.fn.extend({
2417
3225
  // Keep a copy of the old load
2418
3226
  _load: jQuery.fn.load,
2419
3227
 
2420
3228
  load: function( url, params, callback ) {
2421
- if ( typeof url != 'string' )
3229
+ if ( typeof url !== "string" )
2422
3230
  return this._load( url );
2423
3231
 
2424
3232
  var off = url.indexOf(" ");
@@ -2427,8 +3235,6 @@ jQuery.fn.extend({
2427
3235
  url = url.slice(0, off);
2428
3236
  }
2429
3237
 
2430
- callback = callback || function(){};
2431
-
2432
3238
  // Default to a GET request
2433
3239
  var type = "GET";
2434
3240
 
@@ -2441,7 +3247,7 @@ jQuery.fn.extend({
2441
3247
  params = null;
2442
3248
 
2443
3249
  // Otherwise, build a param string
2444
- } else {
3250
+ } else if( typeof params === "object" ) {
2445
3251
  params = jQuery.param( params );
2446
3252
  type = "POST";
2447
3253
  }
@@ -2471,7 +3277,8 @@ jQuery.fn.extend({
2471
3277
  // If not, just inject the full result
2472
3278
  res.responseText );
2473
3279
 
2474
- self.each( callback, [res.responseText, status, res] );
3280
+ if( callback )
3281
+ self.each( callback, [res.responseText, status, res] );
2475
3282
  }
2476
3283
  });
2477
3284
  return this;
@@ -2482,18 +3289,17 @@ jQuery.fn.extend({
2482
3289
  },
2483
3290
  serializeArray: function() {
2484
3291
  return this.map(function(){
2485
- return jQuery.nodeName(this, "form") ?
2486
- jQuery.makeArray(this.elements) : this;
3292
+ return this.elements ? jQuery.makeArray(this.elements) : this;
2487
3293
  })
2488
3294
  .filter(function(){
2489
3295
  return this.name && !this.disabled &&
2490
3296
  (this.checked || /select|textarea/i.test(this.nodeName) ||
2491
- /text|hidden|password/i.test(this.type));
3297
+ /text|hidden|password|search/i.test(this.type));
2492
3298
  })
2493
3299
  .map(function(i, elem){
2494
3300
  var val = jQuery(this).val();
2495
3301
  return val == null ? null :
2496
- val.constructor == Array ?
3302
+ jQuery.isArray(val) ?
2497
3303
  jQuery.map( val, function(val, i){
2498
3304
  return {name: elem.name, value: val};
2499
3305
  }) :
@@ -2512,6 +3318,7 @@ jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".sp
2512
3318
  var jsc = now();
2513
3319
 
2514
3320
  jQuery.extend({
3321
+
2515
3322
  get: function( url, data, callback, type ) {
2516
3323
  // shift arguments if data argument was ommited
2517
3324
  if ( jQuery.isFunction( data ) ) {
@@ -2559,13 +3366,21 @@ jQuery.extend({
2559
3366
  url: location.href,
2560
3367
  global: true,
2561
3368
  type: "GET",
2562
- timeout: 0,
2563
3369
  contentType: "application/x-www-form-urlencoded",
2564
3370
  processData: true,
2565
3371
  async: true,
3372
+ /*
3373
+ timeout: 0,
2566
3374
  data: null,
2567
3375
  username: null,
2568
3376
  password: null,
3377
+ */
3378
+ // Create the request object; Microsoft failed to properly
3379
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
3380
+ // This function can be overriden by calling jQuery.ajaxSetup
3381
+ xhr:function(){
3382
+ return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3383
+ },
2569
3384
  accepts: {
2570
3385
  xml: "application/xml, text/xml",
2571
3386
  html: "text/html",
@@ -2588,7 +3403,7 @@ jQuery.extend({
2588
3403
  type = s.type.toUpperCase();
2589
3404
 
2590
3405
  // convert data if not already a string
2591
- if ( s.data && s.processData && typeof s.data != "string" )
3406
+ if ( s.data && s.processData && typeof s.data !== "string" )
2592
3407
  s.data = jQuery.param(s.data);
2593
3408
 
2594
3409
  // Handle JSONP Parameter Callbacks
@@ -2651,12 +3466,13 @@ jQuery.extend({
2651
3466
  jQuery.event.trigger( "ajaxStart" );
2652
3467
 
2653
3468
  // Matches an absolute URL, and saves the domain
2654
- var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
3469
+ var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
2655
3470
 
2656
3471
  // If we're requesting a remote document
2657
3472
  // and trying to load JSON or Script with a GET
2658
- if ( s.dataType == "script" && type == "GET"
2659
- && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
3473
+ if ( s.dataType == "script" && type == "GET" && parts
3474
+ && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
3475
+
2660
3476
  var head = document.getElementsByTagName("head")[0];
2661
3477
  var script = document.createElement("script");
2662
3478
  script.src = s.url;
@@ -2674,6 +3490,9 @@ jQuery.extend({
2674
3490
  done = true;
2675
3491
  success();
2676
3492
  complete();
3493
+
3494
+ // Handle memory leak in IE
3495
+ script.onload = script.onreadystatechange = null;
2677
3496
  head.removeChild( script );
2678
3497
  }
2679
3498
  };
@@ -2687,9 +3506,8 @@ jQuery.extend({
2687
3506
 
2688
3507
  var requestDone = false;
2689
3508
 
2690
- // Create the request object; Microsoft failed to properly
2691
- // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2692
- var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3509
+ // Create the request object
3510
+ var xhr = s.xhr();
2693
3511
 
2694
3512
  // Open the socket
2695
3513
  // Passing null username, generates a login popup on Opera (#2865)
@@ -2718,10 +3536,11 @@ jQuery.extend({
2718
3536
  s.accepts._default );
2719
3537
  } catch(e){}
2720
3538
 
2721
- // Allow custom headers/mimetypes
3539
+ // Allow custom headers/mimetypes and early abort
2722
3540
  if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
2723
- // cleanup active request counter
2724
- s.global && jQuery.active--;
3541
+ // Handle the global AJAX counter
3542
+ if ( s.global && ! --jQuery.active )
3543
+ jQuery.event.trigger( "ajaxStop" );
2725
3544
  // close opended socket
2726
3545
  xhr.abort();
2727
3546
  return false;
@@ -2732,8 +3551,18 @@ jQuery.extend({
2732
3551
 
2733
3552
  // Wait for a response to come back
2734
3553
  var onreadystatechange = function(isTimeout){
3554
+ // The request was aborted, clear the interval and decrement jQuery.active
3555
+ if (xhr.readyState == 0) {
3556
+ if (ival) {
3557
+ // clear poll interval
3558
+ clearInterval(ival);
3559
+ ival = null;
3560
+ // Handle the global AJAX counter
3561
+ if ( s.global && ! --jQuery.active )
3562
+ jQuery.event.trigger( "ajaxStop" );
3563
+ }
2735
3564
  // The transfer is complete and the data is available, or the request timed out
2736
- if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
3565
+ } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
2737
3566
  requestDone = true;
2738
3567
 
2739
3568
  // clear poll interval
@@ -2742,16 +3571,16 @@ jQuery.extend({
2742
3571
  ival = null;
2743
3572
  }
2744
3573
 
2745
- status = isTimeout == "timeout" && "timeout" ||
2746
- !jQuery.httpSuccess( xhr ) && "error" ||
2747
- s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
3574
+ status = isTimeout == "timeout" ? "timeout" :
3575
+ !jQuery.httpSuccess( xhr ) ? "error" :
3576
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
2748
3577
  "success";
2749
3578
 
2750
3579
  if ( status == "success" ) {
2751
3580
  // Watch for, and catch, XML document parse errors
2752
3581
  try {
2753
3582
  // process the data (runs the xml through httpData regardless of callback)
2754
- data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
3583
+ data = jQuery.httpData( xhr, s.dataType, s );
2755
3584
  } catch(e) {
2756
3585
  status = "parsererror";
2757
3586
  }
@@ -2777,6 +3606,9 @@ jQuery.extend({
2777
3606
  // Fire the complete handlers
2778
3607
  complete();
2779
3608
 
3609
+ if ( isTimeout )
3610
+ xhr.abort();
3611
+
2780
3612
  // Stop memory leaks
2781
3613
  if ( s.async )
2782
3614
  xhr = null;
@@ -2791,13 +3623,8 @@ jQuery.extend({
2791
3623
  if ( s.timeout > 0 )
2792
3624
  setTimeout(function(){
2793
3625
  // Check to see if the request is still happening
2794
- if ( xhr ) {
2795
- // Cancel the request
2796
- xhr.abort();
2797
-
2798
- if( !requestDone )
2799
- onreadystatechange( "timeout" );
2800
- }
3626
+ if ( xhr && !requestDone )
3627
+ onreadystatechange( "timeout" );
2801
3628
  }, s.timeout);
2802
3629
  }
2803
3630
 
@@ -2857,8 +3684,7 @@ jQuery.extend({
2857
3684
  try {
2858
3685
  // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
2859
3686
  return !xhr.status && location.protocol == "file:" ||
2860
- ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
2861
- jQuery.browser.safari && xhr.status == undefined;
3687
+ ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
2862
3688
  } catch(e){}
2863
3689
  return false;
2864
3690
  },
@@ -2869,13 +3695,12 @@ jQuery.extend({
2869
3695
  var xhrRes = xhr.getResponseHeader("Last-Modified");
2870
3696
 
2871
3697
  // Firefox always returns 200. check Last-Modified date
2872
- return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
2873
- jQuery.browser.safari && xhr.status == undefined;
3698
+ return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
2874
3699
  } catch(e){}
2875
3700
  return false;
2876
3701
  },
2877
3702
 
2878
- httpData: function( xhr, type, filter ) {
3703
+ httpData: function( xhr, type, s ) {
2879
3704
  var ct = xhr.getResponseHeader("content-type"),
2880
3705
  xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
2881
3706
  data = xml ? xhr.responseXML : xhr.responseText;
@@ -2884,31 +3709,40 @@ jQuery.extend({
2884
3709
  throw "parsererror";
2885
3710
 
2886
3711
  // Allow a pre-filtering function to sanitize the response
2887
- if( filter )
2888
- data = filter( data, type );
3712
+ // s != null is checked to keep backwards compatibility
3713
+ if( s && s.dataFilter )
3714
+ data = s.dataFilter( data, type );
2889
3715
 
2890
- // If the type is "script", eval it in global context
2891
- if ( type == "script" )
2892
- jQuery.globalEval( data );
3716
+ // The filter can actually parse the response
3717
+ if( typeof data === "string" ){
2893
3718
 
2894
- // Get the JavaScript object, if JSON is used.
2895
- if ( type == "json" )
2896
- data = eval("(" + data + ")");
3719
+ // If the type is "script", eval it in global context
3720
+ if ( type == "script" )
3721
+ jQuery.globalEval( data );
2897
3722
 
3723
+ // Get the JavaScript object, if JSON is used.
3724
+ if ( type == "json" )
3725
+ data = window["eval"]("(" + data + ")");
3726
+ }
3727
+
2898
3728
  return data;
2899
3729
  },
2900
3730
 
2901
3731
  // Serialize an array of form elements or a set of
2902
3732
  // key/values into a query string
2903
3733
  param: function( a ) {
2904
- var s = [];
3734
+ var s = [ ];
3735
+
3736
+ function add( key, value ){
3737
+ s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
3738
+ };
2905
3739
 
2906
3740
  // If an array was passed in, assume that it is an array
2907
3741
  // of form elements
2908
- if ( a.constructor == Array || a.jquery )
3742
+ if ( jQuery.isArray(a) || a.jquery )
2909
3743
  // Serialize the form elements
2910
3744
  jQuery.each( a, function(){
2911
- s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
3745
+ add( this.name, this.value );
2912
3746
  });
2913
3747
 
2914
3748
  // Otherwise, assume that it's an object of key/value pairs
@@ -2916,83 +3750,112 @@ jQuery.extend({
2916
3750
  // Serialize the key/values
2917
3751
  for ( var j in a )
2918
3752
  // If the value is an array then the key names need to be repeated
2919
- if ( a[j] && a[j].constructor == Array )
3753
+ if ( jQuery.isArray(a[j]) )
2920
3754
  jQuery.each( a[j], function(){
2921
- s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
3755
+ add( j, this );
2922
3756
  });
2923
3757
  else
2924
- s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
3758
+ add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
2925
3759
 
2926
3760
  // Return the resulting serialization
2927
3761
  return s.join("&").replace(/%20/g, "+");
2928
3762
  }
2929
3763
 
2930
3764
  });
3765
+ var elemdisplay = {},
3766
+ timerId,
3767
+ fxAttrs = [
3768
+ // height animations
3769
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3770
+ // width animations
3771
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3772
+ // opacity animations
3773
+ [ "opacity" ]
3774
+ ];
3775
+
3776
+ function genFx( type, num ){
3777
+ var obj = {};
3778
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
3779
+ obj[ this ] = type;
3780
+ });
3781
+ return obj;
3782
+ }
3783
+
2931
3784
  jQuery.fn.extend({
2932
3785
  show: function(speed,callback){
2933
- return speed ?
2934
- this.animate({
2935
- height: "show", width: "show", opacity: "show"
2936
- }, speed, callback) :
2937
-
2938
- this.filter(":hidden").each(function(){
2939
- this.style.display = this.oldblock || "";
2940
- if ( jQuery.css(this,"display") == "none" ) {
2941
- var elem = jQuery("<" + this.tagName + " />").appendTo("body");
2942
- this.style.display = elem.css("display");
2943
- // handle an edge condition where css is - div { display:none; } or similar
2944
- if (this.style.display == "none")
2945
- this.style.display = "block";
2946
- elem.remove();
3786
+ if ( speed ) {
3787
+ return this.animate( genFx("show", 3), speed, callback);
3788
+ } else {
3789
+ for ( var i = 0, l = this.length; i < l; i++ ){
3790
+ var old = jQuery.data(this[i], "olddisplay");
3791
+
3792
+ this[i].style.display = old || "";
3793
+
3794
+ if ( jQuery.css(this[i], "display") === "none" ) {
3795
+ var tagName = this[i].tagName, display;
3796
+
3797
+ if ( elemdisplay[ tagName ] ) {
3798
+ display = elemdisplay[ tagName ];
3799
+ } else {
3800
+ var elem = jQuery("<" + tagName + " />").appendTo("body");
3801
+
3802
+ display = elem.css("display");
3803
+ if ( display === "none" )
3804
+ display = "block";
3805
+
3806
+ elem.remove();
3807
+
3808
+ elemdisplay[ tagName ] = display;
3809
+ }
3810
+
3811
+ jQuery.data(this[i], "olddisplay", display);
2947
3812
  }
2948
- }).end();
3813
+ }
3814
+
3815
+ // Set the display of the elements in a second loop
3816
+ // to avoid the constant reflow
3817
+ for ( var i = 0, l = this.length; i < l; i++ ){
3818
+ this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
3819
+ }
3820
+
3821
+ return this;
3822
+ }
2949
3823
  },
2950
3824
 
2951
3825
  hide: function(speed,callback){
2952
- return speed ?
2953
- this.animate({
2954
- height: "hide", width: "hide", opacity: "hide"
2955
- }, speed, callback) :
3826
+ if ( speed ) {
3827
+ return this.animate( genFx("hide", 3), speed, callback);
3828
+ } else {
3829
+ for ( var i = 0, l = this.length; i < l; i++ ){
3830
+ var old = jQuery.data(this[i], "olddisplay");
3831
+ if ( !old && old !== "none" )
3832
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
3833
+ }
3834
+
3835
+ // Set the display of the elements in a second loop
3836
+ // to avoid the constant reflow
3837
+ for ( var i = 0, l = this.length; i < l; i++ ){
3838
+ this[i].style.display = "none";
3839
+ }
2956
3840
 
2957
- this.filter(":visible").each(function(){
2958
- this.oldblock = this.oldblock || jQuery.css(this,"display");
2959
- this.style.display = "none";
2960
- }).end();
3841
+ return this;
3842
+ }
2961
3843
  },
2962
3844
 
2963
3845
  // Save the old toggle function
2964
3846
  _toggle: jQuery.fn.toggle,
2965
3847
 
2966
3848
  toggle: function( fn, fn2 ){
3849
+ var bool = typeof fn === "boolean";
3850
+
2967
3851
  return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
2968
3852
  this._toggle.apply( this, arguments ) :
2969
- fn ?
2970
- this.animate({
2971
- height: "toggle", width: "toggle", opacity: "toggle"
2972
- }, fn, fn2) :
3853
+ fn == null || bool ?
2973
3854
  this.each(function(){
2974
- jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
2975
- });
2976
- },
2977
-
2978
- slideDown: function(speed,callback){
2979
- return this.animate({height: "show"}, speed, callback);
2980
- },
2981
-
2982
- slideUp: function(speed,callback){
2983
- return this.animate({height: "hide"}, speed, callback);
2984
- },
2985
-
2986
- slideToggle: function(speed, callback){
2987
- return this.animate({height: "toggle"}, speed, callback);
2988
- },
2989
-
2990
- fadeIn: function(speed, callback){
2991
- return this.animate({opacity: "show"}, speed, callback);
2992
- },
2993
-
2994
- fadeOut: function(speed, callback){
2995
- return this.animate({opacity: "hide"}, speed, callback);
3855
+ var state = bool ? fn : jQuery(this).is(":hidden");
3856
+ jQuery(this)[ state ? "show" : "hide" ]();
3857
+ }) :
3858
+ this.animate(genFx("toggle", 3), fn, fn2);
2996
3859
  },
2997
3860
 
2998
3861
  fadeTo: function(speed,to,callback){
@@ -3003,17 +3866,16 @@ jQuery.fn.extend({
3003
3866
  var optall = jQuery.speed(speed, easing, callback);
3004
3867
 
3005
3868
  return this[ optall.queue === false ? "each" : "queue" ](function(){
3006
- if ( this.nodeType != 1)
3007
- return false;
3008
-
3869
+
3009
3870
  var opt = jQuery.extend({}, optall), p,
3010
- hidden = jQuery(this).is(":hidden"), self = this;
3011
-
3871
+ hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
3872
+ self = this;
3873
+
3012
3874
  for ( p in prop ) {
3013
3875
  if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3014
3876
  return opt.complete.call(this);
3015
3877
 
3016
- if ( p == "height" || p == "width" ) {
3878
+ if ( ( p == "height" || p == "width" ) && this.style ) {
3017
3879
  // Store display property
3018
3880
  opt.display = jQuery.css(this, "display");
3019
3881
 
@@ -3062,27 +3924,6 @@ jQuery.fn.extend({
3062
3924
  });
3063
3925
  },
3064
3926
 
3065
- queue: function(type, fn){
3066
- if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
3067
- fn = type;
3068
- type = "fx";
3069
- }
3070
-
3071
- if ( !type || (typeof type == "string" && !fn) )
3072
- return queue( this[0], type );
3073
-
3074
- return this.each(function(){
3075
- if ( fn.constructor == Array )
3076
- queue(this, type, fn);
3077
- else {
3078
- queue(this, type).push( fn );
3079
-
3080
- if ( queue(this, type).length == 1 )
3081
- fn.call(this);
3082
- }
3083
- });
3084
- },
3085
-
3086
3927
  stop: function(clearQueue, gotoEnd){
3087
3928
  var timers = jQuery.timers;
3088
3929
 
@@ -3109,46 +3950,31 @@ jQuery.fn.extend({
3109
3950
 
3110
3951
  });
3111
3952
 
3112
- var queue = function( elem, type, array ) {
3113
- if ( elem ){
3114
-
3115
- type = type || "fx";
3116
-
3117
- var q = jQuery.data( elem, type + "queue" );
3118
-
3119
- if ( !q || array )
3120
- q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
3121
-
3122
- }
3123
- return q;
3124
- };
3125
-
3126
- jQuery.fn.dequeue = function(type){
3127
- type = type || "fx";
3128
-
3129
- return this.each(function(){
3130
- var q = queue(this, type);
3131
-
3132
- q.shift();
3133
-
3134
- if ( q.length )
3135
- q[0].call( this );
3136
- });
3137
- };
3953
+ // Generate shortcuts for custom animations
3954
+ jQuery.each({
3955
+ slideDown: genFx("show", 1),
3956
+ slideUp: genFx("hide", 1),
3957
+ slideToggle: genFx("toggle", 1),
3958
+ fadeIn: { opacity: "show" },
3959
+ fadeOut: { opacity: "hide" }
3960
+ }, function( name, props ){
3961
+ jQuery.fn[ name ] = function( speed, callback ){
3962
+ return this.animate( props, speed, callback );
3963
+ };
3964
+ });
3138
3965
 
3139
3966
  jQuery.extend({
3140
3967
 
3141
3968
  speed: function(speed, easing, fn) {
3142
- var opt = speed && speed.constructor == Object ? speed : {
3969
+ var opt = typeof speed === "object" ? speed : {
3143
3970
  complete: fn || !fn && easing ||
3144
3971
  jQuery.isFunction( speed ) && speed,
3145
3972
  duration: speed,
3146
- easing: fn && easing || easing && easing.constructor != Function && easing
3973
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
3147
3974
  };
3148
3975
 
3149
- opt.duration = (opt.duration && opt.duration.constructor == Number ?
3150
- opt.duration :
3151
- jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
3976
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
3977
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
3152
3978
 
3153
3979
  // Queueing
3154
3980
  opt.old = opt.complete;
@@ -3172,7 +3998,6 @@ jQuery.extend({
3172
3998
  },
3173
3999
 
3174
4000
  timers: [],
3175
- timerId: null,
3176
4001
 
3177
4002
  fx: function( elem, options, prop ){
3178
4003
  this.options = options;
@@ -3195,13 +4020,13 @@ jQuery.fx.prototype = {
3195
4020
  (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3196
4021
 
3197
4022
  // Set display property to block for height/width animations
3198
- if ( this.prop == "height" || this.prop == "width" )
4023
+ if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
3199
4024
  this.elem.style.display = "block";
3200
4025
  },
3201
4026
 
3202
4027
  // Get the current size
3203
4028
  cur: function(force){
3204
- if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
4029
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
3205
4030
  return this.elem[ this.prop ];
3206
4031
 
3207
4032
  var r = parseFloat(jQuery.css(this.elem, this.prop, force));
@@ -3216,7 +4041,6 @@ jQuery.fx.prototype = {
3216
4041
  this.unit = unit || this.unit || "px";
3217
4042
  this.now = this.start;
3218
4043
  this.pos = this.state = 0;
3219
- this.update();
3220
4044
 
3221
4045
  var self = this;
3222
4046
  function t(gotoEnd){
@@ -3225,10 +4049,8 @@ jQuery.fx.prototype = {
3225
4049
 
3226
4050
  t.elem = this.elem;
3227
4051
 
3228
- jQuery.timers.push(t);
3229
-
3230
- if ( jQuery.timerId == null ) {
3231
- jQuery.timerId = setInterval(function(){
4052
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
4053
+ timerId = setInterval(function(){
3232
4054
  var timers = jQuery.timers;
3233
4055
 
3234
4056
  for ( var i = 0; i < timers.length; i++ )
@@ -3236,8 +4058,8 @@ jQuery.fx.prototype = {
3236
4058
  timers.splice(i--, 1);
3237
4059
 
3238
4060
  if ( !timers.length ) {
3239
- clearInterval( jQuery.timerId );
3240
- jQuery.timerId = null;
4061
+ clearInterval( timerId );
4062
+ timerId = undefined;
3241
4063
  }
3242
4064
  }, 13);
3243
4065
  }
@@ -3250,12 +4072,9 @@ jQuery.fx.prototype = {
3250
4072
  this.options.show = true;
3251
4073
 
3252
4074
  // Begin the animation
3253
- this.custom(0, this.cur());
3254
-
3255
4075
  // Make sure that we start at a small width/height to avoid any
3256
4076
  // flash of content
3257
- if ( this.prop == "width" || this.prop == "height" )
3258
- this.elem.style[this.prop] = "1px";
4077
+ this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
3259
4078
 
3260
4079
  // Start by showing the element
3261
4080
  jQuery(this.elem).show();
@@ -3275,7 +4094,7 @@ jQuery.fx.prototype = {
3275
4094
  step: function(gotoEnd){
3276
4095
  var t = now();
3277
4096
 
3278
- if ( gotoEnd || t > this.options.duration + this.startTime ) {
4097
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
3279
4098
  this.now = this.end;
3280
4099
  this.pos = this.state = 1;
3281
4100
  this.update();
@@ -3300,17 +4119,16 @@ jQuery.fx.prototype = {
3300
4119
 
3301
4120
  // Hide the element if the "hide" operation was done
3302
4121
  if ( this.options.hide )
3303
- this.elem.style.display = "none";
4122
+ jQuery(this.elem).hide();
3304
4123
 
3305
4124
  // Reset the properties, if the item has been hidden or shown
3306
4125
  if ( this.options.hide || this.options.show )
3307
4126
  for ( var p in this.options.curAnim )
3308
4127
  jQuery.attr(this.elem.style, p, this.options.orig[p]);
3309
- }
3310
-
3311
- if ( done )
4128
+
3312
4129
  // Execute the complete function
3313
4130
  this.options.complete.call( this.elem );
4131
+ }
3314
4132
 
3315
4133
  return false;
3316
4134
  } else {
@@ -3335,124 +4153,106 @@ jQuery.extend( jQuery.fx, {
3335
4153
  slow: 600,
3336
4154
  fast: 200,
3337
4155
  // Default speed
3338
- def: 400
4156
+ _default: 400
3339
4157
  },
3340
4158
  step: {
3341
- scrollLeft: function(fx){
3342
- fx.elem.scrollLeft = fx.now;
3343
- },
3344
-
3345
- scrollTop: function(fx){
3346
- fx.elem.scrollTop = fx.now;
3347
- },
3348
4159
 
3349
4160
  opacity: function(fx){
3350
4161
  jQuery.attr(fx.elem.style, "opacity", fx.now);
3351
4162
  },
3352
4163
 
3353
4164
  _default: function(fx){
3354
- fx.elem.style[ fx.prop ] = fx.now + fx.unit;
4165
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
4166
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
4167
+ else
4168
+ fx.elem[ fx.prop ] = fx.now;
3355
4169
  }
3356
4170
  }
3357
4171
  });
3358
- // The Offset Method
3359
- // Originally By Brandon Aaron, part of the Dimension Plugin
3360
- // http://jquery.com/plugins/project/dimensions
3361
- jQuery.fn.offset = function() {
3362
- var left = 0, top = 0, elem = this[0], results;
3363
-
3364
- if ( elem ) with ( jQuery.browser ) {
3365
- var parent = elem.parentNode,
3366
- offsetChild = elem,
3367
- offsetParent = elem.offsetParent,
3368
- doc = elem.ownerDocument,
3369
- safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
3370
- css = jQuery.curCSS,
3371
- fixed = css(elem, "position") == "fixed";
3372
-
3373
- // Use getBoundingClientRect if available
3374
- if ( elem.getBoundingClientRect ) {
3375
- var box = elem.getBoundingClientRect();
3376
-
3377
- // Add the document scroll offsets
3378
- add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3379
- box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3380
-
3381
- // IE adds the HTML element's border, by default it is medium which is 2px
3382
- // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
3383
- // IE 7 standards mode, the border is always 2px
3384
- // This border/offset is typically represented by the clientLeft and clientTop properties
3385
- // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
3386
- // Therefore this method will be off by 2px in IE while in quirksmode
3387
- add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
3388
-
3389
- // Otherwise loop through the offsetParents and parentNodes
3390
- } else {
3391
-
3392
- // Initial element offsets
3393
- add( elem.offsetLeft, elem.offsetTop );
3394
-
3395
- // Get parent offsets
3396
- while ( offsetParent ) {
3397
- // Add offsetParent offsets
3398
- add( offsetParent.offsetLeft, offsetParent.offsetTop );
4172
+ if ( document.documentElement["getBoundingClientRect"] )
4173
+ jQuery.fn.offset = function() {
4174
+ if ( !this[0] ) return { top: 0, left: 0 };
4175
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4176
+ var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
4177
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
4178
+ top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
4179
+ left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
4180
+ return { top: top, left: left };
4181
+ };
4182
+ else
4183
+ jQuery.fn.offset = function() {
4184
+ if ( !this[0] ) return { top: 0, left: 0 };
4185
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4186
+ jQuery.offset.initialized || jQuery.offset.initialize();
4187
+
4188
+ var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
4189
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
4190
+ body = doc.body, defaultView = doc.defaultView,
4191
+ prevComputedStyle = defaultView.getComputedStyle(elem, null),
4192
+ top = elem.offsetTop, left = elem.offsetLeft;
4193
+
4194
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
4195
+ computedStyle = defaultView.getComputedStyle(elem, null);
4196
+ top -= elem.scrollTop, left -= elem.scrollLeft;
4197
+ if ( elem === offsetParent ) {
4198
+ top += elem.offsetTop, left += elem.offsetLeft;
4199
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
4200
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
4201
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4202
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
4203
+ }
4204
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
4205
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
4206
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4207
+ prevComputedStyle = computedStyle;
4208
+ }
3399
4209
 
3400
- // Mozilla and Safari > 2 does not include the border on offset parents
3401
- // However Mozilla adds the border for table or table cells
3402
- if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
3403
- border( offsetParent );
4210
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
4211
+ top += body.offsetTop,
4212
+ left += body.offsetLeft;
3404
4213
 
3405
- // Add the document scroll offsets if position is fixed on any offsetParent
3406
- if ( !fixed && css(offsetParent, "position") == "fixed" )
3407
- fixed = true;
4214
+ if ( prevComputedStyle.position === "fixed" )
4215
+ top += Math.max(docElem.scrollTop, body.scrollTop),
4216
+ left += Math.max(docElem.scrollLeft, body.scrollLeft);
3408
4217
 
3409
- // Set offsetChild to previous offsetParent unless it is the body element
3410
- offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
3411
- // Get next offsetParent
3412
- offsetParent = offsetParent.offsetParent;
3413
- }
4218
+ return { top: top, left: left };
4219
+ };
3414
4220
 
3415
- // Get parent scroll offsets
3416
- while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
3417
- // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
3418
- if ( !/^inline|table.*$/i.test(css(parent, "display")) )
3419
- // Subtract parent scroll offsets
3420
- add( -parent.scrollLeft, -parent.scrollTop );
4221
+ jQuery.offset = {
4222
+ initialize: function() {
4223
+ if ( this.initialized ) return;
4224
+ var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
4225
+ html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
3421
4226
 
3422
- // Mozilla does not add the border for a parent that has overflow != visible
3423
- if ( mozilla && css(parent, "overflow") != "visible" )
3424
- border( parent );
4227
+ rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
4228
+ for ( prop in rules ) container.style[prop] = rules[prop];
3425
4229
 
3426
- // Get next parent
3427
- parent = parent.parentNode;
3428
- }
4230
+ container.innerHTML = html;
4231
+ body.insertBefore(container, body.firstChild);
4232
+ innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
3429
4233
 
3430
- // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
3431
- // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
3432
- if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
3433
- (mozilla && css(offsetChild, "position") != "absolute") )
3434
- add( -doc.body.offsetLeft, -doc.body.offsetTop );
4234
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
4235
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
3435
4236
 
3436
- // Add the document scroll offsets if position is fixed
3437
- if ( fixed )
3438
- add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3439
- Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3440
- }
4237
+ innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
4238
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
3441
4239
 
3442
- // Return an object with top and left properties
3443
- results = { top: top, left: left };
3444
- }
4240
+ body.style.marginTop = '1px';
4241
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
4242
+ body.style.marginTop = bodyMarginTop;
3445
4243
 
3446
- function border(elem) {
3447
- add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
3448
- }
4244
+ body.removeChild(container);
4245
+ this.initialized = true;
4246
+ },
3449
4247
 
3450
- function add(l, t) {
3451
- left += parseInt(l, 10) || 0;
3452
- top += parseInt(t, 10) || 0;
4248
+ bodyOffset: function(body) {
4249
+ jQuery.offset.initialized || jQuery.offset.initialize();
4250
+ var top = body.offsetTop, left = body.offsetLeft;
4251
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
4252
+ top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
4253
+ left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
4254
+ return { top: top, left: left };
3453
4255
  }
3454
-
3455
- return results;
3456
4256
  };
3457
4257
 
3458
4258
 
@@ -3471,11 +4271,11 @@ jQuery.fn.extend({
3471
4271
  // Subtract element margins
3472
4272
  // note: when an element has margin: auto the offsetLeft and marginLeft
3473
4273
  // are the same in Safari causing offset.left to incorrectly be 0
3474
- offset.top -= num( this, 'marginTop' );
4274
+ offset.top -= num( this, 'marginTop' );
3475
4275
  offset.left -= num( this, 'marginLeft' );
3476
4276
 
3477
4277
  // Add offsetParent borders
3478
- parentOffset.top += num( offsetParent, 'borderTopWidth' );
4278
+ parentOffset.top += num( offsetParent, 'borderTopWidth' );
3479
4279
  parentOffset.left += num( offsetParent, 'borderLeftWidth' );
3480
4280
 
3481
4281
  // Subtract the two offsets
@@ -3489,7 +4289,7 @@ jQuery.fn.extend({
3489
4289
  },
3490
4290
 
3491
4291
  offsetParent: function() {
3492
- var offsetParent = this[0].offsetParent;
4292
+ var offsetParent = this[0].offsetParent || document.body;
3493
4293
  while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
3494
4294
  offsetParent = offsetParent.offsetParent;
3495
4295
  return jQuery(offsetParent);
@@ -3502,9 +4302,9 @@ jQuery.each( ['Left', 'Top'], function(i, name) {
3502
4302
  var method = 'scroll' + name;
3503
4303
 
3504
4304
  jQuery.fn[ method ] = function(val) {
3505
- if (!this[0]) return;
4305
+ if (!this[0]) return null;
3506
4306
 
3507
- return val != undefined ?
4307
+ return val !== undefined ?
3508
4308
 
3509
4309
  // Set the scroll offset
3510
4310
  this.each(function() {
@@ -3528,22 +4328,49 @@ jQuery.each( ['Left', 'Top'], function(i, name) {
3528
4328
  jQuery.each([ "Height", "Width" ], function(i, name){
3529
4329
 
3530
4330
  var tl = i ? "Left" : "Top", // top or left
3531
- br = i ? "Right" : "Bottom"; // bottom or right
4331
+ br = i ? "Right" : "Bottom", // bottom or right
4332
+ lower = name.toLowerCase();
3532
4333
 
3533
4334
  // innerHeight and innerWidth
3534
4335
  jQuery.fn["inner" + name] = function(){
3535
- return this[ name.toLowerCase() ]() +
3536
- num(this, "padding" + tl) +
3537
- num(this, "padding" + br);
4336
+ return this[0] ?
4337
+ jQuery.css( this[0], lower, false, "padding" ) :
4338
+ null;
3538
4339
  };
3539
4340
 
3540
4341
  // outerHeight and outerWidth
3541
4342
  jQuery.fn["outer" + name] = function(margin) {
3542
- return this["inner" + name]() +
3543
- num(this, "border" + tl + "Width") +
3544
- num(this, "border" + br + "Width") +
3545
- (margin ?
3546
- num(this, "margin" + tl) + num(this, "margin" + br) : 0);
4343
+ return this[0] ?
4344
+ jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
4345
+ null;
4346
+ };
4347
+
4348
+ var type = name.toLowerCase();
4349
+
4350
+ jQuery.fn[ type ] = function( size ) {
4351
+ // Get window width or height
4352
+ return this[0] == window ?
4353
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
4354
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
4355
+ document.body[ "client" + name ] :
4356
+
4357
+ // Get document width or height
4358
+ this[0] == document ?
4359
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
4360
+ Math.max(
4361
+ document.documentElement["client" + name],
4362
+ document.body["scroll" + name], document.documentElement["scroll" + name],
4363
+ document.body["offset" + name], document.documentElement["offset" + name]
4364
+ ) :
4365
+
4366
+ // Get or set width or height on the element
4367
+ size === undefined ?
4368
+ // Get width or height on the element
4369
+ (this.length ? jQuery.css( this[0], type ) : null) :
4370
+
4371
+ // Set the width or height on the element (default to pixels if value is unitless)
4372
+ this.css( type, typeof size === "string" ? size : size + "px" );
3547
4373
  };
3548
4374
 
3549
- });})();
4375
+ });
4376
+ })();