jabs 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,252 @@
1
+ module Jabs
2
+ NeverLive = %w{dragstart drag dragend dropstart drop dropend}
3
+
4
+ class Precompiler < Fold::Precompiler
5
+ class << self
6
+ attr_accessor :spot_replacements
7
+ end
8
+
9
+ self.spot_replacements = []
10
+
11
+ def self.spot_replace key, &block
12
+ spot_replacements << block if block_given?
13
+ end
14
+
15
+ attr_reader :sexp, :current_sexp
16
+
17
+ def initialize
18
+ super
19
+
20
+ @ready = false
21
+ @current_sexp = []
22
+ @full_sexp = [:source_elements, @current_sexp]
23
+ end
24
+
25
+ folds :Line, // do
26
+ if children.reject{|child| child.is_a?(Line) }.any?
27
+ call(function(nil, ["$this"], [:source_elements, render_children]), jquery(Johnson::Parser.parse(text).value.first))
28
+ else
29
+ [:fall_through, (Precompiler.do_spot_replace(text, self) + children.map{|child| child.text}.join(""))]
30
+ end
31
+ end
32
+
33
+ folds :Selector, /^\$/ do
34
+ call(function(nil, ["$this"], [:source_elements, render_children]), jquery([:string, text]))
35
+ end
36
+
37
+ folds :SubSelector, /^&/ do
38
+ call(
39
+ function(nil, ["$this"], [:source_elements, render_children]),
40
+ call(access([:name, "$this"], [:name, "find"]), [:string, text])
41
+ )
42
+ end
43
+
44
+ folds :Event, /^:/ do
45
+ event_bind(text, [:name, "$this"], [:source_elements, [parse("var $this = jQuery(this)")] + render_children])
46
+ end
47
+
48
+ folds :Ready, /^:ready/ do
49
+ jquery([:function, nil, [], [:source_elements, [call(function(nil, ["$this"], [:source_elements, render_children]), jquery([:name, "window"]))]]])
50
+ end
51
+
52
+ folds :Function, /^fun / do
53
+ parts = text.split(/ /)
54
+ name, arg_names = parts.shift, parts.join('').gsub(' ', '').split(',')
55
+ [:function, name, arg_names, [:source_elements, render_children]]
56
+ end
57
+
58
+ folds :Def, /^def / do
59
+ parts = text.split(/ /)
60
+ name, arg_names = parts.shift, parts.join('').gsub(' ', '').split(',')
61
+ [:assign_expr,
62
+ access(access([:name, "jQuery"], [:name, "fn"]), [:name, name]),
63
+ [:function, nil, arg_names, [:source_elements, [parse("var $this = this")] + render_children]]]
64
+ end
65
+
66
+ if_meta = <<RUBY
67
+ index = parent.children.index(self) || 0
68
+
69
+ _next = parent.children.slice! index + 1
70
+
71
+ _else = if [Else, ElseIf].include? _next.class
72
+ _next.render
73
+ else
74
+ nil
75
+ end
76
+ [:if, parse(Precompiler.do_spot_replace(text)),[:source_elements, render_children], _else]
77
+ RUBY
78
+
79
+ folds :If, /^if / do
80
+ eval if_meta
81
+ end
82
+
83
+ folds :Unless, /^unless / do
84
+ [:if, [:not, [:parenthesis, parse(Precompiler.do_spot_replace(text))]], [:source_elements, render_children], nil]
85
+ end
86
+
87
+ folds :Else, /^else/ do
88
+ [:source_elements, render_children]
89
+ end
90
+
91
+ folds :ElseIf, /^else if/ do
92
+ eval if_meta
93
+ end
94
+
95
+ folds :DotAccessor, /^\./ do
96
+ if children.find_all{|child| child.text[/^[\w\d]*?:/]}.any? and not(text[/\{/])
97
+ break if text[/\{|\}/]
98
+ self.text << "(" << johnsonize([:object_literal, children.map do |child|
99
+ key, value = *child.text.split(":")
100
+ [:property, [:string, key], parse(value)]
101
+ end]).to_ecma.gsub(",\n", ",") << ")"
102
+ self.children = []
103
+ end
104
+
105
+ index = parent.children.index(self)
106
+ _next = parent.children.slice index + 1
107
+ _text = _next ? _next.text : ""
108
+
109
+ if children.any?
110
+ if (_text[/\}\)/])
111
+ [:fall_through, ("$this."+Precompiler.do_spot_replace(text, self) + children.map{|child| child.text}.join(""))]
112
+ else
113
+ call(
114
+ function(nil, ["$this"], [:source_elements, render_children]),
115
+ parse(Precompiler.do_spot_replace(".#{text}", self))
116
+ )
117
+ end
118
+ else
119
+ parse Precompiler.do_spot_replace(".#{text}", self)
120
+ end
121
+ end
122
+
123
+ spot_replace :DotAccessor do |expression, precompiler|
124
+ expression.gsub /(^\.([\w]+)|- \.(.+))(.*)/ do |match|
125
+ "$this#{Precompiler.compile_arguments expression, $1, match, $4}"
126
+ end
127
+ end
128
+
129
+ spot_replace :AccessUpAndCall do |expression, precompiler|
130
+ expression.gsub /\.\.(\..*)/ do |match|
131
+ "$this.prevObject#{Precompiler.do_spot_replace($1)}"
132
+ end
133
+ end
134
+
135
+ spot_replace :AccessUpUp do |expression, precompiler|
136
+ expression.
137
+ gsub(/ \.\.\/|^\.\.\//, "$this.prevObject/").
138
+ gsub(/\/\.\./, ".prevObject")
139
+ end
140
+
141
+ spot_replace :AccessUp do |expression, precompiler|
142
+ expression.gsub /\.\./ do
143
+ "$this.prevObject"
144
+ end
145
+ end
146
+
147
+ spot_replace :AttributeSetter do |expression, precompiler|
148
+ expression.gsub /@([\w]+)[ ]*=[ ]*(.*)/ do |match|
149
+ if $2[0] == ?=
150
+ match
151
+ else
152
+ "$this.attr('#{$1}', #{Precompiler.do_spot_replace $2, precompiler})"
153
+ end
154
+ end
155
+ end
156
+
157
+ spot_replace :AttributeAccessor do |expression, precompiler|
158
+ expression.gsub /@([\w]+)/ do
159
+ "$this.attr('#{$1}')"
160
+ end
161
+ end
162
+
163
+ spot_replace :DanglingThis do |expression, precompiler|
164
+ expression.gsub /prevObject\$this/ do
165
+ "prevObject"
166
+ end
167
+ end
168
+
169
+ def self.do_spot_replace expression, precompiler=nil
170
+ spot_replacements.each do |block|
171
+ expression = block.call(expression, precompiler)
172
+ end
173
+ expression
174
+ end
175
+
176
+ def self.compile_arguments expression, call, real, args
177
+ return real if expression[Regexp.new("^\\#{call}\\(")]
178
+ arguments = []
179
+ if args[/^\./]
180
+ "#{call}()#{do_spot_replace(args).gsub("$this", "")}"
181
+ else
182
+ args.split(/\s|,/).each do |arg|
183
+ arg.gsub!(/:(\w+)/) {%{"#{$1}"}}
184
+ next if arg[/\s/]
185
+ next if arg == ""
186
+ arguments << arg
187
+ end
188
+ "#{call}(#{arguments.join(', ')})"
189
+ end
190
+ end
191
+
192
+ def parse expression
193
+ self.class.do_spot_replace expression, self
194
+ Johnson::Parser.parse(expression).value.first
195
+ end
196
+
197
+ def source block=nil
198
+ source = [:source_elements]
199
+ source << [block] unless(block.nil? or block.empty?)
200
+ source
201
+ end
202
+
203
+ def event_bind event, binds_to, function_sexp=nil
204
+ binding = NeverLive.include?(event.to_s)? 'bind' : 'live'
205
+ call(access(binds_to, [:name, binding]), [:string, event], [:function, nil, ["event"], function_sexp])
206
+ end
207
+
208
+ def call *args
209
+ [:function_call, args]
210
+ end
211
+
212
+ def onready function_sexp=nil
213
+ event_bind('ready', jquery([:name, "document"]), function_sexp)
214
+ end
215
+
216
+ def access left, right
217
+ [:dot_accessor, right, left]
218
+ end
219
+
220
+ def function name=nil, args=[], function_sexp=nil
221
+ function_sexp.last << [:return, parse("$this")]
222
+ [:return, [:function, name, args, function_sexp]]
223
+ end
224
+
225
+ def jquery *jquery_arg
226
+ [:function_call, [
227
+ [:name, 'jQuery'],
228
+ *jquery_arg
229
+ ]]
230
+ end
231
+
232
+ def johnsonize(sexp)
233
+ return sexp if sexp.is_a?(Johnson::Nodes::Node)
234
+ return sexp if sexp.class.to_s == "String"
235
+ return [] if sexp === []
236
+ return nil if sexp === nil
237
+ unless sexp.first.class.to_s == "Array"
238
+ if sexp.first.class.to_s == "Symbol"
239
+ klass = eval("Johnson::Nodes::#{sexp.shift.to_s.camelcase}")
240
+ klass.new 0,0, *sexp.map{|n|johnsonize(n)}
241
+ elsif sexp.is_a? Array
242
+ sexp.map{|n|johnsonize(n)}
243
+ else
244
+ sexp
245
+ end
246
+ else
247
+ sexp.map{|n|johnsonize(n)}
248
+ end
249
+ end
250
+ end
251
+
252
+ end
@@ -0,0 +1,44 @@
1
+ module Johnson
2
+ module Nodes
3
+ attr_accessor :value
4
+ class FallThrough < Node
5
+ def initialize(_row, _column, value)
6
+ @value = value
7
+ end
8
+ end
9
+ end
10
+
11
+ module Visitors
12
+ class EcmaVisitor
13
+ def visit_SourceElements(o)
14
+ newline = o.value.length > 0 ? "\n" : ' '
15
+ (@depth == 0 ? '' : "{#{newline}") +
16
+ indent {
17
+ o.value.map { |x|
18
+ code = x.accept(self)
19
+ semi = case x
20
+ when Nodes::FallThrough
21
+ ""
22
+ when Nodes::Function, Nodes::While, Nodes::If, Nodes::Try, Nodes::Switch, Nodes::Case, Nodes::Default, Nodes::For, Nodes::ForIn
23
+ code =~ /\}\Z/ ? '' : ';'
24
+ else
25
+ ';'
26
+ end
27
+ "#{indent}#{code}#{semi}"
28
+ }.join("\n")
29
+ } +
30
+ (@depth == 0 ? '' : "#{newline}}")
31
+ end
32
+
33
+ def visit_FallThrough(o)
34
+ o.value
35
+ end
36
+ end
37
+
38
+ class SexpVisitor
39
+ def visit_FallThrough(o)
40
+ [:fall_through, o.value]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,13 +1,13 @@
1
1
  /*!
2
- * jQuery JavaScript Library v1.3.1
2
+ * jQuery JavaScript Library v1.3.2
3
3
  * http://jquery.com/
4
4
  *
5
5
  * Copyright (c) 2009 John Resig
6
6
  * Dual licensed under the MIT and GPL licenses.
7
7
  * http://docs.jquery.com/License
8
8
  *
9
- * Date: 2009-01-21 20:42:16 -0500 (Wed, 21 Jan 2009)
10
- * Revision: 6158
9
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
10
+ * Revision: 6246
11
11
  */
12
12
  (function(){
13
13
 
@@ -88,14 +88,16 @@ jQuery.fn = jQuery.prototype = {
88
88
  this.context = selector.context;
89
89
  }
90
90
 
91
- return this.setArray(jQuery.makeArray(selector));
91
+ return this.setArray(jQuery.isArray( selector ) ?
92
+ selector :
93
+ jQuery.makeArray(selector));
92
94
  },
93
95
 
94
96
  // Start with an empty selector
95
97
  selector: "",
96
98
 
97
99
  // The current version of jQuery being used
98
- jquery: "1.3.1",
100
+ jquery: "1.3.2",
99
101
 
100
102
  // The number of elements contained in the matched element set
101
103
  size: function() {
@@ -108,7 +110,7 @@ jQuery.fn = jQuery.prototype = {
108
110
  return num === undefined ?
109
111
 
110
112
  // Return a 'clean' array
111
- jQuery.makeArray( this ) :
113
+ Array.prototype.slice.call( this ) :
112
114
 
113
115
  // Return just the object
114
116
  this[ num ];
@@ -278,23 +280,21 @@ jQuery.fn = jQuery.prototype = {
278
280
  },
279
281
 
280
282
  // For internal use only.
281
- // Behaves like an Array's .push method, not like a jQuery method.
283
+ // Behaves like an Array's method, not like a jQuery method.
282
284
  push: [].push,
285
+ sort: [].sort,
286
+ splice: [].splice,
283
287
 
284
288
  find: function( selector ) {
285
- if ( this.length === 1 && !/,/.test(selector) ) {
289
+ if ( this.length === 1 ) {
286
290
  var ret = this.pushStack( [], "find", selector );
287
291
  ret.length = 0;
288
292
  jQuery.find( selector, this[0], ret );
289
293
  return ret;
290
294
  } else {
291
- var elems = jQuery.map(this, function(elem){
295
+ return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
292
296
  return jQuery.find( selector, elem );
293
- });
294
-
295
- return this.pushStack( /[^+>] [^+>]/.test( selector ) ?
296
- jQuery.unique( elems ) :
297
- elems, "find", selector );
297
+ })), "find", selector );
298
298
  }
299
299
  },
300
300
 
@@ -310,33 +310,37 @@ jQuery.fn = jQuery.prototype = {
310
310
  // attributes in IE that are actually only stored
311
311
  // as properties will not be copied (such as the
312
312
  // the name attribute on an input).
313
- var clone = this.cloneNode(true),
314
- container = document.createElement("div");
315
- container.appendChild(clone);
316
- 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];
317
321
  } else
318
322
  return this.cloneNode(true);
319
323
  });
320
324
 
321
- // Need to set the expando to null on the cloned set if it exists
322
- // removeData doesn't work here, IE removes it from the original as well
323
- // this is primarily for IE but the data expando shouldn't be copied over in any browser
324
- var clone = ret.find("*").andSelf().each(function(){
325
- if ( this[ expando ] !== undefined )
326
- this[ expando ] = null;
327
- });
328
-
329
325
  // Copy the events from the original to the clone
330
- if ( events === true )
331
- this.find("*").andSelf().each(function(i){
332
- 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 )
333
331
  return;
334
- var events = jQuery.data( this, "events" );
335
332
 
336
- for ( var type in events )
337
- for ( var handler in events[ type ] )
338
- 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++;
339
342
  });
343
+ }
340
344
 
341
345
  // Return the cloned set
342
346
  return ret;
@@ -355,14 +359,18 @@ jQuery.fn = jQuery.prototype = {
355
359
  },
356
360
 
357
361
  closest: function( selector ) {
358
- var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null;
362
+ var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
363
+ closer = 0;
359
364
 
360
365
  return this.map(function(){
361
366
  var cur = this;
362
367
  while ( cur && cur.ownerDocument ) {
363
- if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) )
368
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
369
+ jQuery.data(cur, "closest", closer);
364
370
  return cur;
371
+ }
365
372
  cur = cur.parentNode;
373
+ closer++;
366
374
  }
367
375
  });
368
376
  },
@@ -475,7 +483,7 @@ jQuery.fn = jQuery.prototype = {
475
483
  html: function( value ) {
476
484
  return value === undefined ?
477
485
  (this[0] ?
478
- this[0].innerHTML :
486
+ this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
479
487
  null) :
480
488
  this.empty().append( value );
481
489
  },
@@ -507,13 +515,13 @@ jQuery.fn = jQuery.prototype = {
507
515
  if ( this[0] ) {
508
516
  var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
509
517
  scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
510
- first = fragment.firstChild,
511
- extra = this.length > 1 ? fragment.cloneNode(true) : fragment;
518
+ first = fragment.firstChild;
512
519
 
513
520
  if ( first )
514
521
  for ( var i = 0, l = this.length; i < l; i++ )
515
- callback.call( root(this[i], first), i > 0 ? extra.cloneNode(true) : fragment );
516
-
522
+ callback.call( root(this[i], first), this.length > 1 || i > 0 ?
523
+ fragment.cloneNode(true) : fragment );
524
+
517
525
  if ( scripts )
518
526
  jQuery.each( scripts, evalScript );
519
527
  }
@@ -636,9 +644,7 @@ jQuery.extend({
636
644
 
637
645
  // Evalulates a script in a global context
638
646
  globalEval: function( data ) {
639
- data = jQuery.trim( data );
640
-
641
- if ( data ) {
647
+ if ( data && /\S/.test(data) ) {
642
648
  // Inspired by code by Andrea Giammarchi
643
649
  // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
644
650
  var head = document.getElementsByTagName("head")[0] || document.documentElement,
@@ -741,26 +747,32 @@ jQuery.extend({
741
747
  elem.style[ name ] = old[ name ];
742
748
  },
743
749
 
744
- css: function( elem, name, force ) {
750
+ css: function( elem, name, force, extra ) {
745
751
  if ( name == "width" || name == "height" ) {
746
752
  var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
747
753
 
748
754
  function getWH() {
749
755
  val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
750
- var padding = 0, border = 0;
756
+
757
+ if ( extra === "border" )
758
+ return;
759
+
751
760
  jQuery.each( which, function() {
752
- padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
753
- 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;
754
767
  });
755
- val -= Math.round(padding + border);
756
768
  }
757
769
 
758
- if ( jQuery(elem).is(":visible") )
770
+ if ( elem.offsetWidth !== 0 )
759
771
  getWH();
760
772
  else
761
773
  jQuery.swap( elem, props, getWH );
762
774
 
763
- return Math.max(0, val);
775
+ return Math.max(0, Math.round(val));
764
776
  }
765
777
 
766
778
  return jQuery.curCSS( elem, name, force );
@@ -866,7 +878,7 @@ jQuery.extend({
866
878
  });
867
879
 
868
880
  // Trim whitespace, otherwise indexOf won't work as expected
869
- var tags = jQuery.trim( elem ).toLowerCase();
881
+ var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
870
882
 
871
883
  var wrap =
872
884
  // option or optgroup
@@ -906,11 +918,12 @@ jQuery.extend({
906
918
  if ( !jQuery.support.tbody ) {
907
919
 
908
920
  // String was a <table>, *may* have spurious <tbody>
909
- var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
910
- div.firstChild && div.firstChild.childNodes :
921
+ var hasBody = /<tbody/i.test(elem),
922
+ tbody = !tags.indexOf("<table") && !hasBody ?
923
+ div.firstChild && div.firstChild.childNodes :
911
924
 
912
925
  // String was a bare <thead> or <tfoot>
913
- wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
926
+ wrap[1] == "<table>" && !hasBody ?
914
927
  div.childNodes :
915
928
  [];
916
929
 
@@ -1189,13 +1202,16 @@ jQuery.each({
1189
1202
  insertAfter: "after",
1190
1203
  replaceAll: "replaceWith"
1191
1204
  }, function(name, original){
1192
- jQuery.fn[ name ] = function() {
1193
- var args = arguments;
1205
+ jQuery.fn[ name ] = function( selector ) {
1206
+ var ret = [], insert = jQuery( selector );
1194
1207
 
1195
- return this.each(function(){
1196
- for ( var i = 0, length = args.length; i < length; i++ )
1197
- jQuery( args[ i ] )[ original ]( this );
1198
- });
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 );
1199
1215
  };
1200
1216
  });
1201
1217
 
@@ -1234,7 +1250,7 @@ jQuery.each({
1234
1250
 
1235
1251
  empty: function() {
1236
1252
  // Remove element nodes and prevent memory leaks
1237
- jQuery( ">*", this ).remove();
1253
+ jQuery(this).children().remove();
1238
1254
 
1239
1255
  // Remove any remaining nodes
1240
1256
  while ( this.firstChild )
@@ -1402,7 +1418,7 @@ jQuery.fn.extend({
1402
1418
  */
1403
1419
  (function(){
1404
1420
 
1405
- var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]+['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,
1421
+ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1406
1422
  done = 0,
1407
1423
  toString = Object.prototype.toString;
1408
1424
 
@@ -1507,6 +1523,19 @@ var Sizzle = function(selector, context, results, seed) {
1507
1523
 
1508
1524
  if ( extra ) {
1509
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);
1535
+ }
1536
+ }
1537
+ }
1538
+ }
1510
1539
  }
1511
1540
 
1512
1541
  return results;
@@ -1548,7 +1577,8 @@ Sizzle.find = function(expr, context, isXML){
1548
1577
  };
1549
1578
 
1550
1579
  Sizzle.filter = function(expr, set, inplace, not){
1551
- var old = expr, result = [], curLoop = set, match, anyFound;
1580
+ var old = expr, result = [], curLoop = set, match, anyFound,
1581
+ isXMLFilter = set && set[0] && isXML(set[0]);
1552
1582
 
1553
1583
  while ( expr && set.length ) {
1554
1584
  for ( var type in Expr.filter ) {
@@ -1561,7 +1591,7 @@ Sizzle.filter = function(expr, set, inplace, not){
1561
1591
  }
1562
1592
 
1563
1593
  if ( Expr.preFilter[ type ] ) {
1564
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not );
1594
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1565
1595
 
1566
1596
  if ( !match ) {
1567
1597
  anyFound = found = true;
@@ -1606,8 +1636,6 @@ Sizzle.filter = function(expr, set, inplace, not){
1606
1636
  }
1607
1637
  }
1608
1638
 
1609
- expr = expr.replace(/\s*,\s*/, "");
1610
-
1611
1639
  // Improper expression
1612
1640
  if ( expr == old ) {
1613
1641
  if ( anyFound == null ) {
@@ -1645,26 +1673,33 @@ var Expr = Sizzle.selectors = {
1645
1673
  }
1646
1674
  },
1647
1675
  relative: {
1648
- "+": function(checkSet, part){
1649
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1650
- var elem = checkSet[i];
1651
- if ( elem ) {
1652
- var cur = elem.previousSibling;
1653
- while ( cur && cur.nodeType !== 1 ) {
1654
- cur = cur.previousSibling;
1655
- }
1656
- checkSet[i] = typeof part === "string" ?
1657
- cur || false :
1658
- cur === part;
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
+ }
1684
+
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 ) {}
1688
+
1689
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1690
+ elem || false :
1691
+ elem === part;
1659
1692
  }
1660
1693
  }
1661
1694
 
1662
- if ( typeof part === "string" ) {
1695
+ if ( isPartStrNotTag ) {
1663
1696
  Sizzle.filter( part, checkSet, true );
1664
1697
  }
1665
1698
  },
1666
1699
  ">": function(checkSet, part, isXML){
1667
- if ( typeof part === "string" && !/\W/.test(part) ) {
1700
+ var isPartStr = typeof part === "string";
1701
+
1702
+ if ( isPartStr && !/\W/.test(part) ) {
1668
1703
  part = isXML ? part : part.toUpperCase();
1669
1704
 
1670
1705
  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
@@ -1678,19 +1713,19 @@ var Expr = Sizzle.selectors = {
1678
1713
  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1679
1714
  var elem = checkSet[i];
1680
1715
  if ( elem ) {
1681
- checkSet[i] = typeof part === "string" ?
1716
+ checkSet[i] = isPartStr ?
1682
1717
  elem.parentNode :
1683
1718
  elem.parentNode === part;
1684
1719
  }
1685
1720
  }
1686
1721
 
1687
- if ( typeof part === "string" ) {
1722
+ if ( isPartStr ) {
1688
1723
  Sizzle.filter( part, checkSet, true );
1689
1724
  }
1690
1725
  }
1691
1726
  },
1692
1727
  "": function(checkSet, part, isXML){
1693
- var doneName = "done" + (done++), checkFn = dirCheck;
1728
+ var doneName = done++, checkFn = dirCheck;
1694
1729
 
1695
1730
  if ( !part.match(/\W/) ) {
1696
1731
  var nodeCheck = part = isXML ? part : part.toUpperCase();
@@ -1700,7 +1735,7 @@ var Expr = Sizzle.selectors = {
1700
1735
  checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1701
1736
  },
1702
1737
  "~": function(checkSet, part, isXML){
1703
- var doneName = "done" + (done++), checkFn = dirCheck;
1738
+ var doneName = done++, checkFn = dirCheck;
1704
1739
 
1705
1740
  if ( typeof part === "string" && !part.match(/\W/) ) {
1706
1741
  var nodeCheck = part = isXML ? part : part.toUpperCase();
@@ -1718,8 +1753,16 @@ var Expr = Sizzle.selectors = {
1718
1753
  }
1719
1754
  },
1720
1755
  NAME: function(match, context, isXML){
1721
- if ( typeof context.getElementsByName !== "undefined" && !isXML ) {
1722
- return context.getElementsByName(match[1]);
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
+ }
1763
+ }
1764
+
1765
+ return ret.length === 0 ? null : ret;
1723
1766
  }
1724
1767
  },
1725
1768
  TAG: function(match, context){
@@ -1727,13 +1770,16 @@ var Expr = Sizzle.selectors = {
1727
1770
  }
1728
1771
  },
1729
1772
  preFilter: {
1730
- CLASS: function(match, curLoop, inplace, result, not){
1773
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
1731
1774
  match = " " + match[1].replace(/\\/g, "") + " ";
1732
1775
 
1733
- var elem;
1734
- for ( var i = 0; (elem = curLoop[i]) != null; i++ ) {
1776
+ if ( isXML ) {
1777
+ return match;
1778
+ }
1779
+
1780
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1735
1781
  if ( elem ) {
1736
- if ( not ^ (" " + elem.className + " ").indexOf(match) >= 0 ) {
1782
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1737
1783
  if ( !inplace )
1738
1784
  result.push( elem );
1739
1785
  } else if ( inplace ) {
@@ -1764,14 +1810,14 @@ var Expr = Sizzle.selectors = {
1764
1810
  }
1765
1811
 
1766
1812
  // TODO: Move to normal caching system
1767
- match[0] = "done" + (done++);
1813
+ match[0] = done++;
1768
1814
 
1769
1815
  return match;
1770
1816
  },
1771
- ATTR: function(match){
1817
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
1772
1818
  var name = match[1].replace(/\\/g, "");
1773
1819
 
1774
- if ( Expr.attrMap[name] ) {
1820
+ if ( !isXML && Expr.attrMap[name] ) {
1775
1821
  match[1] = Expr.attrMap[name];
1776
1822
  }
1777
1823
 
@@ -1784,7 +1830,7 @@ var Expr = Sizzle.selectors = {
1784
1830
  PSEUDO: function(match, curLoop, inplace, result, not){
1785
1831
  if ( match[1] === "not" ) {
1786
1832
  // If we're dealing with a complex expression, or a simple one
1787
- if ( match[3].match(chunker).length > 1 ) {
1833
+ if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
1788
1834
  match[3] = Sizzle(match[3], null, null, curLoop);
1789
1835
  } else {
1790
1836
  var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
@@ -1793,7 +1839,7 @@ var Expr = Sizzle.selectors = {
1793
1839
  }
1794
1840
  return false;
1795
1841
  }
1796
- } else if ( Expr.match.POS.test( match[0] ) ) {
1842
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1797
1843
  return true;
1798
1844
  }
1799
1845
 
@@ -1890,47 +1936,6 @@ var Expr = Sizzle.selectors = {
1890
1936
  }
1891
1937
  },
1892
1938
  filter: {
1893
- CHILD: function(elem, match){
1894
- var type = match[1], parent = elem.parentNode;
1895
-
1896
- var doneName = match[0];
1897
-
1898
- if ( parent && (!parent[ doneName ] || !elem.nodeIndex) ) {
1899
- var count = 1;
1900
-
1901
- for ( var node = parent.firstChild; node; node = node.nextSibling ) {
1902
- if ( node.nodeType == 1 ) {
1903
- node.nodeIndex = count++;
1904
- }
1905
- }
1906
-
1907
- parent[ doneName ] = count - 1;
1908
- }
1909
-
1910
- if ( type == "first" ) {
1911
- return elem.nodeIndex == 1;
1912
- } else if ( type == "last" ) {
1913
- return elem.nodeIndex == parent[ doneName ];
1914
- } else if ( type == "only" ) {
1915
- return parent[ doneName ] == 1;
1916
- } else if ( type == "nth" ) {
1917
- var add = false, first = match[2], last = match[3];
1918
-
1919
- if ( first == 1 && last == 0 ) {
1920
- return true;
1921
- }
1922
-
1923
- if ( first == 0 ) {
1924
- if ( elem.nodeIndex == last ) {
1925
- add = true;
1926
- }
1927
- } else if ( (elem.nodeIndex - last) % first == 0 && (elem.nodeIndex - last) / first >= 0 ) {
1928
- add = true;
1929
- }
1930
-
1931
- return add;
1932
- }
1933
- },
1934
1939
  PSEUDO: function(elem, match, i, array){
1935
1940
  var name = match[1], filter = Expr.filters[ name ];
1936
1941
 
@@ -1950,6 +1955,49 @@ var Expr = Sizzle.selectors = {
1950
1955
  return true;
1951
1956
  }
1952
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];
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;
1994
+ if ( first == 0 ) {
1995
+ return diff == 0;
1996
+ } else {
1997
+ return ( diff % first == 0 && diff / first >= 0 );
1998
+ }
1999
+ }
2000
+ },
1953
2001
  ID: function(elem, match){
1954
2002
  return elem.nodeType === 1 && elem.getAttribute("id") === match;
1955
2003
  },
@@ -1957,10 +2005,20 @@ var Expr = Sizzle.selectors = {
1957
2005
  return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
1958
2006
  },
1959
2007
  CLASS: function(elem, match){
1960
- return match.test( elem.className );
2008
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
2009
+ .indexOf( match ) > -1;
1961
2010
  },
1962
2011
  ATTR: function(elem, match){
1963
- var result = Expr.attrHandle[ match[1] ] ? Expr.attrHandle[ match[1] ]( elem ) : elem[ match[1] ] || elem.getAttribute( match[1] ), value = result + "", type = match[2], check = match[4];
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
+
1964
2022
  return result == null ?
1965
2023
  type === "!=" :
1966
2024
  type === "=" ?
@@ -1969,8 +2027,8 @@ var Expr = Sizzle.selectors = {
1969
2027
  value.indexOf(check) >= 0 :
1970
2028
  type === "~=" ?
1971
2029
  (" " + value + " ").indexOf(check) >= 0 :
1972
- !match[4] ?
1973
- result :
2030
+ !check ?
2031
+ value && result !== false :
1974
2032
  type === "!=" ?
1975
2033
  value != check :
1976
2034
  type === "^=" ?
@@ -2036,6 +2094,39 @@ try {
2036
2094
  };
2037
2095
  }
2038
2096
 
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
+
2039
2130
  // Check to see if the browser returns elements by name when
2040
2131
  // querying by getElementById (and provide a workaround)
2041
2132
  (function(){
@@ -2099,7 +2190,8 @@ try {
2099
2190
 
2100
2191
  // Check to see if an attribute returns normalized href attributes
2101
2192
  div.innerHTML = "<a href='#'></a>";
2102
- if ( div.firstChild && div.firstChild.getAttribute("href") !== "#" ) {
2193
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
2194
+ div.firstChild.getAttribute("href") !== "#" ) {
2103
2195
  Expr.attrHandle.href = function(elem){
2104
2196
  return elem.getAttribute("href", 2);
2105
2197
  };
@@ -2136,29 +2228,50 @@ if ( document.querySelectorAll ) (function(){
2136
2228
  Sizzle.matches = oldSizzle.matches;
2137
2229
  })();
2138
2230
 
2139
- if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) {
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;
2238
+
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
+
2140
2245
  Expr.order.splice(1, 0, "CLASS");
2141
- Expr.find.CLASS = function(match, context) {
2142
- return context.getElementsByClassName(match[1]);
2246
+ Expr.find.CLASS = function(match, context, isXML) {
2247
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
2248
+ return context.getElementsByClassName(match[1]);
2249
+ }
2143
2250
  };
2144
- }
2251
+ })();
2145
2252
 
2146
2253
  function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2254
+ var sibDir = dir == "previousSibling" && !isXML;
2147
2255
  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2148
2256
  var elem = checkSet[i];
2149
2257
  if ( elem ) {
2258
+ if ( sibDir && elem.nodeType === 1 ){
2259
+ elem.sizcache = doneName;
2260
+ elem.sizset = i;
2261
+ }
2150
2262
  elem = elem[dir];
2151
2263
  var match = false;
2152
2264
 
2153
- while ( elem && elem.nodeType ) {
2154
- var done = elem[doneName];
2155
- if ( done ) {
2156
- match = checkSet[ done ];
2265
+ while ( elem ) {
2266
+ if ( elem.sizcache === doneName ) {
2267
+ match = checkSet[elem.sizset];
2157
2268
  break;
2158
2269
  }
2159
2270
 
2160
- if ( elem.nodeType === 1 && !isXML )
2161
- elem[doneName] = i;
2271
+ if ( elem.nodeType === 1 && !isXML ){
2272
+ elem.sizcache = doneName;
2273
+ elem.sizset = i;
2274
+ }
2162
2275
 
2163
2276
  if ( elem.nodeName === cur ) {
2164
2277
  match = elem;
@@ -2174,22 +2287,28 @@ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2174
2287
  }
2175
2288
 
2176
2289
  function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2290
+ var sibDir = dir == "previousSibling" && !isXML;
2177
2291
  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2178
2292
  var elem = checkSet[i];
2179
2293
  if ( elem ) {
2294
+ if ( sibDir && elem.nodeType === 1 ) {
2295
+ elem.sizcache = doneName;
2296
+ elem.sizset = i;
2297
+ }
2180
2298
  elem = elem[dir];
2181
2299
  var match = false;
2182
2300
 
2183
- while ( elem && elem.nodeType ) {
2184
- if ( elem[doneName] ) {
2185
- match = checkSet[ elem[doneName] ];
2301
+ while ( elem ) {
2302
+ if ( elem.sizcache === doneName ) {
2303
+ match = checkSet[elem.sizset];
2186
2304
  break;
2187
2305
  }
2188
2306
 
2189
2307
  if ( elem.nodeType === 1 ) {
2190
- if ( !isXML )
2191
- elem[doneName] = i;
2192
-
2308
+ if ( !isXML ) {
2309
+ elem.sizcache = doneName;
2310
+ elem.sizset = i;
2311
+ }
2193
2312
  if ( typeof cur !== "string" ) {
2194
2313
  if ( elem === cur ) {
2195
2314
  match = true;
@@ -2248,15 +2367,11 @@ jQuery.expr = Sizzle.selectors;
2248
2367
  jQuery.expr[":"] = jQuery.expr.filters;
2249
2368
 
2250
2369
  Sizzle.selectors.filters.hidden = function(elem){
2251
- return "hidden" === elem.type ||
2252
- jQuery.css(elem, "display") === "none" ||
2253
- jQuery.css(elem, "visibility") === "hidden";
2370
+ return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2254
2371
  };
2255
2372
 
2256
2373
  Sizzle.selectors.filters.visible = function(elem){
2257
- return "hidden" !== elem.type &&
2258
- jQuery.css(elem, "display") !== "none" &&
2259
- jQuery.css(elem, "visibility") !== "hidden";
2374
+ return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2260
2375
  };
2261
2376
 
2262
2377
  Sizzle.selectors.filters.animated = function(elem){
@@ -2552,7 +2667,8 @@ jQuery.event = {
2552
2667
  var all, handlers;
2553
2668
 
2554
2669
  event = arguments[0] = jQuery.event.fix( event || window.event );
2555
-
2670
+ event.currentTarget = this;
2671
+
2556
2672
  // Namespaced event handlers
2557
2673
  var namespaces = event.type.split(".");
2558
2674
  event.type = namespaces.shift();
@@ -2883,9 +2999,13 @@ function liveHandler( event ){
2883
2999
  }
2884
3000
  });
2885
3001
 
3002
+ elems.sort(function(a,b) {
3003
+ return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
3004
+ });
3005
+
2886
3006
  jQuery.each(elems, function(){
2887
3007
  if ( this.fn.call(this.elem, event, this.fn.data) === false )
2888
- stop = false;
3008
+ return (stop = false);
2889
3009
  });
2890
3010
 
2891
3011
  return stop;
@@ -2949,7 +3069,7 @@ function bindReady(){
2949
3069
 
2950
3070
  // If IE and not an iframe
2951
3071
  // continually check to see if the document is ready
2952
- if ( document.documentElement.doScroll && typeof window.frameElement === "undefined" ) (function(){
3072
+ if ( document.documentElement.doScroll && window == window.top ) (function(){
2953
3073
  if ( jQuery.isReady ) return;
2954
3074
 
2955
3075
  try {
@@ -3079,12 +3199,11 @@ jQuery( window ).bind( 'unload', function(){
3079
3199
  // document.body must exist before we can do this
3080
3200
  jQuery(function(){
3081
3201
  var div = document.createElement("div");
3082
- div.style.width = "1px";
3083
- div.style.paddingLeft = "1px";
3202
+ div.style.width = div.style.paddingLeft = "1px";
3084
3203
 
3085
3204
  document.body.appendChild( div );
3086
3205
  jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3087
- document.body.removeChild( div );
3206
+ document.body.removeChild( div ).style.display = 'none';
3088
3207
  });
3089
3208
  })();
3090
3209
 
@@ -3175,7 +3294,7 @@ jQuery.fn.extend({
3175
3294
  .filter(function(){
3176
3295
  return this.name && !this.disabled &&
3177
3296
  (this.checked || /select|textarea/i.test(this.nodeName) ||
3178
- /text|hidden|password/i.test(this.type));
3297
+ /text|hidden|password|search/i.test(this.type));
3179
3298
  })
3180
3299
  .map(function(i, elem){
3181
3300
  var val = jQuery(this).val();
@@ -3371,6 +3490,9 @@ jQuery.extend({
3371
3490
  done = true;
3372
3491
  success();
3373
3492
  complete();
3493
+
3494
+ // Handle memory leak in IE
3495
+ script.onload = script.onreadystatechange = null;
3374
3496
  head.removeChild( script );
3375
3497
  }
3376
3498
  };
@@ -3686,9 +3808,15 @@ jQuery.fn.extend({
3686
3808
  elemdisplay[ tagName ] = display;
3687
3809
  }
3688
3810
 
3689
- this[i].style.display = jQuery.data(this[i], "olddisplay", display);
3811
+ jQuery.data(this[i], "olddisplay", display);
3690
3812
  }
3691
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
+ }
3692
3820
 
3693
3821
  return this;
3694
3822
  }
@@ -3702,8 +3830,14 @@ jQuery.fn.extend({
3702
3830
  var old = jQuery.data(this[i], "olddisplay");
3703
3831
  if ( !old && old !== "none" )
3704
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++ ){
3705
3838
  this[i].style.display = "none";
3706
3839
  }
3840
+
3707
3841
  return this;
3708
3842
  }
3709
3843
  },
@@ -3915,7 +4049,7 @@ jQuery.fx.prototype = {
3915
4049
 
3916
4050
  t.elem = this.elem;
3917
4051
 
3918
- if ( t() && jQuery.timers.push(t) == 1 ) {
4052
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
3919
4053
  timerId = setInterval(function(){
3920
4054
  var timers = jQuery.timers;
3921
4055
 
@@ -3925,6 +4059,7 @@ jQuery.fx.prototype = {
3925
4059
 
3926
4060
  if ( !timers.length ) {
3927
4061
  clearInterval( timerId );
4062
+ timerId = undefined;
3928
4063
  }
3929
4064
  }, 13);
3930
4065
  }
@@ -4193,22 +4328,21 @@ jQuery.each( ['Left', 'Top'], function(i, name) {
4193
4328
  jQuery.each([ "Height", "Width" ], function(i, name){
4194
4329
 
4195
4330
  var tl = i ? "Left" : "Top", // top or left
4196
- br = i ? "Right" : "Bottom"; // bottom or right
4331
+ br = i ? "Right" : "Bottom", // bottom or right
4332
+ lower = name.toLowerCase();
4197
4333
 
4198
4334
  // innerHeight and innerWidth
4199
4335
  jQuery.fn["inner" + name] = function(){
4200
- return this[ name.toLowerCase() ]() +
4201
- num(this, "padding" + tl) +
4202
- num(this, "padding" + br);
4336
+ return this[0] ?
4337
+ jQuery.css( this[0], lower, false, "padding" ) :
4338
+ null;
4203
4339
  };
4204
4340
 
4205
4341
  // outerHeight and outerWidth
4206
4342
  jQuery.fn["outer" + name] = function(margin) {
4207
- return this["inner" + name]() +
4208
- num(this, "border" + tl + "Width") +
4209
- num(this, "border" + br + "Width") +
4210
- (margin ?
4211
- 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;
4212
4346
  };
4213
4347
 
4214
4348
  var type = name.toLowerCase();
@@ -4238,4 +4372,5 @@ jQuery.each([ "Height", "Width" ], function(i, name){
4238
4372
  this.css( type, typeof size === "string" ? size : size + "px" );
4239
4373
  };
4240
4374
 
4241
- });})();
4375
+ });
4376
+ })();